r6369: update release notes
authorGerald Carter <jerry@samba.org>
Mon, 18 Apr 2005 16:08:52 +0000 (16:08 +0000)
committerGerald Carter <jerry@samba.org>
Mon, 18 Apr 2005 16:08:52 +0000 (16:08 +0000)
sync with SAMBA_3_0 (r6365).
Getting ready for 3.0.15pre2

230 files changed:
WHATSNEW.txt
examples/libsmbclient/Makefile
examples/libsmbclient/README
examples/libsmbclient/smbwrapper/Makefile [new file with mode: 0644]
examples/libsmbclient/smbwrapper/README [new file with mode: 0644]
examples/libsmbclient/smbwrapper/opendir_smbsh.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/select.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/smbsh.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/smbw.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/smbw.h [new file with mode: 0644]
examples/libsmbclient/smbwrapper/smbw_dir.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/smbw_stat.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/wrapper.c [new file with mode: 0644]
examples/libsmbclient/smbwrapper/wrapper.h [new file with mode: 0644]
examples/libsmbclient/testacl.c
examples/libsmbclient/testbrowse.c
examples/libsmbclient/testchmod.c [new file with mode: 0644]
examples/libsmbclient/testsmbc.c
examples/libsmbclient/teststat.c [new file with mode: 0644]
examples/libsmbclient/testutime.c [new file with mode: 0644]
examples/libsmbclient/tree.c
source/Makefile.in
source/VERSION
source/auth/auth_compat.c
source/auth/auth_sam.c
source/auth/auth_util.c
source/client/client.c
source/client/clitar.c
source/client/mount.cifs.c
source/client/smbspool.c
source/client/umount.cifs.c [new file with mode: 0644]
source/configure.in
source/groupdb/mapping.c
source/include/doserr.h
source/include/includes.h
source/include/libsmb_internal.h
source/include/libsmbclient.h
source/include/msdfs.h
source/include/nt_status.h
source/include/ntdomain.h
source/include/nterr.h
source/include/passdb.h
source/include/rpc_buffer.h [new file with mode: 0644]
source/include/rpc_client.h
source/include/rpc_eventlog.h [new file with mode: 0644]
source/include/rpc_lsa.h
source/include/rpc_misc.h
source/include/rpc_netlogon.h
source/include/rpc_reg.h
source/include/rpc_secdes.h
source/include/rpc_shutdown.h
source/include/rpc_spoolss.h
source/include/rpc_srvsvc.h
source/include/rpc_svcctl.h [new file with mode: 0644]
source/include/smb.h
source/include/smb_macros.h
source/include/smbldap.h
source/include/trans2.h
source/intl/lang_tdb.c
source/lib/access.c
source/lib/account_pol.c
source/lib/charcnv.c
source/lib/data_blob.c
source/lib/iconv.c
source/lib/ms_fnmatch.c
source/lib/privileges.c
source/lib/secace.c
source/lib/secdesc.c
source/lib/select.c
source/lib/smbldap.c
source/lib/substitute.c
source/lib/system.c
source/lib/system_smbd.c
source/lib/talloc.c
source/lib/time.c
source/lib/util.c
source/lib/util_seaccess.c
source/lib/util_sid.c
source/lib/util_smbd.c
source/lib/util_str.c
source/lib/util_unistr.c
source/lib/util_uuid.c
source/lib/wins_srv.c
source/libads/kerberos.c
source/libads/ldap.c
source/libads/ldap_printer.c
source/libads/sasl.c
source/libsmb/cliconnect.c
source/libsmb/clientgen.c
source/libsmb/clifile.c
source/libsmb/clifsinfo.c
source/libsmb/clikrb5.c
source/libsmb/clilist.c
source/libsmb/clirap.c
source/libsmb/clirap2.c
source/libsmb/clispnego.c
source/libsmb/doserr.c
source/libsmb/libsmbclient.c
source/libsmb/nmblib.c
source/libsmb/smb_signing.c
source/libsmb/smbencrypt.c
source/libsmb/spnego.c
source/modules/getdate.c
source/modules/getdate.y
source/modules/vfs_catia.c [new file with mode: 0644]
source/modules/vfs_fake_perms.c
source/modules/weird.c
source/nmbd/nmbd.c
source/nmbd/nmbd_subnetdb.c
source/nmbd/nmbd_synclists.c
source/nsswitch/wb_client.c
source/nsswitch/wb_common.c
source/nsswitch/winbindd.c
source/nsswitch/winbindd.h
source/nsswitch/winbindd_acct.c
source/nsswitch/winbindd_ads.c
source/nsswitch/winbindd_cache.c
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_nss.h
source/nsswitch/winbindd_passdb.c
source/nsswitch/winbindd_rpc.c
source/nsswitch/winbindd_util.c
source/param/loadparm.c
source/param/params.c
source/passdb/machine_sid.c
source/passdb/passdb.c
source/passdb/pdb_get_set.c
source/passdb/pdb_interface.c
source/passdb/pdb_ldap.c
source/passdb/secrets.c
source/passdb/util_sam_sid.c
source/printing/nt_printing.c
source/printing/printfsp.c
source/printing/printing.c
source/python/py_smb.c
source/registry/reg_db.c
source/registry/reg_eventlog.c [new file with mode: 0644]
source/registry/reg_frontend.c
source/rpc_client/cli_lsarpc.c
source/rpc_client/cli_reg.c
source/rpc_client/cli_shutdown.c
source/rpc_client/cli_spoolss.c
source/rpc_client/cli_svcctl.c [new file with mode: 0644]
source/rpc_parse/parse_buffer.c [new file with mode: 0644]
source/rpc_parse/parse_eventlog.c [new file with mode: 0644]
source/rpc_parse/parse_lsa.c
source/rpc_parse/parse_misc.c
source/rpc_parse/parse_net.c
source/rpc_parse/parse_prs.c
source/rpc_parse/parse_reg.c
source/rpc_parse/parse_rpc.c
source/rpc_parse/parse_samr.c
source/rpc_parse/parse_sec.c
source/rpc_parse/parse_shutdown.c
source/rpc_parse/parse_spoolss.c
source/rpc_parse/parse_srv.c
source/rpc_parse/parse_svcctl.c [new file with mode: 0644]
source/rpc_server/srv_eventlog.c [new file with mode: 0644]
source/rpc_server/srv_eventlog_nt.c [new file with mode: 0644]
source/rpc_server/srv_lsa_ds_nt.c
source/rpc_server/srv_lsa_nt.c
source/rpc_server/srv_netlog.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_pipe.c
source/rpc_server/srv_reg.c
source/rpc_server/srv_reg_nt.c
source/rpc_server/srv_samr_nt.c
source/rpc_server/srv_samr_util.c
source/rpc_server/srv_spoolss.c
source/rpc_server/srv_spoolss_nt.c
source/rpc_server/srv_srvsvc.c
source/rpc_server/srv_srvsvc_nt.c
source/rpc_server/srv_svcctl.c [new file with mode: 0644]
source/rpc_server/srv_svcctl_nt.c [new file with mode: 0644]
source/rpc_server/srv_util.c
source/rpcclient/cmd_reg.c
source/rpcclient/cmd_samr.c
source/rpcclient/cmd_shutdown.c
source/rpcclient/cmd_spoolss.c
source/rpcclient/rpcclient.c
source/sam/idmap_util.c
source/script/installman.sh
source/script/mkversion.sh
source/smbd/chgpasswd.c
source/smbd/dir.c
source/smbd/dosmode.c
source/smbd/error.c
source/smbd/fake_file.c
source/smbd/filename.c
source/smbd/files.c
source/smbd/lanman.c
source/smbd/msdfs.c
source/smbd/negprot.c
source/smbd/notify_kernel.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/oplock.c
source/smbd/oplock_linux.c
source/smbd/posix_acls.c
source/smbd/process.c
source/smbd/quotas.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/service.c
source/smbd/sesssetup.c
source/smbd/statcache.c
source/smbd/trans2.c
source/smbwrapper/smbw.c
source/smbwrapper/smbw_stat.c
source/tdb/tdb.c
source/tdb/tdbbackup.c
source/tdb/tdbtool.c
source/tdb/tdbutil.c
source/tests/sysquotas.c
source/torture/torture.c
source/torture/utable.c
source/utils/net.c
source/utils/net_ads.c
source/utils/net_groupmap.c
source/utils/net_lookup.c
source/utils/net_rap.c
source/utils/net_rpc.c
source/utils/net_rpc_rights.c
source/utils/net_rpc_samsync.c
source/utils/net_rpc_service.c [new file with mode: 0644]
source/utils/pdbedit.c
source/utils/smbcontrol.c
source/utils/smbpasswd.c
source/web/diagnose.c
source/web/neg_lang.c

index 41d53e04a72cec23214821cfb645c713de2efbfd..0d599c50447ffde597d6a8c499607f2eb64f4116 100644 (file)
+                   ==================================
+                   Release Notes for Samba 3.0.15pre2
+                               Apr 18, 2005
+                   ==================================
+
+This is a preview release of the Samba 3.0.15 code base and
+is provided for testing only.  This release is *not* intended
+for production servers.  However, there have been several bug
+fixes and new features added since 3.0.14 that we feel are
+important to make available to the Samba community for wider
+testing.  There are still more changes planned before the 
+final 3.0.15 release.
+
+Additional features introduced in Samba 3.0.15pre1 include:
+
+  o Support for several new Win32 rpc pipes.
+  o Improved support for OS/2 clients.
+  o New 'net rpc service' tool for managing Win32 services.
+  o Capability to set the owner on new files and directory
+    based on the parent's ownership.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.14a
+---------------------
+
+    Parameter Name                      Action
+    --------------                      ------
+    inherit owner                      New
+    max stat cache size                        New
+
+commits
+-------
+
+o   Jeremy Allison <jra@samba.org>
+    * BUG 2533: Fix incorrect directory listings for OS/2 clients.
+    * Ensure the old SMB search calls always ask mask_match() to 
+      translate patterns like ????????.???.
+    * Split out the check_path_syntax() into a findfirst, findnext,
+      & wildcard versions.
+    * Fix checks for matching groups in an file ACL against the
+      user's primary and supplementary group list.
+    * BUG 2541: Ensure we recognize LANMAN2.1 as OS/2 and select 
+      LANMAN2 protocol, ensure the EA size is always correctly 
+      set on a query for a file with no EA's.
+    * BUG 2551: Look at the incoming flags2 flag 
+      FLAGS2_LONG_PATH_COMPONENTS determines if a reply is 
+      uppercased on a SMBsearch request, not the protocol level.
+    * Added "volume" command to smbclient that prints out the 
+      volume name and serial number.
+    * Added "fix for broken SMB_INFO_VOLUME level used by OS/2.
+    * Add support for OS/2 Extended Attributes.
+    * Correctly check OpenX open modes.
+    * Ensure allocation size is correctly returned for OpenX. 
+    * Only set allocation on create/truncate for nttrans.
+    * Fix oplock bug in trans2open() code.
+    * Remove unix_ERR_XXX global nastiness.
+    * Only do the strange DOS error for openX, not trans2open.
+    * Ensure SMBopen replies includes the share modes as well as 
+      open modes.
+    * BUG 2581: Add size limit (in kb) to stat cache.
+    * Fix bug in the trans2 secondary processing.
+    * BUG 2601: Enforce DOS_OPEN_EXEC to mean read-only.
+    * Add an SMB counter per connection struct for gathering
+      profiling data.
+    * BUG 2605: Ensure smbclient doesn't perform commands if 
+      the "chdir" fails in a scripted set.
+    * Ensure a 'forced group' is added to the list of effective
+      gids when processing ACLs.
+
+
+o   Timur Bakeyev <timur@com.bat.ru>
+    * BUG 2546: Add support for FreeBSD EA API
+    
+    
+o   Gerald (Jerry) Carter <jerry@samba.org>
+    * Added support for \svcctl pipe rpcs.
+    * Added 'net rpc service' subcommand for managing Win32 
+      services.
+    * Refactoring work on the rpc [un]marshalling layer and 
+      structures.
+    * Verify privilege name in 'net rpc rights privileges' in 
+      order to provide better error messages.
+    * Cleanup rpc structures in rpc_spoolss.h.
+    * Cleanups and fixes for the \winreg server code.
+    * Cleanup of rpc structures used by LsaEnumerateTrustedDomains.
+
+
+o   Jeremy Cooper <jeremy@ncircle.com>
+    * Added support for several new \winreg client rpcs.
+
+
+o   Guenther Deschner <gd@samba.org>
+    * Close handles on group creation in rpcclient to better 
+      support mass group account creation.
+    * Fix account policy key lookup for minimum and maximum
+      password lengths.
+    * Fix some compiler warnings and add missing exclude-block 
+      in 'net rpc share migrate'.
+
+
+o   Steve French <sfrench@us.ibm.com>
+    * Update list of mount options for mount.cifs.
+    * Add more defines for POSIX extensions to match the newly 
+      added client implementation.
+    * Add initial support for cifs umount utility.
+    * Fix cifs mounts to handle commas embedded in prompted 
+      password, and password and credential files.
+    * Fix cifs mounts to handle domain name and user name in 
+      username field (in form domain\user).
+
+
+o   Guenter Kukkukk <guenter.kukkukk@kukkukk.com>
+    * BUG 2541: Fix copying of file(s) from samba share to an OS/2 
+      local drive.
+    
+    
+o   Tom Lackemann <cessnatomny@yahoo.com>
+    * BUG 2242: Patch to ensure that we only set the security 
+      descriptor on an NTtransact create if we created the file.
+    
+
+o   Volker Lendecke <vl@samba.org>
+    * Port some of the non-critical changes from HEAD to 3_0. 
+      The main one is the change in pdb_enum_alias_memberships 
+      to match samr.idl a bit closer.
+    * Close handles on user creation in rpcclient to better 
+      support mass user account creation.
+    * Implement client RAP calls for enumusers/enumgroups level 0.
+    * Implement a new caching API for enumerating the pdb elements.
+    * Convert the RAP user and group enumeration functions to the 
+      utilized the pdb_search API. 
+    * BUG 2438: Partial fix for 'net rpc trustdom establish' in 
+      RestrictAnonymous environments.
+    * Internal passdb API changes for better search capabilities
+      (based on original work by Guenther Deschner).
+
+
+o   Herb Lewis <herb@samba.org>
+    * Compiler warning cleanups.
+    * smbwrapper Makefile and compile time check cleanups.
+
+
+o   Derrell Lipman <derrell@samba.org>
+    * add support for opening a file for write with O_APPEND 
+      in libsmbclient.
+    * Added smbsh/smbwrapper for Linux to example/libsmbclient 
+      tree.
+    * Fix smbc_stat() from returning incorrect timestamps IFF 
+      it used cli_qpathinfo2() to retrieve the timestamps (Win2k) 
+      and not if it used cli-getatr() to retrieve the timestamps 
+      (Win98). 
+    * Fix handful of compiler warnings.
+    * BUG 2498, 2484: smbc_getxattr() fixes.
+    * BUG 1133: Added provision for overloading some global 
+      configuration options via the new, per-user file 
+      ~/.smb/smb.conf.append.
+    * BUG 2543: Properly cache anonymous username when reverting 
+      to anonymous login, in libsmbclient.
+    * BUG 2505: Fix large file support in libsmbclient.
+
+
+o   Jason Mader <jason@ncac.gwu.edu>
+    * BUG 2483, 2468. 2469, 2478, 2093: Compiler warning fixes.
+
+
+o   Jim McDonough <jmcd@us.ibm.com>
+    * Fixes for samr_lookup_rids() when using ldapsam:trusted=yes
+      (in conjunction with Volker).
+
+
+o   Marcel Muller <mueller@maazl.de>
+    * Patch to fix the OS/2 EA_FROM_LIST info level call.
+    * Mangled names fix for OS/2 clients.
+
+
+
+o   James Peach <jpeach@sgi.com>
+    * BUG 1843: Fix quotas (with no soft limits) on IRIX.
+
+
+o   Marcin Porwit <mporwit@centeris.com>
+    * Initial support for the \eventlog pipe.
+    
+
+o   Simo Sorce <idra@samba.org>
+    * Allow Domain Admins to force user sessions to close via the 
+      Windows Server Manager.
+    * Add support to 'net rpc right privileges <name>' to enumerate 
+      accounts which possess a specific privilege.
+
+
+o   Mark Weaver <mark-clist@npsl.co.uk>
+    * Patch to fix sys_select so it can't drop signals if another 
+      fd is ready to read. 
+
+
+o   Jelmer Vernooij <jelmer@samba.org>
+    * Remove --with-manpage-languages configure option.
+
+
+
+Release Notes for older release follow:
+
+      --------------------------------------------------
                    ===============================
                    Release Notes for Samba 3.0.14a
                               Apr 14, 2005
                    ===============================
 
-This is the latest stable release of Samba. This is the version
-that production Samba servers should be running for all current
-bug-fixes.  Please read the following important changes in this
-release.
-
 Common bugs fixed in 3.0.14a include:
 
   o Compatibility issues between Winbind and Windows 2003 SP1
index fcd5ef290030f940ed7de979af8af99ce0ef8340..4b4919ee7ff2bbc3e2cb824a0e19050c6abe090b 100644 (file)
@@ -6,19 +6,24 @@ EXTLIB_INCL = -I/usr/include/gtk-1.2 \
              -I/usr/include/glib-1.2 \
              -I/usr/lib/glib/include
 
-CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL)
+DEFS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+CFLAGS = -O0 -g -I$(SAMBA_INCL) $(EXTLIB_INCL) $(DEFS)
 
-LDFLAGS = -L/usr/lib
+LDFLAGS = -L/usr/local/samba/lib
 
-all: testsmbc tree testacl testbrowse
+TESTS= testsmbc \
+       tree \
+       testacl \
+       testbrowse \
+       teststat \
+       testchmod \
+       testutime
 
-testsmbc: testsmbc.o 
-       @echo Linking testsmbc
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient -L/usr/local/lib
+all:   $(TESTS) smbsh
 
-testsmbc-static: testsmbc.o 
+testsmbc: testsmbc.o 
        @echo Linking testsmbc
-       @$(CC) $(CFLAGS) -static $(LDFLAGS) -o $@ $< -lsmbclient -ldl -lnsl
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lsmbclient
 
 tree: tree.o
        @echo Linking tree
@@ -32,5 +37,21 @@ testbrowse: testbrowse.o
        @echo Linking testbrowse
        @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -lsmbclient -lpopt $<
 
+teststat: teststat.o
+       @echo Linking teststat
+       @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ /usr/local/samba/lib/libsmbclient.so -lpopt $<
+
+testchmod: testchmod.o
+       @echo Linking testchmod
+       @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ /usr/local/samba/lib/libsmbclient.so -lpopt $<
+
+testutime: testutime.o
+       @echo Linking testutime
+       @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ /usr/local/samba/lib/libsmbclient.so -lpopt $<
+
+smbsh:
+       make -C smbwrapper
+
 clean:
-       @rm -f *.o *~
+       @rm -f *.o *~ $(TESTS)
+       @make -C smbwrapper clean
index d9a9f829174d3eeee3919282d1402b50d9471770..c45dd8b9d68cff58aaed9e3b42c6f755c5e40337 100644 (file)
@@ -2,7 +2,16 @@ Some simple example programs for libsmbclient ...
 
 testsmbc.c is kinda broken as it has many hardcoded bits in it
 
+testbrowse.c opens a remote folder and displays its contents
+
+teststat.c allows comparing the results of smbc_stat() against a local stat() of
+the same file.
+
 tree.c is an example of how you might do some of these things with GTK+
 It needs lots of work but shows you some ways to use libsmbclient.
 
-Richard Sharpe, 17-May-2001 ...
+smbwrapper implements the old smbsh/smbwrapper mechanism using libsmbclient, in
+such a way that it works on Linux
+
+Richard Sharpe, 17 May 2001
+Derrell Lipman, 30 Mar 2005
diff --git a/examples/libsmbclient/smbwrapper/Makefile b/examples/libsmbclient/smbwrapper/Makefile
new file mode 100644 (file)
index 0000000..8e7070c
--- /dev/null
@@ -0,0 +1,36 @@
+LIBS = -lsmbclient -ldl
+DEFS = -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+
+CFLAGS = -I$(SAMBA_INCL) $(EXTLIB_INCL)
+
+LDFLAGS = -L/usr/local/samba/lib
+
+SMBINCLUDE = -I../../../source/include
+CFLAGS= -fpic -g -O0 $(DEFS) $(SMBINCLUDE)
+
+BIN    = .
+
+SMBWRAPPER_OBJS        = smbw.o smbw_dir.o smbw_stat.o wrapper.o select.o 
+SMBSH_OBJS     = smbsh.o
+
+all:   $(BIN)/smbwrapper.so $(BIN)/smbsh
+
+$(BIN)/smbwrapper.so:  $(SMBWRAPPER_OBJS)
+       $(CC) -g \
+               -Wl,-init=smbw_initialize \
+               -shared \
+               --export-all-symbols \
+               -o $(BIN)/smbwrapper.so \
+               $(SMBWRAPPER_OBJS) \
+               $(LDFLAGS) \
+               $(LIBS) \
+               -Wl,-soname=`basename $@`
+
+$(BIN)/smbsh: $(SMBSH_OBJS)
+       $(CC) -g -o $(BIN)/smbsh $(SMBSH_OBJS) $(LIBS) $(LDFLAGS)
+
+opendir_smbsh: opendir_smbsh.o
+       $(CC) -g -o opendir_smbsh opendir_smbsh.o $(LIBS) $(DMALLOC)
+
+clean:
+       rm -f *.o *~ opendir_smbsh smbsh smbwrapper.so
diff --git a/examples/libsmbclient/smbwrapper/README b/examples/libsmbclient/smbwrapper/README
new file mode 100644 (file)
index 0000000..7b71ec0
--- /dev/null
@@ -0,0 +1,40 @@
+To create "smbsh" on Linux, just type "make".
+
+If you execute "smbsh" in *this* directory (so that it can find the required
+shared library), you'll find yourself in a new shell.  You can then issue
+commands referencing the "/smb" pseudo-filesystem:
+
+  ls /smb
+  ls /smb/WORKGROUP_OR_DOMAIN
+  ls /smb/SERVER
+  ls /smb/SERVER/SHARE
+  ls /smb/SERVER/SHARE/PATH
+
+Note that WORKGROUP_OR_DOMAIN is *not* used other than at that level.  This is
+consistent with the smb:// URI definition.
+
+Usage:
+  smbsh [-L <path to find smbwrapper.so>]
+        [-p <library to load before smbwrapper.so>]
+        [-a <library to load after smbwrapper.so>]
+        [-d <debug value for libsmbclient>]
+        [-n]                                    (do not ask for username/password)
+        [-W <workgroup>]
+        [-U <username%password]
+        [command]
+
+So to list the contents of \\MYDESK\C$ where a username (adventure) and password
+(xyzzy) are required, and with smbwrapper.so installed in /usr/share/samba, you
+could try:
+
+  smbsh -L /usr/share/samba -U adventure%xyzzy ls '/smb/MYDESK/C$'
+
+(It's a good idea to get in the habit of surrounding windows paths in single
+quotes, since they often contain spaces and other characters that'll give you
+headaches when not escaped.)
+
+This smbsh seems to work quite well on Linux 2.4 and 2.6.  The biggest problem it
+has is in tracking your current working directory.  I haven't had the time to
+track that down and fix it.
+
+Derrell Lipman
diff --git a/examples/libsmbclient/smbwrapper/opendir_smbsh.c b/examples/libsmbclient/smbwrapper/opendir_smbsh.c
new file mode 100644 (file)
index 0000000..275b95f
--- /dev/null
@@ -0,0 +1,47 @@
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <libsmbclient.h>
+
+int
+main(int argc, char * argv[])
+{
+    char *          p;
+    char            buf[1024];
+    DIR *           dir;
+    struct dirent * dirent;
+
+    setbuf(stdout, NULL);
+
+    for (fputs("path: ", stdout), p = fgets(buf, sizeof(buf), stdin);
+         p != NULL && *p != '\n' && *p != '\0';
+         fputs("path: ", stdout), p = fgets(buf, sizeof(buf), stdin))
+    {
+        if ((p = strchr(buf, '\n')) != NULL)
+        {
+            *p = '\0';
+        }
+        
+        printf("Opening (%s)...\n", buf);
+        
+        if ((dir = opendir(buf)) == NULL)
+        {
+            printf("Could not open directory [%s]: \n",
+                   buf, strerror(errno));
+            continue;
+        }
+
+        while ((dirent = readdir(dir)) != NULL)
+        {
+            printf("%-30s", dirent->d_name);
+            printf("%-30s", dirent->d_name + strlen(dirent->d_name) + 1);
+            printf("\n");
+        }
+
+        closedir(dir);
+    }
+
+    exit(0);
+}
diff --git a/examples/libsmbclient/smbwrapper/select.c b/examples/libsmbclient/smbwrapper/select.c
new file mode 100644 (file)
index 0000000..aa90169
--- /dev/null
@@ -0,0 +1,124 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   Samba select/poll implementation
+   Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * WHY THIS FILE?
+ *
+ * This file implements the two functions in the select() family, as required
+ * by samba.  The samba native functions, though, implement a pipe to help
+ * alleviate a deadlock problem, but which creates problems of its own (the
+ * timeout stops working correctly).  Those functions also require that all
+ * signal handlers call a function which writes to the pipe -- a task which is
+ * difficult to do in the smbwrapper environment.
+ */
+
+
+#include <sys/select.h>
+#include <errno.h>
+#include <stdio.h>
+
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
+{
+        int ret;
+       fd_set *readfds2, readfds_buf;
+
+       /* If readfds is NULL we need to provide our own set. */
+       if (readfds) {
+               readfds2 = readfds;
+       } else {
+               readfds2 = &readfds_buf;
+               FD_ZERO(readfds2);
+       }
+
+       errno = 0;
+       ret = select(maxfd,readfds2,writefds,errorfds,tval);
+
+       if (ret <= 0) {
+               FD_ZERO(readfds2);
+               if (writefds)
+                       FD_ZERO(writefds);
+               if (errorfds)
+                       FD_ZERO(errorfds);
+       }
+
+       return ret;
+}
+
+/*******************************************************************
+ Similar to sys_select() but catch EINTR and continue.
+ This is what sys_select() used to do in Samba.
+********************************************************************/
+
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
+{
+       int ret;
+       fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
+       struct timeval tval2, *ptval, end_time, now_time;
+        extern void GetTimeOfDay(struct timeval *tval);
+
+       readfds2 = (readfds ? &readfds_buf : NULL);
+       writefds2 = (writefds ? &writefds_buf : NULL);
+       errorfds2 = (errorfds ? &errorfds_buf : NULL);
+        if (tval) {
+                GetTimeOfDay(&end_time);
+                end_time.tv_sec += tval->tv_sec;
+                end_time.tv_usec += tval->tv_usec;
+                end_time.tv_sec += end_time.tv_usec / 1000000;
+                end_time.tv_usec %= 1000000;
+                ptval = &tval2;
+        } else {
+                ptval = NULL;
+        }
+
+       do {
+               if (readfds)
+                       readfds_buf = *readfds;
+               if (writefds)
+                       writefds_buf = *writefds;
+               if (errorfds)
+                       errorfds_buf = *errorfds;
+               if (tval) {
+                        GetTimeOfDay(&now_time);
+                        tval2.tv_sec = end_time.tv_sec - now_time.tv_sec;
+                       tval2.tv_usec = end_time.tv_usec - now_time.tv_usec;
+                        if ((signed long) tval2.tv_usec < 0) {
+                                tval2.tv_usec += 1000000;
+                                tval2.tv_sec--;
+                        }
+                        if ((signed long) tval2.tv_sec < 0) {
+                                ret = 0;
+                                break;          /* time has already elapsed */
+                        }
+                }
+
+               ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
+       } while (ret == -1 && errno == EINTR);
+
+       if (readfds)
+               *readfds = readfds_buf;
+       if (writefds)
+               *writefds = writefds_buf;
+       if (errorfds)
+               *errorfds = errorfds_buf;
+
+       return ret;
+}
diff --git a/examples/libsmbclient/smbwrapper/smbsh.c b/examples/libsmbclient/smbwrapper/smbsh.c
new file mode 100644 (file)
index 0000000..7b33de7
--- /dev/null
@@ -0,0 +1,160 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper functions - frontend
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <libsmbclient.h>
+
+#ifndef FALSE
+# define        FALSE   (0)
+# define        TRUE    (! FALSE)
+#endif
+
+static void smbsh_usage(void)
+{
+       printf("smbsh [options] [command [args] ...]\n\n");
+        printf(" -p prepend library name\n");
+        printf(" -a append library name\n");
+        printf(" -n");
+       printf(" -W workgroup\n");
+       printf(" -U username\n");
+       printf(" -P prefix\n");
+       printf(" -R resolve order\n");
+       printf(" -d debug level\n");
+       printf(" -l logfile\n");
+       printf(" -L libdir\n");
+       exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+       char *p, *u;
+       char *libd = ".";
+       char line[PATH_MAX], pre[PATH_MAX], post[PATH_MAX];
+       int opt;
+        int no_ask = 0;
+        struct stat statbuf;
+       extern char *optarg;
+       extern int optind;
+
+        *pre = *post = '\0';
+
+       while ((opt = getopt(argc, argv, "p:a:d:nL:W:U:h")) != -1) {
+               switch (opt) {
+                case 'p':       /* prepend library before smbwrapper.so */
+                        if (*pre != '\0')
+                                strncat(pre, " ", PATH_MAX - strlen(pre));
+                        strncat(pre, optarg, PATH_MAX - strlen(pre));
+                        break;
+                        
+                case 'a':       /* append library after smbwrapper.so */
+                        strncat(post, " ", PATH_MAX - strlen(post));
+                        strncat(post, optarg, PATH_MAX - strlen(post));
+                        break;
+                        
+                case 'd':
+                        setenv("DEBUG", optarg, TRUE);
+                        break;
+
+                case 'n':       /* don't ask for username/password */
+                        no_ask++;
+                        break;
+
+               case 'L':
+                       libd = optarg;
+                       break;
+
+               case 'W':
+                       setenv("WORKGROUP", optarg, TRUE);
+                       break;
+
+               case 'U':
+                       p = strchr(optarg,'%');
+                       if (p) {
+                               *p=0;
+                               setenv("PASSWORD", p+1, TRUE);
+                       }
+                       setenv("USER", optarg, TRUE);
+                       break;
+
+               case 'h':
+               default:
+                       smbsh_usage();
+               }
+       }
+
+
+        if (! no_ask) {
+                if (!getenv("USER")) {
+                        printf("Username: ");
+                        u = fgets(line, sizeof(line)-1, stdin);
+                        setenv("USER", u, TRUE);
+                }
+                
+                if (!getenv("PASSWORD")) {
+                        p = getpass("Password: ");
+                        setenv("PASSWORD", p, TRUE);
+                }
+        }
+
+        strncpy(line, pre, PATH_MAX - strlen(line));
+        strncat(line, " ", PATH_MAX - strlen(line));
+        strncat(line, libd, PATH_MAX - strlen(line));
+        strncat(line, "/smbwrapper.so", PATH_MAX - strlen(line));
+        strncat(line, post, PATH_MAX - strlen(line));
+       setenv("LD_PRELOAD", line, TRUE);
+        setenv("LD_BIND_NOW", "true", TRUE);
+
+       snprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so", libd);
+
+       if (stat(line, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) {
+               snprintf(line,sizeof(line)-1,"%s/smbwrapper.32.so:DEFAULT", libd);
+               setenv("_RLD_LIST", line, TRUE);
+               snprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
+               setenv("_RLDN32_LIST", line, TRUE);
+       } else {
+               snprintf(line,sizeof(line)-1,"%s/smbwrapper.so:DEFAULT", libd);
+               setenv("_RLD_LIST", line, TRUE);
+       }
+
+        if (optind < argc) {
+                execvp(argv[optind], &argv[optind]);
+        } else {
+                char *shellpath = getenv("SHELL");
+
+                setenv("PS1", "smbsh$ ", TRUE);
+
+                if(shellpath) {
+                       execl(shellpath,"smbsh", NULL);
+                } else {
+                        setenv("SHELL", "/bin/sh", TRUE);
+                       execl("/bin/sh", "smbsh", NULL);
+                }
+       }
+       printf("launch failed!\n");
+       return 1;
+}      
diff --git a/examples/libsmbclient/smbwrapper/smbw.c b/examples/libsmbclient/smbwrapper/smbw.c
new file mode 100644 (file)
index 0000000..d2f1c18
--- /dev/null
@@ -0,0 +1,910 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper functions
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <assert.h>
+#include "smbw.h"
+
+int smbw_fd_map[__FD_SETSIZE];
+int smbw_ref_count[__FD_SETSIZE];
+char smbw_cwd[PATH_MAX];
+char smbw_prefix[] = SMBW_PREFIX;
+
+/* needs to be here because of dumb include files on some systems */
+int creat_bits = O_WRONLY|O_CREAT|O_TRUNC;
+
+int smbw_initialized = 0;
+
+static int debug_level = 0;
+
+static SMBCCTX *smbw_ctx;
+
+extern int smbw_debug;
+
+
+int smbw_ref(int client_fd, Ref_Count_Type type, ...)
+{
+        va_list ap;
+
+        /* client id values begin at SMBC_BASE_FC. */
+        client_fd -= SMBC_BASE_FD;
+
+        va_start(ap, type);
+        switch(type)
+        {
+        case SMBW_RCT_Increment:
+                return ++smbw_ref_count[client_fd];
+
+        case SMBW_RCT_Decrement:
+                return --smbw_ref_count[client_fd];
+
+        case SMBW_RCT_Get:
+                return smbw_ref_count[client_fd];
+
+        case SMBW_RCT_Set:
+                return (smbw_ref_count[client_fd] = va_arg(ap, int));
+        }
+        va_end(ap);
+
+        /* never gets here */
+        return -1;
+}
+
+
+/*
+ * Return a username and password given a server and share name
+ *
+ * Returns 0 upon success;
+ * non-zero otherwise, and errno is set to indicate the error.
+ */
+static void get_envvar_auth_data(const char *srv, 
+                                 const char *shr,
+                                 char *wg, int wglen, 
+                                 char *un, int unlen,
+                                 char *pw, int pwlen)
+{
+        char *u;
+        char *p;
+        char *w;
+
+       /* Fall back to environment variables */
+
+       w = getenv("WORKGROUP");
+       if (w == NULL) w = "";
+
+       u = getenv("USER");
+       if (u == NULL) u = "";
+
+       p = getenv("PASSWORD");
+       if (p == NULL) p = "";
+
+        strncpy(wg, w, wglen);
+        strncpy(un, u, unlen);
+        strncpy(pw, p, pwlen);
+}
+
+static smbc_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data;
+
+/*****************************************************
+set the get auth data function
+******************************************************/
+void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn)
+{
+       get_auth_data_fn = fn;
+}
+
+
+/*****************************************************
+ensure that all connections are terminated upon exit
+******************************************************/
+static void do_shutdown(void)
+{
+        if (smbw_ctx != NULL) {
+                smbc_free_context(smbw_ctx, 1);
+        }
+}
+
+
+/***************************************************** 
+initialise structures
+*******************************************************/
+static void do_init(int is_real_startup)
+{
+        int i;
+        char *p;
+
+       smbw_initialized = 1;   /* this must be first to avoid recursion! */
+
+        smbw_ctx = NULL;        /* don't free context until it's established */
+
+        /* initially, no file descriptors are mapped */
+        for (i = 0; i < __FD_SETSIZE; i++) {
+                smbw_fd_map[i] = -1;
+                smbw_ref_count[i] = 0;
+        }
+
+        /* See if we've been told to start in a particular directory */
+        if ((p=getenv("SMBW_DIR")) != NULL) {
+                strncpy(smbw_cwd, p, PATH_MAX);
+
+                /* we don't want the old directory to be busy */
+                (* smbw_libc.chdir)("/");
+                
+        } else {
+                *smbw_cwd = '\0';
+        }
+
+       if ((p=getenv("DEBUG"))) {
+               debug_level = atoi(p);
+       }
+
+        if ((smbw_ctx = smbc_new_context()) == NULL) {
+                exit(1);
+        }
+        
+        smbw_ctx->debug = debug_level;
+        smbw_ctx->callbacks.auth_fn = get_auth_data_fn;
+        smbw_ctx->options.browse_max_lmb_count = 0;
+        smbw_ctx->options.urlencode_readdir_entries = 1;
+        smbw_ctx->options.one_share_per_server = 1;
+//        smbw_cache_functions(smbw_ctx);
+        
+        if (smbc_init_context(smbw_ctx) == NULL) {
+                exit(1);
+        }
+                
+        smbc_set_context(smbw_ctx);
+
+        /* if not real startup, exit handler has already been established */
+        if (is_real_startup) {
+            atexit(do_shutdown);
+        }
+}
+
+/***************************************************** 
+initialise structures, real start up vs a fork()
+*******************************************************/
+void smbw_init(void)
+{
+    do_init(1);
+}
+
+
+/***************************************************** 
+determine if a file descriptor is a smb one
+*******************************************************/
+int smbw_fd(int smbw_fd)
+{
+        SMBW_INIT();
+
+        return (smbw_fd >= 0 &&
+                smbw_fd < __FD_SETSIZE &&
+                smbw_fd_map[smbw_fd] >= SMBC_BASE_FD); /* minimum smbc_ fd */
+}
+
+
+/***************************************************** 
+determine if a path is a smb one
+*******************************************************/
+int smbw_path(const char *name)
+{
+        int len;
+        int ret;
+        int saved_errno;
+
+        saved_errno = errno;
+
+        SMBW_INIT();
+
+        len = strlen(smbw_prefix);
+
+        ret = ((strncmp(name, smbw_prefix, len) == 0 &&
+                (name[len] == '\0' || name[len] == '/')) ||
+               (*name != '/' && *smbw_cwd != '\0'));
+
+        errno = saved_errno;
+        return ret;
+}
+
+
+/***************************************************** 
+remove redundent stuff from a filename
+*******************************************************/
+void smbw_clean_fname(char *name)
+{
+       char *p, *p2;
+       int l;
+       int modified = 1;
+
+       if (!name) return;
+
+        DEBUG(10, ("Clean [%s]...\n", name));
+
+       while (modified) {
+               modified = 0;
+
+               if ((p=strstr(name,"/./"))) {
+                       modified = 1;
+                       while (*p) {
+                               p[0] = p[2];
+                               p++;
+                       }
+                        DEBUG(10, ("\tclean 1 (/./) produced [%s]\n", name));
+               }
+
+               if ((p=strstr(name,"//"))) {
+                       modified = 1;
+                       while (*p) {
+                               p[0] = p[1];
+                               p++;
+                       }
+                        DEBUG(10, ("\tclean 2 (//) produced [%s]\n", name));
+               }
+
+               if (strcmp(name,"/../")==0) {
+                       modified = 1;
+                       name[1] = 0;
+                        DEBUG(10,("\tclean 3 (^/../$) produced [%s]\n", name));
+               }
+
+               if ((p=strstr(name,"/../"))) {
+                       modified = 1;
+                       for (p2 = (p > name ? p-1 : p); p2 > name; p2--) {
+                               if (p2[0] == '/') break;
+                       }
+                        if (p2 > name) p2++;
+                       while (*p2) {
+                               p2[0] = p[3];
+                               p2++;
+                                p++;
+                       }
+                        DEBUG(10, ("\tclean 4 (/../) produced [%s]\n", name));
+               }
+
+               if (strcmp(name,"/..")==0) {
+                       modified = 1;
+                       name[1] = 0;
+                        DEBUG(10, ("\tclean 5 (^/..$) produced [%s]\n", name));
+               }
+
+               l = strlen(name);
+               p = l>=3?(name+l-3):name;
+               if (strcmp(p,"/..")==0) {
+                       modified = 1;
+                       for (p2=p-1;p2>name;p2--) {
+                               if (p2[0] == '/') break;
+                       }
+                       if (p2==name) {
+                               p[0] = '/';
+                               p[1] = 0;
+                       } else {
+                               p2[0] = 0;
+                       }
+                        DEBUG(10, ("\tclean 6 (/..) produced [%s]\n", name));
+               }
+
+               l = strlen(name);
+               p = l>=2?(name+l-2):name;
+               if (strcmp(p,"/.")==0) {
+                        modified = 1;
+                       if (p == name) {
+                               p[1] = 0;
+                       } else {
+                               p[0] = 0;
+                       }
+                        DEBUG(10, ("\tclean 7 (/.) produced [%s]\n", name));
+               }
+
+               if (strncmp(p=name,"./",2) == 0) {      
+                       modified = 1;
+                       do {
+                               p[0] = p[2];
+                       } while (*p++);
+                        DEBUG(10, ("\tclean 8 (^./) produced [%s]\n", name));
+               }
+
+               l = strlen(p=name);
+               if (l > 1 && p[l-1] == '/') {
+                       modified = 1;
+                       p[l-1] = 0;
+                        DEBUG(10, ("\tclean 9 (/) produced [%s]\n", name));
+               }
+       }
+}
+
+void smbw_fix_path(const char *src, char *dest)
+{
+        const char *p;
+        int len = strlen(smbw_prefix);
+
+        if (*src == '/') {
+                for (p = src + len; *p == '/'; p++)
+                        ;
+                snprintf(dest, PATH_MAX, "smb://%s", p);
+        } else {
+                snprintf(dest, PATH_MAX, "%s/%s", smbw_cwd, src);
+        }
+
+        smbw_clean_fname(dest + 5);
+
+        DEBUG(10, ("smbw_fix_path(%s) returning [%s]\n", src, dest));
+}
+
+
+
+/***************************************************** 
+a wrapper for open()
+*******************************************************/
+int smbw_open(const char *fname, int flags, mode_t mode)
+{
+        int client_fd;
+        int smbw_fd;
+       char path[PATH_MAX];
+
+       SMBW_INIT();
+
+       if (!fname) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       smbw_fd = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200);
+       if (smbw_fd == -1) {
+               errno = EMFILE;
+                return -1;
+       }
+
+        smbw_fix_path(fname, path);
+        if (flags == creat_bits) {
+                client_fd =  smbc_creat(path, mode);
+        } else {
+                client_fd = smbc_open(path, flags, mode);
+        }
+
+        if (client_fd < 0) {
+                (* smbw_libc.close)(smbw_fd);
+                return -1;
+        }
+
+        smbw_fd_map[smbw_fd] = client_fd;
+        smbw_ref(client_fd, SMBW_RCT_Increment);
+        return smbw_fd;
+}
+
+
+/***************************************************** 
+a wrapper for pread()
+
+there should really be an smbc_pread() to avoid the two
+lseek()s required in this kludge.
+*******************************************************/
+ssize_t smbw_pread(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs)
+{
+        int client_fd;
+       ssize_t ret;
+        int saved_errno;
+        SMBW_OFF_T old_ofs;
+        
+        client_fd = smbw_fd_map[smbw_fd];
+
+        if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 ||
+            smbc_lseek(client_fd, ofs, SEEK_SET) < 0) {
+                return -1;
+        }
+
+        if ((ret = smbc_read(client_fd, buf, count)) < 0) {
+                saved_errno = errno;
+                (void) smbc_lseek(client_fd, old_ofs, SEEK_SET);
+                errno = saved_errno;
+                return -1;
+        }
+
+        return ret;
+}
+
+/***************************************************** 
+a wrapper for read()
+*******************************************************/
+ssize_t smbw_read(int smbw_fd, void *buf, size_t count)
+{
+        int client_fd;
+        
+        client_fd = smbw_fd_map[smbw_fd];
+
+        return smbc_read(client_fd, buf, count);
+}
+
+       
+
+/***************************************************** 
+a wrapper for write()
+*******************************************************/
+ssize_t smbw_write(int smbw_fd, void *buf, size_t count)
+{
+        int client_fd;
+
+        client_fd = smbw_fd_map[smbw_fd];
+
+        return smbc_write(client_fd, buf, count);
+}
+
+/***************************************************** 
+a wrapper for pwrite()
+*******************************************************/
+ssize_t smbw_pwrite(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs)
+{
+        int saved_errno;
+        int client_fd;
+       ssize_t ret;
+        SMBW_OFF_T old_ofs;
+        
+        client_fd = smbw_fd_map[smbw_fd];
+
+        if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 ||
+            smbc_lseek(client_fd, ofs, SEEK_SET) < 0) {
+                return -1;
+        }
+
+        if ((ret = smbc_write(client_fd, buf, count)) < 0) {
+                saved_errno = errno;
+                (void) smbc_lseek(client_fd, old_ofs, SEEK_SET);
+                errno = saved_errno;
+                return -1;
+        }
+
+        return ret;
+}
+
+/***************************************************** 
+a wrapper for close()
+*******************************************************/
+int smbw_close(int smbw_fd)
+{
+        int client_fd;
+
+        client_fd = smbw_fd_map[smbw_fd];
+
+        if (smbw_ref(client_fd, SMBW_RCT_Decrement) > 0) {
+                return 0;
+        }
+        
+        (* smbw_libc.close)(smbw_fd);
+        smbw_fd_map[smbw_fd] = -1;
+        return smbc_close(client_fd);
+}
+
+
+/***************************************************** 
+a wrapper for fcntl()
+*******************************************************/
+int smbw_fcntl(int smbw_fd, int cmd, long arg)
+{
+       return 0;
+}
+
+
+/***************************************************** 
+a wrapper for access()
+*******************************************************/
+int smbw_access(const char *name, int mode)
+{
+       struct SMBW_stat st;
+
+        SMBW_INIT();
+
+       if (smbw_stat(name, &st)) return -1;
+
+       if (((mode & R_OK) && !(st.s_mode & S_IRUSR)) ||
+           ((mode & W_OK) && !(st.s_mode & S_IWUSR)) ||
+           ((mode & X_OK) && !(st.s_mode & S_IXUSR))) {
+               errno = EACCES;
+               return -1;
+       }
+       
+       return 0;
+}
+
+/***************************************************** 
+a wrapper for readlink() - needed for correct errno setting
+*******************************************************/
+int smbw_readlink(const char *fname, char *buf, size_t bufsize)
+{
+       struct SMBW_stat st;
+       int ret;
+
+        SMBW_INIT();
+
+       ret = smbw_stat(fname, &st);
+       if (ret != 0) {
+               return -1;
+       }
+       
+       /* it exists - say it isn't a link */
+       errno = EINVAL;
+       return -1;
+}
+
+
+/***************************************************** 
+a wrapper for unlink()
+*******************************************************/
+int smbw_unlink(const char *fname)
+{
+        char path[PATH_MAX];
+        
+        SMBW_INIT();
+
+        smbw_fix_path(fname, path);
+        return smbc_unlink(path);
+}
+
+
+/***************************************************** 
+a wrapper for rename()
+*******************************************************/
+int smbw_rename(const char *oldname, const char *newname)
+{
+        char path_old[PATH_MAX];
+        char path_new[PATH_MAX];
+
+        SMBW_INIT();
+
+        smbw_fix_path(oldname, path_old);
+        smbw_fix_path(newname, path_new);
+        return smbc_rename(path_old, path_new);
+}
+
+
+/***************************************************** 
+a wrapper for utimes
+*******************************************************/
+int smbw_utimes(const char *fname, void *buf)
+{
+        char path[PATH_MAX];
+
+        smbw_fix_path(fname, path);
+       return smbc_utimes(path, buf);
+}
+
+
+/***************************************************** 
+a wrapper for utime 
+*******************************************************/
+int smbw_utime(const char *fname, void *buf)
+{
+        char path[PATH_MAX];
+
+        smbw_fix_path(fname, path);
+        return smbc_utime(path, buf);
+}
+
+/***************************************************** 
+a wrapper for chown()
+*******************************************************/
+int smbw_chown(const char *fname, uid_t owner, gid_t group)
+{
+        /* always indiciate that this is not supported. */
+        errno = ENOTSUP;
+        return -1;
+}
+
+/***************************************************** 
+a wrapper for chmod()
+*******************************************************/
+int smbw_chmod(const char *fname, mode_t newmode)
+{
+        char path[PATH_MAX];
+
+        smbw_fix_path(fname, path);
+        return smbc_chmod(path, newmode);
+}
+
+
+/***************************************************** 
+a wrapper for lseek()
+*******************************************************/
+SMBW_OFF_T smbw_lseek(int smbw_fd,
+                      SMBW_OFF_T offset,
+                      int whence)
+{
+        int client_fd;
+        SMBW_OFF_T ret;
+        
+        client_fd = smbw_fd_map[smbw_fd];
+
+        ret = smbc_lseek(client_fd, offset, whence);
+        if (smbw_debug)
+        {
+                printf("smbw_lseek(%d/%d, 0x%llx) returned 0x%llx\n",
+                       smbw_fd, client_fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+/***************************************************** 
+a wrapper for dup()
+*******************************************************/
+int smbw_dup(int smbw_fd)
+{
+       int fd2;
+
+       fd2 = (smbw_libc.dup)(smbw_fd);
+       if (fd2 == -1) {
+                return -1;
+       }
+
+        smbw_fd_map[fd2] = smbw_fd_map[smbw_fd];
+        smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment);
+       return fd2;
+}
+
+
+/***************************************************** 
+a wrapper for dup2()
+*******************************************************/
+int smbw_dup2(int smbw_fd, int fd2)
+{
+       if ((* smbw_libc.dup2)(smbw_fd, fd2) != fd2) {
+                return -1;
+       }
+
+        smbw_fd_map[fd2] = smbw_fd_map[smbw_fd];
+        smbw_ref(smbw_fd_map[smbw_fd], SMBW_RCT_Increment);
+       return fd2;
+}
+
+
+/***************************************************** 
+when we fork we have to close all connections and files
+in the child
+*******************************************************/
+int smbw_fork(void)
+{
+        int i;
+       pid_t child_pid;
+       int p[2];
+       char c = 0;
+
+        SMBW_INIT();
+
+       if (pipe(p)) return (* smbw_libc.fork)();
+
+       child_pid = (* smbw_libc.fork)();
+
+       if (child_pid) {
+               /* block the parent for a moment until the sockets are
+                   closed */
+               (* smbw_libc.close)(p[1]);
+               (* smbw_libc.read)(p[0], &c, 1);
+               (* smbw_libc.close)(p[0]);
+               return child_pid;
+        }
+
+       (* smbw_libc.close)(p[0]);
+
+        /* close all server connections and locally-opened files */
+        for (i = 0; i < __FD_SETSIZE; i++) {
+                if (smbw_fd_map[i] > 0 &&
+                    smbw_ref(smbw_fd_map[i], SMBW_RCT_Get) > 0) {
+                        
+                        smbc_close(smbw_fd_map[i]);
+                        smbw_ref(smbw_fd_map[i], SMBW_RCT_Set, 0);
+                        (* smbw_libc.close)(i);
+                }
+
+                smbw_fd_map[i] = -1;
+        }
+
+       /* unblock the parent */
+       write(p[1], &c, 1);
+       (* smbw_libc.close)(p[1]);
+
+        /* specify directory to start in, if it's simulated smb */
+        if (*smbw_cwd != '\0') {
+                setenv("SMBW_DIR", smbw_cwd, 1);
+        } else {
+                unsetenv("SMBW_DIR");
+        }
+
+        /* Re-initialize this library for the child */
+        do_init(0);
+
+       /* and continue in the child */
+       return 0;
+}
+
+int smbw_setxattr(const char *fname,
+                  const char *name,
+                  const void *value,
+                  size_t size,
+                  int flags)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+        return smbc_setxattr(path, name, value, size, flags);
+}
+
+int smbw_lsetxattr(const char *fname,
+                   const char *name,
+                   const void *value,
+                   size_t size,
+                   int flags)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+        return smbc_lsetxattr(path, name, value, size, flags);
+}
+
+int smbw_fsetxattr(int smbw_fd,
+                   const char *name,
+                   const void *value,
+                   size_t size,
+                   int flags)
+{
+        int client_fd;
+        
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        client_fd = smbw_fd_map[smbw_fd];
+        return smbc_fsetxattr(client_fd, name, value, size, flags);
+}
+
+int smbw_getxattr(const char *fname,
+                  const char *name,
+                  const void *value,
+                  size_t size)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+
+        return smbc_getxattr(path, name, value, size);
+}
+
+int smbw_lgetxattr(const char *fname,
+                   const char *name,
+                   const void *value,
+                   size_t size)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+        return smbc_lgetxattr(path, name, value, size);
+}
+
+int smbw_fgetxattr(int smbw_fd,
+                   const char *name,
+                   const void *value,
+                   size_t size)
+{
+        int client_fd;
+        
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        client_fd = smbw_fd_map[smbw_fd];
+        return smbc_fgetxattr(client_fd, name, value, size);
+}
+
+int smbw_removexattr(const char *fname,
+                     const char *name)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+        return smbc_removexattr(path, name);
+}
+
+int smbw_lremovexattr(const char *fname,
+                      const char *name)
+{
+        char path[PATH_MAX];
+
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        smbw_fix_path(fname, path);
+        return smbc_lremovexattr(path, name);
+}
+
+int smbw_fremovexattr(int smbw_fd,
+                      const char *name)
+{
+        int client_fd;
+        
+        if (strcmp(name, "system.posix_acl_access") == 0)
+        {
+                name = "system.*";
+        }
+
+        client_fd = smbw_fd_map[smbw_fd];
+        return smbc_fremovexattr(client_fd, name);
+}
+
+int smbw_listxattr(const char *fname,
+                   char *list,
+                   size_t size)
+{
+        char path[PATH_MAX];
+
+        smbw_fix_path(fname, path);
+        return smbc_listxattr(path, list, size);
+}
+
+int smbw_llistxattr(const char *fname,
+                    char *list,
+                    size_t size)
+{
+        char path[PATH_MAX];
+
+        smbw_fix_path(fname, path);
+        return smbc_llistxattr(path, list, size);
+}
+
+int smbw_flistxattr(int smbw_fd,
+                    char *list,
+                    size_t size)
+{
+        int client_fd;
+        
+        client_fd = smbw_fd_map[smbw_fd];
+        return smbc_flistxattr(client_fd, list, size);
+}
diff --git a/examples/libsmbclient/smbwrapper/smbw.h b/examples/libsmbclient/smbwrapper/smbw.h
new file mode 100644 (file)
index 0000000..717b5c2
--- /dev/null
@@ -0,0 +1,163 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper functions - definitions
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SMBW_H
+#define _SMBW_H
+
+#include <sys/types.h>
+#include <errno.h>
+#include <malloc.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "config.h"             /* must come before libsmbclient.h */
+#include "libsmbclient.h"
+#include "wrapper.h"
+
+#undef DEBUG
+#define DEBUG(level, s) do { if (level <= debug_level) printf s; } while (0)
+
+
+#define SMBW_PREFIX "/smb"
+#define SMBW_DUMMY "/dev/null"
+
+extern int smbw_initialized;
+#define SMBW_INIT()     do { if (! smbw_initialized) smbw_init(); } while (0)
+
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)
+#  define SMBW_OFF_T off64_t
+#else
+#  define SMBW_OFF_T off_t
+#endif
+
+
+/* The following definitions come from  smbwrapper/smbw.c  */
+
+typedef enum {
+        SMBW_RCT_Increment,
+        SMBW_RCT_Decrement,
+        SMBW_RCT_Get,
+        SMBW_RCT_Set
+} Ref_Count_Type;
+
+int smbw_ref(int client_fd, Ref_Count_Type type, ...);
+void smbw_init(void);
+int smbw_fd(int fd);
+int smbw_path(const char *path);
+void smbw_clean_fname(char *name);
+void smbw_fix_path(const char *src, char *dest);
+void smbw_set_auth_data_fn(smbc_get_auth_data_fn fn);
+int smbw_open(const char *fname, int flags, mode_t mode);
+ssize_t smbw_pread(int fd, void *buf, size_t count, SMBW_OFF_T ofs);
+ssize_t smbw_read(int fd, void *buf, size_t count);
+ssize_t smbw_write(int fd, void *buf, size_t count);
+ssize_t smbw_pwrite(int fd, void *buf, size_t count, SMBW_OFF_T ofs);
+int smbw_close(int fd);
+int smbw_fcntl(int fd, int cmd, long arg);
+int smbw_access(const char *name, int mode);
+int smbw_readlink(const char *path, char *buf, size_t bufsize);
+int smbw_unlink(const char *fname);
+int smbw_rename(const char *oldname, const char *newname);
+int smbw_utime(const char *fname, void *buf);
+int smbw_utimes(const char *fname, void *buf);
+int smbw_chown(const char *fname, uid_t owner, gid_t group);
+int smbw_chmod(const char *fname, mode_t newmode);
+SMBW_OFF_T smbw_lseek(int smbw_fd, SMBW_OFF_T offset, int whence);
+int smbw_dup(int fd);
+int smbw_dup2(int fd, int fd2);
+int smbw_fork(void);
+
+/* The following definitions come from  smbwrapper/smbw_dir.c  */
+
+int smbw_dirp(DIR * dirp);
+int smbw_dir_open(const char *fname);
+int smbw_dir_fstat(int fd, SMBW_stat *st);
+int smbw_dir_close(int fd);
+int smbw_getdents(unsigned int fd, SMBW_dirent *dirp, int count);
+int smbw_chdir(const char *name);
+int smbw_mkdir(const char *fname, mode_t mode);
+int smbw_rmdir(const char *fname);
+char *smbw_getcwd(char *buf, size_t size);
+int smbw_fchdir(int fd);
+DIR *smbw_opendir(const char *fname);
+SMBW_dirent *smbw_readdir(DIR *dirp);
+int smbw_readdir_r(DIR *dirp,
+                   struct SMBW_dirent *__restrict entry,
+                   struct SMBW_dirent **__restrict result);
+int smbw_closedir(DIR *dirp);
+void smbw_seekdir(DIR *dirp, long long offset);
+long long smbw_telldir(DIR *dirp);
+int smbw_setxattr(const char *fname,
+                  const char *name,
+                  const void *value,
+                  size_t size,
+                  int flags);
+int smbw_lsetxattr(const char *fname,
+                   const char *name,
+                   const void *value,
+                   size_t size,
+                   int flags);
+int smbw_fsetxattr(int smbw_fd,
+                   const char *name,
+                   const void *value,
+                   size_t size,
+                   int flags);
+int smbw_getxattr(const char *fname,
+                  const char *name,
+                  const void *value,
+                  size_t size);
+int smbw_lgetxattr(const char *fname,
+                   const char *name,
+                   const void *value,
+                   size_t size);
+int smbw_fgetxattr(int smbw_fd,
+                   const char *name,
+                   const void *value,
+                   size_t size);
+int smbw_removexattr(const char *fname,
+                     const char *name);
+int smbw_lremovexattr(const char *fname,
+                      const char *name);
+int smbw_fremovexattr(int smbw_fd,
+                      const char *name);
+int smbw_listxattr(const char *fname,
+                   char *list,
+                   size_t size);
+int smbw_llistxattr(const char *fname,
+                    char *list,
+                    size_t size);
+int smbw_flistxattr(int smbw_fd,
+                    char *list,
+                    size_t size);
+
+/* The following definitions come from  smbwrapper/smbw_stat.c  */
+
+int smbw_fstat(int fd, SMBW_stat *st);
+int smbw_stat(const char *fname, SMBW_stat *st);
+
+/* The following definitions come from smbwrapper/cache.c */
+int
+smbw_cache_functions(SMBCCTX * context);
+
+
+#endif /* _SMBW_H */
diff --git a/examples/libsmbclient/smbwrapper/smbw_dir.c b/examples/libsmbclient/smbwrapper/smbw_dir.c
new file mode 100644 (file)
index 0000000..f3ec03e
--- /dev/null
@@ -0,0 +1,355 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper directory functions
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "smbw.h"
+
+/***************************************************** 
+determine if a directory handle is a smb one
+*******************************************************/
+int smbw_dirp(DIR * dirp)
+{
+        return ((char *) dirp >= (char *) smbw_fd_map &&
+                (char *) dirp < (char *) &smbw_fd_map[__FD_SETSIZE] &&
+                *(int *) dirp != -1);
+}
+
+
+/***************************************************** 
+a wrapper for getdents()
+*******************************************************/
+int smbw_getdents(unsigned int fd_smbw,
+                  struct SMBW_dirent *dirent_external,
+                  int count)
+{
+        int remaining;
+        int fd_client = smbw_fd_map[fd_smbw];
+        struct smbc_dirent *dirent_internal;
+
+
+        for (remaining = count;
+             remaining > sizeof(struct SMBW_dirent);
+             dirent_external++) {
+
+                /*
+                 * We do these one at a time because there's otherwise no way
+                 * to limit how many smbc_getdents() will return for us, and
+                 * if it returns too many, it also doesn't give us offsets to
+                 * be able to seek back to where we need to be.  In practice,
+                 * this one-at-a-time retrieval isn't a problem because the
+                 * time-consuming network transaction is all done at
+                 * smbc_opendir() time.
+                 */
+                dirent_internal = smbc_readdir(fd_client);
+                if (dirent_internal == NULL) {
+                        break;
+                }
+
+                remaining -= sizeof(struct SMBW_dirent);
+
+                dirent_external->d_ino = -1; /* not supported */
+               dirent_external->d_off = smbc_telldir(fd_client);
+               dirent_external->d_reclen = sizeof(struct SMBW_dirent);
+                dirent_external->d_type = dirent_internal->smbc_type;
+
+                strncpy(dirent_external->d_name,
+                        dirent_internal->name,
+                        sizeof(dirent_external->d_name) - 1);
+                strncpy(dirent_external->d_comment,
+                        dirent_internal->comment,
+                        sizeof(dirent_external->d_comment) - 1);
+       }
+
+       return(count - remaining);
+}
+
+
+/***************************************************** 
+a wrapper for chdir()
+*******************************************************/
+int smbw_chdir(const char *name)
+{
+        int simulate;
+        struct stat statbuf;
+        char path[PATH_MAX];
+        char *p;
+
+       SMBW_INIT();
+
+       if (!name) {
+               errno = EINVAL;
+                return -1;
+       }
+
+       if (! smbw_path((char *) name)) {
+               if ((* smbw_libc.chdir)(name) == 0) {
+                        *smbw_cwd = '\0';
+                        return 0;
+               }
+
+                return -1;
+       }
+
+        smbw_fix_path(name, path);
+
+        /* ensure it exists */
+        p = path + 6;           /* look just past smb:// */
+        simulate = (strchr(p, '/') == NULL);
+
+        /* special case for full-network scan, workgroups, and servers */
+        if (! simulate) {
+            
+            if (smbc_stat(path, &statbuf) < 0) {
+                return -1;
+            }
+            
+            /* ensure it's a directory */
+            if (! S_ISDIR(statbuf.st_mode)) {
+                errno = ENOTDIR;
+                return -1;
+            }
+        }
+
+        strncpy(smbw_cwd, path, PATH_MAX);
+
+       /* we don't want the old directory to be busy */
+       (* smbw_libc.chdir)("/");
+
+       return 0;
+}
+
+
+/***************************************************** 
+a wrapper for mkdir()
+*******************************************************/
+int smbw_mkdir(const char *fname, mode_t mode)
+{
+        char path[PATH_MAX];
+
+       if (!fname) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       SMBW_INIT();
+
+        smbw_fix_path(fname, path);
+        return smbc_mkdir(path, mode);
+}
+
+/***************************************************** 
+a wrapper for rmdir()
+*******************************************************/
+int smbw_rmdir(const char *fname)
+{
+        char path[PATH_MAX];
+
+       if (!fname) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       SMBW_INIT();
+
+        smbw_fix_path(fname, path);
+        return smbc_rmdir(path);
+}
+
+
+/***************************************************** 
+a wrapper for getcwd()
+*******************************************************/
+char *smbw_getcwd(char *buf, size_t size)
+{
+       SMBW_INIT();
+
+        if (*smbw_cwd == '\0') {
+                return (* smbw_libc.getcwd)(buf, size);
+        }
+
+        if (buf == NULL) {
+                if (size == 0) {
+                        size = strlen(smbw_cwd) + 1;
+                }
+                buf = malloc(size);
+                if (buf == NULL) {
+                        errno = ENOMEM;
+                        return NULL;
+                }
+        }
+
+        strncpy(buf, smbw_cwd, size);
+        buf[size-1] = '\0';
+       return buf;
+}
+
+/***************************************************** 
+a wrapper for fchdir()
+*******************************************************/
+int smbw_fchdir(int fd_smbw)
+{
+        int ret;
+
+        SMBW_INIT();
+
+        if (! smbw_fd(fd_smbw)) {
+                ret = (* smbw_libc.fchdir)(fd_smbw);
+                (void) (* smbw_libc.getcwd)(smbw_cwd, PATH_MAX);
+                return ret;
+        }
+
+        errno = EACCES;
+        return -1;
+}
+
+/***************************************************** 
+open a directory on the server
+*******************************************************/
+DIR *smbw_opendir(const char *fname)
+{
+        int fd_client;
+        int fd_smbw;
+       char path[PATH_MAX];
+        DIR * dirp;
+
+       SMBW_INIT();
+
+       if (!fname) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       fd_smbw = (smbw_libc.open)(SMBW_DUMMY, O_WRONLY, 0200);
+       if (fd_smbw == -1) {
+               errno = EMFILE;
+                return NULL;
+       }
+
+        smbw_fix_path(fname, path);
+        fd_client =  smbc_opendir(path);
+
+        if (fd_client < 0) {
+                (* smbw_libc.close)(fd_smbw);
+                return NULL;
+        }
+
+        smbw_fd_map[fd_smbw] = fd_client;
+        smbw_ref(fd_client, SMBW_RCT_Increment);
+        dirp = (DIR *) &smbw_fd_map[fd_smbw];
+        return dirp;
+}
+
+/***************************************************** 
+read one entry from a directory
+*******************************************************/
+struct SMBW_dirent *smbw_readdir(DIR *dirp)
+{
+        int fd_smbw;
+        int fd_client;
+        struct smbc_dirent *dirent_internal;
+        static struct SMBW_dirent dirent_external;
+
+        fd_smbw = (int *) dirp - smbw_fd_map;
+        fd_client = smbw_fd_map[fd_smbw];
+
+       if ((dirent_internal = smbc_readdir(fd_client)) == NULL) {
+               return NULL;
+        }
+        dirent_external.d_ino = -1; /* not supported */
+        dirent_external.d_off = smbc_telldir(fd_client);
+        dirent_external.d_reclen = sizeof(struct SMBW_dirent);
+        dirent_external.d_type = dirent_internal->smbc_type;
+        strncpy(dirent_external.d_name,
+                dirent_internal->name,
+                sizeof(dirent_external.d_name) - 1);
+        strncpy(dirent_external.d_comment,
+                dirent_internal->comment,
+                sizeof(dirent_external.d_comment) - 1);
+
+       return &dirent_external;
+}
+
+/***************************************************** 
+read one entry from a directory in a reentrant fashion
+ha!  samba is not re-entrant, and neither is the
+libsmbclient library
+*******************************************************/
+int smbw_readdir_r(DIR *dirp,
+                   struct SMBW_dirent *__restrict entry,
+                   struct SMBW_dirent **__restrict result)
+{
+        SMBW_dirent *dirent;
+
+        dirent = smbw_readdir(dirp);
+
+        if (dirent != NULL) {
+                *entry = *dirent;
+                if (result != NULL) {
+                        *result = entry;
+                }
+                return 0;
+        }
+
+        if (result != NULL) {
+                *result = NULL;
+        }
+       return EBADF;
+}
+
+
+/***************************************************** 
+close a DIR*
+*******************************************************/
+int smbw_closedir(DIR *dirp)
+{
+        int fd_smbw = (int *) dirp - smbw_fd_map;
+        int fd_client = smbw_fd_map[fd_smbw];
+
+        (* smbw_libc.close)(fd_smbw);
+        if (smbw_ref(fd_client, SMBW_RCT_Decrement) > 0) {
+                return 0;
+        }
+        smbw_fd_map[fd_smbw] = -1;
+        return smbc_closedir(fd_client);
+}
+
+/***************************************************** 
+seek in a directory
+*******************************************************/
+void smbw_seekdir(DIR *dirp, long long offset)
+{
+        int fd_smbw = (int *) dirp - smbw_fd_map;
+        int fd_client = smbw_fd_map[fd_smbw];
+
+        smbc_lseekdir(fd_client, offset);
+}
+
+/***************************************************** 
+current loc in a directory
+*******************************************************/
+long long smbw_telldir(DIR *dirp)
+{
+        int fd_smbw = (int *) dirp - smbw_fd_map;
+        int fd_client = smbw_fd_map[fd_smbw];
+
+        return (long long) smbc_telldir(fd_client);
+}
diff --git a/examples/libsmbclient/smbwrapper/smbw_stat.c b/examples/libsmbclient/smbwrapper/smbw_stat.c
new file mode 100644 (file)
index 0000000..70b3064
--- /dev/null
@@ -0,0 +1,146 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper stat functions
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "smbw.h"
+
+static int timezone_diff = -1;
+
+#define TM_YEAR_BASE 1900
+
+/*******************************************************************
+yield the difference between *A and *B, in seconds, ignoring leap seconds
+********************************************************************/
+static int tm_diff(struct tm *a, struct tm *b)
+{
+  int ay = a->tm_year + (TM_YEAR_BASE - 1);
+  int by = b->tm_year + (TM_YEAR_BASE - 1);
+  int intervening_leap_days =
+    (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
+  int years = ay - by;
+  int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
+  int hours = 24*days + (a->tm_hour - b->tm_hour);
+  int minutes = 60*hours + (a->tm_min - b->tm_min);
+  int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
+
+  return seconds;
+}
+
+/*******************************************************************
+  return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
+  ******************************************************************/
+static int TimeZone(time_t t)
+{
+  struct tm *tm = gmtime(&t);
+  struct tm tm_utc;
+  if (!tm)
+    return 0;
+  tm_utc = *tm;
+  tm = localtime(&t);
+  if (!tm)
+    return 0;
+  return tm_diff(&tm_utc,tm);
+
+}
+
+
+static void copy_stat(struct SMBW_stat *external, struct stat *internal)
+{
+        if (timezone_diff < 0)
+        {
+            timezone_diff = TimeZone(time(NULL));
+        }
+
+        external->s_dev = internal->st_dev;
+        external->s_ino = internal->st_ino;
+        external->s_mode = internal->st_mode;
+        external->s_nlink = internal->st_nlink;
+        external->s_uid = internal->st_uid;
+        external->s_gid = internal->st_gid;
+        external->s_rdev = internal->st_rdev;
+        external->s_size = internal->st_size;
+        external->s_blksize = internal->st_blksize;
+        external->s_blocks = internal->st_blocks;
+        external->s_atime = internal->st_atime + timezone_diff;
+        external->s_mtime = internal->st_mtime + timezone_diff;
+        external->s_ctime = internal->st_ctime + timezone_diff;
+}
+
+
+/***************************************************** 
+a wrapper for fstat()
+*******************************************************/
+int smbw_fstat(int fd_smbw, struct SMBW_stat *st)
+{
+        int fd_client = smbw_fd_map[fd_smbw];
+        struct stat statbuf;
+
+        if (smbc_fstat(fd_client, &statbuf) < 0) {
+                return -1;
+        }
+        
+        copy_stat(st, &statbuf);
+
+       return 0;
+}
+
+
+/***************************************************** 
+a wrapper for stat()
+*******************************************************/
+int smbw_stat(const char *fname, struct SMBW_stat *st)
+{
+        int simulate;
+        char *p;
+        char path[PATH_MAX];
+        struct stat statbuf;
+
+        SMBW_INIT();
+
+        smbw_fix_path(fname, path);
+
+        p = path + 6;           /* look just past smb:// */
+        simulate = (strchr(p, '/') == NULL);
+
+        /* special case for full-network scan, workgroups, and servers */
+        if (simulate) {
+            statbuf.st_dev = 0;
+            statbuf.st_ino = 0;
+            statbuf.st_mode = 0040777;
+            statbuf.st_nlink = 1;
+            statbuf.st_uid = 0;
+            statbuf.st_gid = 0;
+            statbuf.st_rdev = 0;
+            statbuf.st_size = 0;
+            statbuf.st_blksize = 1024;
+            statbuf.st_blocks = 1;
+            statbuf.st_atime = 0; /* beginning of epoch */
+            statbuf.st_mtime = 0; /* beginning of epoch */
+            statbuf.st_ctime = 0; /* beginning of epoch */
+
+        } else if (smbc_stat(path, &statbuf) < 0) {
+                return -1;
+        }
+        
+        copy_stat(st, &statbuf);
+
+       return 0;
+}
diff --git a/examples/libsmbclient/smbwrapper/wrapper.c b/examples/libsmbclient/smbwrapper/wrapper.c
new file mode 100644 (file)
index 0000000..71d6f20
--- /dev/null
@@ -0,0 +1,1729 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper functions
+   Copyright (C) Andrew Tridgell 1998
+   Copyright (C) Derrell Lipman 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 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * This is a rewrite of the original wrapped.c file, using libdl to obtain
+ * pointers into the C library rather than attempting to find undocumented
+ * functions in the C library to call for native file access.  The problem
+ * with the original implementation's paradigm is that samba manipulates
+ * defines such that it gets the sizes of structures that it wants
+ * (e.g. mapping 32-bit functions to 64-bit functions with their associated
+ * 64-bit structure fields), but programs run under smbsh or using
+ * smbwrapper.so were not necessarily compiled with the same flags.  As an
+ * example of the problem, a program calling stat() passes a pointer to a
+ * "struct stat" but the fields in that structure are different in samba than
+ * they are in the calling program if the calling program was not compiled to
+ * force stat() to be mapped to stat64().
+ *
+ * In this version, we provide an interface to each of the native functions,
+ * not just the ones that samba is compiled to map to.  We obtain the function
+ * pointers from the C library using dlsym(), and for native file operations,
+ * directly call the same function that the calling application was
+ * requesting.  Since the size of the calling application's structures vary
+ * depending on what function was called, we use our own internal structures
+ * for passing information to/from the SMB equivalent functions, and map them
+ * back to the native structures before returning the result to the caller.
+ *
+ * This implementation was completed 25 December 2002.
+ * Derrell Lipman
+ */
+
+/* We do not want auto munging of 32->64 bit names in this file (only) */
+#undef _FILE_OFFSET_BITS
+#undef _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <utime.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include "libsmbclient.h"
+#include "wrapper.h"
+
+/*
+ * Debug bits:
+ * 0x0 = none
+ * 0x1 = display symbol definitions not found in C library
+ * 0x2 = show wrapper functions being called
+ * 0x4 = log to file SMBW_DEBUG_FILE instead of stderr
+ */
+#define SMBW_DEBUG      0x0
+#define SMBW_DEBUG_FILE "/tmp/smbw.log"
+
+int      smbw_debug = 0;
+
+#if SMBW_DEBUG & 0x2
+static int      debugFd = 2;
+#endif
+
+#ifndef ENOTSUP
+#define ENOTSUP EOPNOTSUPP
+#endif
+
+/*
+ * None of the methods of having the initialization function called
+ * automatically upon shared library startup are effective in all situations.
+ * We provide the "-init" parameter to the linker which is effective most of
+ * the time, but fails for applications that provide their own shared
+ * libraries with _init() functions (e.g. ps).  We can't use "-z initfirst"
+ * because the environment isn't yet set up at that point, so we can't find
+ * our shared memory identifier (see shared.c).  We therefore must resort to
+ * this tried-and-true method of keeping an "initialized" flag.  We check it
+ * prior to calling the initialize() function to save a function call (a slow
+ * operation on x86).
+ */
+#if SMBW_DEBUG & 0x2
+#  define check_init(buf)                                               \
+        do {                                                            \
+                int saved_errno = errno;                                \
+                if (! initialized) initialize();                        \
+                (* smbw_libc.write)(debugFd, "["buf"]", sizeof(buf)+1); \
+                errno = saved_errno;                                    \
+        } while (0);
+#else
+#  define check_init(buf)                               \
+        do {                                            \
+                if (! initialized) smbw_initialize();   \
+        } while (0);
+#endif
+
+static void initialize(void);
+
+static int initialized = 0;
+
+SMBW_libc_pointers smbw_libc;
+
+/*
+ * A public entry point used by the "-init" option to the linker.
+ */
+void smbw_initialize(void)
+{
+        initialize();
+}
+
+static void initialize(void)
+{
+        void *lib = NULL;
+        int saved_errno;
+#if SMBW_DEBUG & 0x1
+        char *error;
+#endif
+
+        saved_errno = errno;
+        
+        if (initialized) {
+                errno = saved_errno;
+                return;
+        }
+        initialized = 1;
+        
+        if ((lib = dlopen("/lib/libc.so.6", RTLD_NOW | RTLD_GLOBAL)) == NULL) {
+                exit(1);
+        }
+        
+#if SMBW_DEBUG & 0x1
+# define GETSYM(symname, symstring)                                     \
+        if ((smbw_libc.symname = dlsym(lib, symstring)) == NULL) {      \
+                if (smbw_libc.write != NULL &&                          \
+                    (error = dlerror()) != NULL) {                      \
+                        (* smbw_libc.write)(1, error, strlen(error));   \
+                        (* smbw_libc.write)(1, "\n", 1);                \
+                }                                                       \
+        }
+#else
+# define GETSYM(symname, symstring)                     \
+        smbw_libc.symname = dlsym(lib, symstring);
+#endif
+        
+        /*
+         * Get pointers to each of the symbols we'll need, from the C library
+         *
+         * Some of these symbols may not be found in the C library.  That's
+         * fine.  We declare all of them here, and if the C library supports
+         * them, they may be called so we have the wrappers for them.  If the
+         * C library doesn't support them, then the wrapper function will
+         * never be called, and the null pointer will never be dereferenced.
+         */
+        do {
+                GETSYM(write, "write"); /* first, to allow debugging */
+                GETSYM(open, "open");
+                GETSYM(_open, "_open");
+                GETSYM(__open, "__open");
+                GETSYM(open64, "open64");
+                GETSYM(_open64, "_open64");
+                GETSYM(__open64, "__open64");
+                GETSYM(pread, "pread");
+                GETSYM(pread64, "pread64");
+                GETSYM(pwrite, "pwrite");
+                GETSYM(pwrite64, "pwrite64");
+                GETSYM(close, "close");
+                GETSYM(__close, "__close");
+                GETSYM(_close, "_close");
+                GETSYM(fcntl, "fcntl");
+                GETSYM(__fcntl, "__fcntl");
+                GETSYM(_fcntl, "_fcntl");
+                GETSYM(getdents, "getdents");
+                GETSYM(__getdents, "__getdents");
+                GETSYM(_getdents, "_getdents");
+                GETSYM(getdents64, "getdents64");
+                GETSYM(lseek, "lseek");
+                GETSYM(__lseek, "__lseek");
+                GETSYM(_lseek, "_lseek");
+                GETSYM(lseek64, "lseek64");
+                GETSYM(__lseek64, "__lseek64");
+                GETSYM(_lseek64, "_lseek64");
+                GETSYM(read, "read");
+                GETSYM(__read, "__read");
+                GETSYM(_read, "_read");
+                GETSYM(__write, "__write");
+                GETSYM(_write, "_write");
+                GETSYM(access, "access");
+                GETSYM(chmod, "chmod");
+                GETSYM(fchmod, "fchmod");
+                GETSYM(chown, "chown");
+                GETSYM(fchown, "fchown");
+                GETSYM(__xstat, "__xstat");
+                GETSYM(getcwd, "getcwd");
+                GETSYM(mkdir, "mkdir");
+                GETSYM(__fxstat, "__fxstat");
+                GETSYM(__lxstat, "__lxstat");
+                GETSYM(stat, "stat");
+                GETSYM(lstat, "lstat");
+                GETSYM(fstat, "fstat");
+                GETSYM(unlink, "unlink");
+                GETSYM(utime, "utime");
+                GETSYM(utimes, "utimes");
+                GETSYM(readlink, "readlink");
+                GETSYM(rename, "rename");
+                GETSYM(rmdir, "rmdir");
+                GETSYM(symlink, "symlink");
+                GETSYM(dup, "dup");
+                GETSYM(dup2, "dup2");
+                GETSYM(opendir, "opendir");
+                GETSYM(readdir, "readdir");
+                GETSYM(closedir, "closedir");
+                GETSYM(telldir, "telldir");
+                GETSYM(seekdir, "seekdir");
+                GETSYM(creat, "creat");
+                GETSYM(creat64, "creat64");
+                GETSYM(__xstat64, "__xstat64");
+                GETSYM(stat64, "stat64");
+                GETSYM(__fxstat64, "__fxstat64");
+                GETSYM(fstat64, "fstat64");
+                GETSYM(__lxstat64, "__lxstat64");
+                GETSYM(lstat64, "lstat64");
+                GETSYM(_llseek, "_llseek");
+                GETSYM(readdir64, "readdir64");
+                GETSYM(readdir_r, "readdir_r");
+                GETSYM(readdir64_r, "readdir64_r");
+                GETSYM(setxattr, "setxattr");
+                GETSYM(lsetxattr, "lsetxattr");
+                GETSYM(fsetxattr, "fsetxattr");
+                GETSYM(getxattr, "getxattr");
+                GETSYM(lgetxattr, "lgetxattr");
+                GETSYM(fgetxattr, "fgetxattr");
+                GETSYM(removexattr, "removexattr");
+                GETSYM(lremovexattr, "lremovexattr");
+                GETSYM(fremovexattr, "fremovexattr");
+                GETSYM(listxattr, "listxattr");
+                GETSYM(llistxattr, "llistxattr");
+                GETSYM(flistxattr, "flistxattr");
+                GETSYM(chdir, "chdir");
+                GETSYM(fchdir, "fchdir");
+                GETSYM(fork, "fork");
+                GETSYM(select, "select");
+                GETSYM(_select, "_select");
+                GETSYM(__select, "__select");
+        } while (0);
+        
+        dlclose(lib);
+
+        if ((lib = dlopen("/lib/libc.so.6", RTLD_NOW | RTLD_GLOBAL)) == NULL) {
+                exit(1);
+        }
+        
+#if SMBW_DEBUG & 4
+        {
+            if ((debugFd =
+                 open(SMBW_DEBUG_FILE, O_WRONLY | O_CREAT | O_APPEND)) < 0)
+            {
+#               define SMBW_MESSAGE    "Could not create " SMBW_DEBUG_FILE "\n" 
+                (* smbw_libc.write)(1, SMBW_MESSAGE, sizeof(SMBW_MESSAGE));
+#               undef SMBW_MESSAGE
+                exit(1);
+            }
+        }
+#endif
+
+        errno = saved_errno;
+}
+
+/**
+ ** Static Functions
+ **/
+
+static void stat_convert(struct SMBW_stat *src, struct stat *dest)
+{
+        memset(dest, '\0', sizeof(*dest));
+       dest->st_size = src->s_size;
+       dest->st_mode = src->s_mode;
+       dest->st_ino = src->s_ino;
+       dest->st_dev = src->s_dev;
+       dest->st_rdev = src->s_rdev;
+       dest->st_nlink = src->s_nlink;
+       dest->st_uid = src->s_uid;
+       dest->st_gid = src->s_gid;
+       dest->st_atime = src->s_atime;
+       dest->st_mtime = src->s_mtime;
+       dest->st_ctime = src->s_ctime;
+       dest->st_blksize = src->s_blksize;
+       dest->st_blocks = src->s_blocks;
+}
+
+static void stat64_convert(struct SMBW_stat *src, struct stat64 *dest)
+{
+        memset(dest, '\0', sizeof(*dest));
+       dest->st_size = src->s_size;
+       dest->st_mode = src->s_mode;
+       dest->st_ino = src->s_ino;
+       dest->st_dev = src->s_dev;
+       dest->st_rdev = src->s_rdev;
+       dest->st_nlink = src->s_nlink;
+       dest->st_uid = src->s_uid;
+       dest->st_gid = src->s_gid;
+       dest->st_atime = src->s_atime;
+       dest->st_mtime = src->s_mtime;
+       dest->st_ctime = src->s_ctime;
+       dest->st_blksize = src->s_blksize;
+       dest->st_blocks = src->s_blocks;
+}
+
+static void dirent_convert(struct SMBW_dirent *src, struct dirent *dest)
+{
+        char *p;
+
+        memset(dest, '\0', sizeof(*dest));
+       dest->d_ino = src->d_ino;
+       dest->d_off = src->d_off;
+
+        switch(src->d_type)
+        {
+        case SMBC_WORKGROUP:
+        case SMBC_SERVER:
+        case SMBC_FILE_SHARE:
+        case SMBC_DIR:
+                dest->d_type = DT_DIR;
+                break;
+                
+        case SMBC_FILE:
+                dest->d_type = DT_REG;
+                break;
+                
+        case SMBC_PRINTER_SHARE:
+                dest->d_type = DT_CHR;
+                break;
+                
+        case SMBC_COMMS_SHARE:
+                dest->d_type = DT_SOCK;
+                break;
+                
+        case SMBC_IPC_SHARE:
+                dest->d_type = DT_FIFO;
+                break;
+                
+        case SMBC_LINK:
+                dest->d_type = DT_LNK;
+                break;
+        }
+
+       dest->d_reclen = src->d_reclen;
+       strncpy(dest->d_name, src->d_name, sizeof(dest->d_name));
+        p = dest->d_name + strlen(dest->d_name) + 1;
+        strncpy(p, src->d_comment, sizeof(dest->d_name) - (p - dest->d_name));
+}
+
+static void dirent64_convert(struct SMBW_dirent *src, struct dirent64 *dest)
+{
+        char *p;
+
+        memset(dest, '\0', sizeof(*dest));
+       dest->d_ino = src->d_ino;
+       dest->d_off = src->d_off;
+
+        switch(src->d_type)
+        {
+        case SMBC_WORKGROUP:
+        case SMBC_SERVER:
+        case SMBC_FILE_SHARE:
+        case SMBC_DIR:
+                dest->d_type = DT_DIR;
+                break;
+                
+        case SMBC_FILE:
+                dest->d_type = DT_REG;
+                break;
+                
+        case SMBC_PRINTER_SHARE:
+                dest->d_type = DT_CHR;
+                break;
+                
+        case SMBC_COMMS_SHARE:
+                dest->d_type = DT_SOCK;
+                break;
+                
+        case SMBC_IPC_SHARE:
+                dest->d_type = DT_FIFO;
+                break;
+                
+        case SMBC_LINK:
+                dest->d_type = DT_LNK;
+                break;
+        }
+
+       dest->d_reclen = src->d_reclen;
+       strncpy(dest->d_name, src->d_name, sizeof(dest->d_name));
+        p = dest->d_name + strlen(dest->d_name) + 1;
+        strncpy(p, src->d_comment, sizeof(dest->d_name) - (p - dest->d_name));
+}
+
+static int openx(char *name, int flags, mode_t mode, int (* f)(char *, int, mode_t))
+{
+       if (smbw_path(name)) {
+               return smbw_open(name, flags, mode);
+       }
+
+        return (* f)(name, flags, mode);
+}
+
+static int closex(int fd, int (* f)(int fd))
+{
+       if (smbw_fd(fd)) {
+               return smbw_close(fd);
+       }
+
+        return (* f)(fd);
+}
+
+static int fcntlx(int fd, int cmd, long arg, int (* f)(int, int, long))
+{
+       if (smbw_fd(fd)) {
+               return smbw_fcntl(fd, cmd, arg);
+       }
+
+        return (* f)(fd, cmd, arg);
+}
+
+static int getdentsx(int fd, struct dirent *external, unsigned int count, int (* f)(int, struct dirent *, unsigned int))
+{
+       if (smbw_fd(fd)) {
+                int i;
+                int internal_count;
+                struct SMBW_dirent *internal;
+                int ret;
+                int n;
+
+                /*
+                 * LIMITATION: If they pass a count which is not a multiple of
+                 * the size of struct dirent, they will not get a partial
+                 * structure; we ignore the excess count.
+                 */
+                n = (count / sizeof(struct dirent));
+
+                internal_count = sizeof(struct SMBW_dirent) * n;
+                internal = malloc(internal_count);
+                if (internal == NULL) {
+                        errno = ENOMEM;
+                        return -1;
+                }
+               ret = smbw_getdents(fd, internal, internal_count);
+                if (ret <= 0)
+                        return ret;
+
+                ret = sizeof(struct dirent) * n;
+                
+                for (i = 0; i < n; i++)
+                        dirent_convert(&internal[i], &external[i]);
+
+                return ret;
+       }
+
+        return (* f)(fd, external, count);
+}
+
+static off_t lseekx(int fd,
+                    off_t offset,
+                    int whence,
+                    off_t (* f)(int, off_t, int))
+{
+        off_t           ret;
+
+        /*
+         * We have left the definitions of the smbw_ functions undefined,
+         * because types such as off_t can differ in meaning betweent his
+         * function and smbw.c et al.  Functions that return other than an
+         * integer value, however, MUST have their return value defined.
+         */
+        off64_t         smbw_lseek();
+
+        if (smbw_fd(fd)) {
+               return (off_t) smbw_lseek(fd, offset, whence);
+       }
+
+        ret = (* f)(fd, offset, whence);
+        if (smbw_debug)
+        {
+                printf("lseekx(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+static off64_t lseek64x(int fd,
+                        off64_t offset,
+                        int whence,
+                        off64_t (* f)(int, off64_t, int))
+{
+        off64_t         ret;
+
+        /*
+         * We have left the definitions of the smbw_ functions undefined,
+         * because types such as off_t can differ in meaning betweent his
+         * function and smbw.c et al.  Functions that return other than an
+         * integer value, however, MUST have their return value defined.
+         */
+        off64_t         smbw_lseek();
+
+       if (smbw_fd(fd))
+               ret = smbw_lseek(fd, offset, whence);
+        else
+                ret = (* f)(fd, offset, whence);
+        if (smbw_debug)
+        {
+                printf("lseek64x(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+static ssize_t readx(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t))
+{
+       if (smbw_fd(fd)) {
+               return smbw_read(fd, buf, count);
+       }
+
+        return (* f)(fd, buf, count);
+}
+
+static ssize_t writex(int fd, void *buf, size_t count, ssize_t (* f)(int, void *, size_t))
+{
+       if (smbw_fd(fd)) {
+               return smbw_write(fd, buf, count);
+       }
+
+        return (* f)(fd, buf, count);
+}
+
+
+/**
+ ** Wrapper Functions
+ **/
+
+int open(__const char *name, int flags, ...)
+{
+        va_list ap;
+        mode_t mode;
+
+        va_start(ap, flags);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+
+        check_init("open");
+
+        return openx((char *) name, flags, mode, smbw_libc.open);
+}
+
+int _open(char *name, int flags, mode_t mode)
+{
+        check_init("open");
+
+        return openx(name, flags, mode, smbw_libc._open);
+}
+
+int __open(char *name, int flags, mode_t mode)
+{
+        check_init("open");
+
+        return openx(name, flags, mode, smbw_libc.__open);
+}
+
+int open64 (__const char *name, int flags, ...)
+{
+        va_list ap;
+        mode_t mode;
+
+        va_start(ap, flags);
+        mode = va_arg(ap, mode_t);
+        va_end(ap);
+
+        check_init("open64");
+        return openx((char *) name, flags, mode, smbw_libc.open64);
+}
+
+int _open64(char *name, int flags, mode_t mode)
+{
+        check_init("_open64");
+        return openx(name, flags, mode, smbw_libc._open64);
+}
+
+int __open64(char *name, int flags, mode_t mode)
+{
+        check_init("__open64");
+        return openx(name, flags, mode, smbw_libc.__open64);
+}
+
+ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
+{
+        check_init("pread");
+
+       if (smbw_fd(fd)) {
+               return smbw_pread(fd, buf, size, ofs);
+       }
+
+        return (* smbw_libc.pread)(fd, buf, size, ofs);
+}
+
+ssize_t pread64(int fd, void *buf, size_t size, off64_t ofs)
+{
+        check_init("pread64");
+
+       if (smbw_fd(fd)) {
+               return smbw_pread(fd, buf, size, (off_t) ofs);
+       }
+
+        return (* smbw_libc.pread64)(fd, buf, size, ofs);
+}
+
+ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
+{
+        check_init("pwrite");
+
+       if (smbw_fd(fd)) {
+               return smbw_pwrite(fd, (void *) buf, size, ofs);
+       }
+
+        return (* smbw_libc.pwrite)(fd, (void *) buf, size, ofs);
+}
+
+ssize_t pwrite64(int fd,  const void *buf, size_t size, off64_t ofs)
+{
+        check_init("pwrite64");
+
+       if (smbw_fd(fd)) {
+               return smbw_pwrite(fd, (void *) buf, size, (off_t) ofs);
+       }
+
+        return (* smbw_libc.pwrite64)(fd, (void *) buf, size, ofs);
+}
+
+int chdir(const char *name)
+{
+        check_init("chdir");
+        return smbw_chdir((char *) name);;
+}
+
+int __chdir(char *name)
+{
+        check_init("__chdir");
+        return smbw_chdir(name);
+}
+
+int _chdir(char *name)
+{
+        check_init("_chdir");
+        return smbw_chdir(name);
+}
+
+int close(int fd)
+{
+        check_init("close");
+        return closex(fd, smbw_libc.close);
+}
+
+int __close(int fd)
+{
+        check_init("__close");
+        return closex(fd, smbw_libc.__close);
+}
+
+int _close(int fd)
+{
+        check_init("_close");
+        return closex(fd, smbw_libc._close);
+}
+
+int fchdir(int fd)
+{
+        check_init("fchdir");
+       return smbw_fchdir(fd);
+}
+
+int __fchdir(int fd)
+{
+        check_init("__fchdir");
+       return fchdir(fd);
+}
+
+int _fchdir(int fd)
+{
+        check_init("_fchdir");
+       return fchdir(fd);
+}
+
+int fcntl (int fd, int cmd, ...)
+{
+        va_list ap;
+        long arg;
+
+        va_start(ap, cmd);
+        arg = va_arg(ap, long);
+        va_end(ap);
+
+        check_init("fcntl");
+        return fcntlx(fd, cmd, arg, smbw_libc.fcntl);
+}
+
+int __fcntl(int fd, int cmd, ...)
+{
+        va_list ap;
+        long arg;
+
+        va_start(ap, cmd);
+        arg = va_arg(ap, long);
+        va_end(ap);
+
+        check_init("__fcntl");
+        return fcntlx(fd, cmd, arg, smbw_libc.__fcntl);
+}
+
+int _fcntl(int fd, int cmd, ...)
+{
+        va_list ap;
+        long arg;
+
+        va_start(ap, cmd);
+        arg = va_arg(ap, long);
+        va_end(ap);
+
+        check_init("_fcntl");
+        return fcntlx(fd, cmd, arg, smbw_libc._fcntl);
+}
+
+int getdents(int fd, struct dirent *dirp, unsigned int count)
+{
+        check_init("getdents");
+        return getdentsx(fd, dirp, count, smbw_libc.getdents);
+}
+
+int __getdents(int fd, struct dirent *dirp, unsigned int count)
+{
+        check_init("__getdents");
+        return getdentsx(fd, dirp, count, smbw_libc.__getdents);
+}
+
+int _getdents(int fd, struct dirent *dirp, unsigned int count)
+{
+        check_init("_getdents");
+        return getdentsx(fd, dirp, count, smbw_libc._getdents);
+}
+
+int getdents64(int fd, struct dirent64 *external, unsigned int count)
+{
+        check_init("getdents64");
+       if (smbw_fd(fd)) {
+                int i;
+                struct SMBW_dirent *internal;
+                int ret;
+                int n;
+
+                /*
+                 * LIMITATION: If they pass a count which is not a multiple of
+                 * the size of struct dirent, they will not get a partial
+                 * structure; we ignore the excess count.
+                 */
+                n = (count / sizeof(struct dirent64));
+
+                internal = malloc(sizeof(struct SMBW_dirent) * n);
+                if (internal == NULL) {
+                        errno = ENOMEM;
+                        return -1;
+                }
+               ret = smbw_getdents(fd, internal, count);
+                if (ret <= 0)
+                        return ret;
+
+                ret = sizeof(struct dirent) * count;
+                
+                for (i = 0; count; i++, count--)
+                        dirent64_convert(&internal[i], &external[i]);
+
+                return ret;
+       }
+
+        return (* smbw_libc.getdents64)(fd, external, count);
+}
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+        off_t           ret;
+        check_init("lseek");
+        ret = lseekx(fd, offset, whence, smbw_libc.lseek);
+        if (smbw_debug)
+        {
+                printf("lseek(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+off_t __lseek(int fd, off_t offset, int whence)
+{
+        off_t           ret;
+        check_init("__lseek");
+        ret = lseekx(fd, offset, whence, smbw_libc.__lseek);
+        if (smbw_debug)
+        {
+                printf("__lseek(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+off_t _lseek(int fd, off_t offset, int whence)
+{
+        off_t           ret;
+        check_init("_lseek");
+        ret = lseekx(fd, offset, whence, smbw_libc._lseek);
+        if (smbw_debug)
+        {
+                printf("_lseek(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+off64_t lseek64(int fd, off64_t offset, int whence)
+{
+        off64_t         ret;
+        check_init("lseek64");
+        ret = lseek64x(fd, offset, whence, smbw_libc.lseek64);
+        if (smbw_debug)
+        {
+                printf("lseek64(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+off64_t __lseek64(int fd, off64_t offset, int whence)
+{
+        check_init("__lseek64");
+        return lseek64x(fd, offset, whence, smbw_libc.__lseek64);
+}
+
+off64_t _lseek64(int fd, off64_t offset, int whence)
+{
+        off64_t         ret;
+        check_init("_lseek64");
+        ret = lseek64x(fd, offset, whence, smbw_libc._lseek64);
+        if (smbw_debug)
+        {
+                printf("_lseek64(%d, 0x%llx) returned 0x%llx\n",
+                       fd,
+                       (unsigned long long) offset,
+                       (unsigned long long) ret);
+        }
+        return ret;
+}
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+        check_init("read");
+        return readx(fd, buf, count, smbw_libc.read);
+}
+
+ssize_t __read(int fd, void *buf, size_t count)
+{
+        check_init("__read");
+        return readx(fd, buf, count, smbw_libc.__read);
+}
+
+ssize_t _read(int fd, void *buf, size_t count)
+{
+        check_init("_read");
+        return readx(fd, buf, count, smbw_libc._read);
+}
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+        check_init("write");
+        return writex(fd, (void *) buf, count, smbw_libc.write);
+}
+
+ssize_t __write(int fd, const void *buf, size_t count)
+{
+        check_init("__write");
+        return writex(fd, (void *) buf, count, smbw_libc.__write);
+}
+
+ssize_t _write(int fd, const void *buf, size_t count)
+{
+        check_init("_write");
+        return writex(fd, (void *) buf, count, smbw_libc._write);
+}
+
+int access(const char *name, int mode)
+{
+        check_init("access");
+
+       if (smbw_path((char *) name)) {
+               return smbw_access((char *) name, mode);
+       }
+
+        return (* smbw_libc.access)((char *) name, mode);
+}
+
+int chmod(const char *name, mode_t mode)
+{
+        check_init("chmod");
+
+       if (smbw_path((char *) name)) {
+               return smbw_chmod((char *) name, mode);
+       }
+
+        return (* smbw_libc.chmod)((char *) name, mode);
+}
+
+int fchmod(int fd, mode_t mode)
+{
+        check_init("fchmod");
+
+       if (smbw_fd(fd)) {
+                /* Not yet implemented in libsmbclient */
+                return ENOTSUP;
+       }
+
+        return (* smbw_libc.fchmod)(fd, mode);
+}
+
+int chown(const char *name, uid_t owner, gid_t group)
+{
+        check_init("chown");
+
+       if (smbw_path((char *) name)) {
+               return smbw_chown((char *) name, owner, group);
+       }
+
+        return (* smbw_libc.chown)((char *) name, owner, group);
+}
+
+int fchown(int fd, uid_t owner, gid_t group)
+{
+        check_init("fchown");
+
+       if (smbw_fd(fd)) {
+                /* Not yet implemented in libsmbclient */
+                return ENOTSUP;
+       }
+
+        return (* smbw_libc.fchown)(fd, owner, group);
+}
+
+char *getcwd(char *buf, size_t size)
+{
+        check_init("getcwd");
+       return (char *)smbw_getcwd(buf, size);
+}
+
+int mkdir(const char *name, mode_t mode)
+{
+        check_init("mkdir");
+
+       if (smbw_path((char *) name)) {
+               return smbw_mkdir((char *) name, mode);
+       }
+
+        return (* smbw_libc.mkdir)((char *) name, mode);
+}
+
+int __fxstat(int vers, int fd, struct stat *st)
+{
+        check_init("__fxstat");
+
+       if (smbw_fd(fd)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_fstat(fd, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.__fxstat)(vers, fd, st);
+}
+
+int __xstat(int vers, const char *name, struct stat *st)
+{
+        check_init("__xstat");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.__xstat)(vers, (char *) name, st);
+}
+
+int __lxstat(int vers, const char *name, struct stat *st)
+{
+        check_init("__lxstat");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.__lxstat)(vers, (char *) name, st);
+}
+
+int stat(const char *name, struct stat *st)
+{
+        check_init("stat");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.stat)((char *) name, st);
+}
+
+int lstat(const char *name, struct stat *st)
+{
+        check_init("lstat");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+                int ret = smbw_stat((char *) name, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.lstat)((char *) name, st);
+}
+
+int fstat(int fd, struct stat *st)
+{
+        check_init("fstat");
+
+       if (smbw_fd(fd)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_fstat(fd, &statbuf);
+                stat_convert(&statbuf, st);
+                return ret;
+       }
+
+        return (* smbw_libc.fstat)(fd, st);
+}
+
+int unlink(const char *name)
+{
+        check_init("unlink");
+
+       if (smbw_path((char *) name)) {
+               return smbw_unlink((char *) name);
+       }
+
+        return (* smbw_libc.unlink)((char *) name);
+}
+
+int utime(const char *name, const struct utimbuf *tvp)
+{
+        check_init("utime");
+
+       if (smbw_path(name)) {
+               return smbw_utime(name, (struct utimbuf *) tvp);
+       }
+
+        return (* smbw_libc.utime)((char *) name, (struct utimbuf *) tvp);
+}
+
+int utimes(const char *name, const struct timeval *tvp)
+{
+        check_init("utimes");
+
+       if (smbw_path(name)) {
+               return smbw_utimes(name, (struct timeval *) tvp);
+       }
+
+        return (* smbw_libc.utimes)((char *) name, (struct timeval *) tvp);
+}
+
+int readlink(const char *path, char *buf, size_t bufsize)
+{
+        check_init("readlink");
+
+       if (smbw_path((char *) path)) {
+               return smbw_readlink(path, (char *) buf, bufsize);
+       }
+
+        return (* smbw_libc.readlink)((char *) path, buf, bufsize);
+}
+
+int rename(const char *oldname, const char *newname)
+{
+       int p1, p2;
+
+        check_init("rename");
+
+       p1 = smbw_path((char *) oldname); 
+       p2 = smbw_path((char *) newname); 
+       if (p1 ^ p2) {
+               /* can't cross filesystem boundaries */
+               errno = EXDEV;
+               return -1;
+       }
+       if (p1 && p2) {
+               return smbw_rename((char *) oldname, (char *) newname);
+       }
+
+        return (* smbw_libc.rename)((char *) oldname, (char *) newname);
+}
+
+int rmdir(const char *name)
+{
+        check_init("rmdir");
+
+       if (smbw_path((char *) name)) {
+               return smbw_rmdir((char *) name);
+       }
+
+        return (* smbw_libc.rmdir)((char *) name);
+}
+
+int symlink(const char *topath, const char *frompath)
+{
+       int p1, p2;
+
+        check_init("symlink");
+
+       p1 = smbw_path((char *) topath); 
+       p2 = smbw_path((char *) frompath); 
+       if (p1 || p2) {
+               /* can't handle symlinks */
+               errno = EPERM;
+               return -1;
+       }
+
+        return (* smbw_libc.symlink)((char *) topath, (char *) frompath);
+}
+
+int dup(int fd)
+{
+        check_init("dup");
+
+       if (smbw_fd(fd)) {
+               return smbw_dup(fd);
+       }
+
+        return (* smbw_libc.dup)(fd);
+}
+
+int dup2(int oldfd, int newfd)
+{
+        check_init("dup2");
+
+       if (smbw_fd(newfd)) {
+               (* smbw_libc.close)(newfd);
+       }
+        
+       if (smbw_fd(oldfd)) {
+               return smbw_dup2(oldfd, newfd);
+       }
+
+        return (* smbw_libc.dup2)(oldfd, newfd);
+}
+
+
+DIR *opendir(const char *name)
+{
+        check_init("opendir");
+
+       if (smbw_path((char *) name)) {
+               return (void *)smbw_opendir((char *) name);
+       }
+
+        return (* smbw_libc.opendir)((char *) name);
+}
+
+struct dirent *readdir(DIR *dir)
+{
+        check_init("readdir");
+
+       if (smbw_dirp(dir)) {
+                static struct dirent external;
+                struct SMBW_dirent * internal = (void *)smbw_readdir(dir);
+                if (internal != NULL) {
+                        dirent_convert(internal, &external);
+                        return &external;
+                }
+                return NULL;
+       }
+        return (* smbw_libc.readdir)(dir);
+}
+
+int closedir(DIR *dir)
+{
+        check_init("closedir");
+
+       if (smbw_dirp(dir)) {
+               return smbw_closedir(dir);
+       }
+
+        return (* smbw_libc.closedir)(dir);
+}
+
+long telldir(DIR *dir)
+{
+        check_init("telldir");
+
+       if (smbw_dirp(dir)) {
+               return (long) smbw_telldir(dir);
+       }
+
+        return (* smbw_libc.telldir)(dir);
+}
+
+void seekdir(DIR *dir, long offset)
+{
+        check_init("seekdir");
+
+       if (smbw_dirp(dir)) {
+               smbw_seekdir(dir, (long long) offset);
+               return;
+       }
+
+        (* smbw_libc.seekdir)(dir, offset);
+}
+
+int creat(const char *path, mode_t mode)
+{
+       extern int creat_bits;
+
+        check_init("creat");
+       return openx((char *) path, creat_bits, mode, smbw_libc.open);
+}
+
+int creat64(const char *path, mode_t mode)
+{
+       extern int creat_bits;
+
+        check_init("creat64");
+       return openx((char *) path, creat_bits, mode, smbw_libc.open64);
+}
+
+int __xstat64 (int ver, const char *name, struct stat64 *st64)
+{
+        check_init("__xstat64");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.__xstat64)(ver, (char *) name, st64);
+}
+
+int stat64(const char *name, struct stat64 *st64)
+{
+        check_init("stat64");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.stat64)((char *) name, st64);
+}
+
+int __fxstat64(int ver, int fd, struct stat64 *st64)
+{
+        check_init("__fxstat64");
+
+       if (smbw_fd(fd)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_fstat(fd, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.__fxstat64)(ver, fd, st64);
+}
+
+int fstat64(int fd, struct stat64 *st64)
+{
+        check_init("fstat64");
+
+       if (smbw_fd(fd)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_fstat(fd, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.fstat64)(fd, st64);
+}
+
+int __lxstat64(int ver, const char *name, struct stat64 *st64)
+{
+        check_init("__lxstat64");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat(name, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.__lxstat64)(ver, (char *) name, st64);
+}
+
+int lstat64(const char *name, struct stat64 *st64)
+{
+        check_init("lstat64");
+
+       if (smbw_path((char *) name)) {
+                struct SMBW_stat statbuf;
+               int ret = smbw_stat((char *) name, &statbuf);
+               stat64_convert(&statbuf, st64);
+               return ret;
+       }
+
+        return (* smbw_libc.lstat64)((char *) name, st64);
+}
+
+int _llseek(unsigned int fd,  unsigned  long  offset_high, unsigned  long  offset_low,  loff_t  *result, unsigned int whence)
+{
+        check_init("_llseek");
+
+       if (smbw_fd(fd)) {
+               *result = lseek(fd, offset_low, whence);
+                return (*result < 0 ? -1 : 0);
+       }
+
+        return (* smbw_libc._llseek)(fd, offset_high, offset_low, result, whence);
+}
+
+struct dirent64 *readdir64(DIR *dir)
+{
+        check_init("readdir64");
+
+       if (smbw_dirp(dir)) {
+                static struct dirent64 external;
+                struct SMBW_dirent * internal = (void *)smbw_readdir(dir);
+                if (internal != NULL) {
+                        dirent64_convert(internal, &external);
+                        return &external;
+                }
+                return NULL;
+       }
+
+        return (* smbw_libc.readdir64)(dir);
+}
+
+int readdir_r(DIR *dir, struct dirent *external, struct dirent **result)
+{
+        check_init("readdir_r");
+
+       if (smbw_dirp(dir)) {
+                struct SMBW_dirent internal;
+                int ret = smbw_readdir_r(dir, &internal, NULL);
+                if (ret == 0) {
+                        dirent_convert(&internal, external);
+                        *result = external;
+                }
+               return ret;
+       }
+
+        return (* smbw_libc.readdir_r)(dir, external, result);
+}
+
+int readdir64_r(DIR *dir, struct dirent64 *external, struct dirent64 **result)
+{
+        check_init("readdir64_r");
+
+       if (smbw_dirp(dir)) {
+                struct SMBW_dirent internal;
+                int ret = smbw_readdir_r(dir, &internal, NULL);
+                if (ret == 0) {
+                        dirent64_convert(&internal, external);
+                        *result = external;
+                }
+               return ret;
+       }
+
+        return (* smbw_libc.readdir64_r)(dir, external, result);
+}
+
+int fork(void)
+{
+        check_init("fork");
+       return smbw_fork();
+}
+
+int setxattr(const char *fname,
+             const char *name,
+             const void *value,
+             size_t size,
+             int flags)
+{
+       if (smbw_path(fname)) {
+               return smbw_setxattr(fname, name, value, size, flags);
+       }
+
+        return (* smbw_libc.setxattr)(fname, name, value, size, flags);
+}
+
+int lsetxattr(const char *fname,
+              const char *name,
+              const void *value,
+              size_t size,
+              int flags)
+{
+       if (smbw_path(fname)) {
+               return smbw_lsetxattr(fname, name, value, size, flags);
+       }
+
+        return (* smbw_libc.lsetxattr)(fname, name, value, size, flags);
+}
+
+int fsetxattr(int fd,
+              const char *name,
+              const void *value,
+              size_t size,
+              int flags)
+{
+       if (smbw_fd(fd)) {
+               return smbw_fsetxattr(fd, name, value, size, flags);
+       }
+
+        return (* smbw_libc.fsetxattr)(fd, name, value, size, flags);
+}
+
+int getxattr(const char *fname,
+             const char *name,
+             const void *value,
+             size_t size)
+{
+       if (smbw_path(fname)) {
+               return smbw_getxattr(fname, name, value, size);
+       }
+
+        return (* smbw_libc.getxattr)(fname, name, value, size);
+}
+
+int lgetxattr(const char *fname,
+              const char *name,
+              const void *value,
+              size_t size)
+{
+       if (smbw_path(fname)) {
+               return smbw_lgetxattr(fname, name, value, size);
+       }
+
+        return (* smbw_libc.lgetxattr)(fname, name, value, size);
+}
+
+int fgetxattr(int fd,
+              const char *name,
+              const void *value,
+              size_t size)
+{
+       if (smbw_fd(fd)) {
+               return smbw_fgetxattr(fd, name, value, size);
+       }
+
+        return (* smbw_libc.fgetxattr)(fd, name, value, size);
+}
+
+int removexattr(const char *fname,
+                const char *name)
+{
+       if (smbw_path(fname)) {
+               return smbw_removexattr(fname, name);
+       }
+
+        return (* smbw_libc.removexattr)(fname, name);
+}
+
+int lremovexattr(const char *fname,
+                 const char *name)
+{
+       if (smbw_path(fname)) {
+               return smbw_lremovexattr(fname, name);
+       }
+
+        return (* smbw_libc.lremovexattr)(fname, name);
+}
+
+int fremovexattr(int fd,
+                 const char *name)
+{
+       if (smbw_fd(fd)) {
+               return smbw_fremovexattr(fd, name);
+       }
+
+        return (* smbw_libc.fremovexattr)(fd, name);
+}
+
+int listxattr(const char *fname,
+              char *list,
+              size_t size)
+{
+       if (smbw_path(fname)) {
+               return smbw_listxattr(fname, list, size);
+       }
+
+        return (* smbw_libc.listxattr)(fname, list, size);
+}
+
+int llistxattr(const char *fname,
+               char *list,
+               size_t size)
+{
+       if (smbw_path(fname)) {
+               return smbw_llistxattr(fname, list, size);
+       }
+
+        return (* smbw_libc.llistxattr)(fname, list, size);
+}
+
+int flistxattr(int fd,
+               char *list,
+               size_t size)
+{
+       if (smbw_fd(fd)) {
+                return smbw_flistxattr(fd, list, size);
+       }
+
+        return (* smbw_libc.flistxattr)(fd, list, size);
+}
+
+
+/*
+ * We're ending up with a different implementation of malloc() with smbwrapper
+ * than without it.  The one with it does not support returning a non-NULL
+ * pointer from a call to malloc(0), and many apps depend on getting a valid
+ * pointer when requesting zero length (e.g. df, emacs).
+ *
+ * Unfortunately, initializing the smbw_libc[] array via the dynamic link
+ * library (libdl) requires malloc so we can't just do the same type of
+ * mapping to the C library as we do with everything else.  We need to
+ * implement a different way of allocating memory that ensures that the C
+ * library version of malloc() gets used.  This is the only place where we
+ * kludge the code to use an undocumented interface to the C library.
+ *
+ * If anyone can come up with a way to dynamically link to the C library
+ * rather than using this undocumented interface, I'd sure love to hear about
+ * it.  Better yet, if you can figure out where the alternate malloc()
+ * functions are coming from and arrange for them not to be called, that would
+ * be even better.  We should try to avoid wrapping functions that don't
+ * really require it.
+ */
+
+void *malloc(size_t size)
+{
+        void *__libc_malloc(size_t size);
+        return __libc_malloc(size);
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+        void *__libc_calloc(size_t nmemb, size_t size);
+        return __libc_calloc(nmemb, size);
+}
+
+void *realloc(void *ptr, size_t size)
+{
+        void *__libc_realloc(void *ptr, size_t size);
+        return __libc_realloc(ptr, size);
+}
+
+void free(void *ptr)
+{
+        static int      in_progress = 0;
+        void __libc_free(void *ptr);
+
+        if (in_progress) return;
+        in_progress = 1;
+        __libc_free(ptr);
+        in_progress = 0;
+}
+
+
+#if 0                           /* SELECT */
+
+static struct sigaction user_action[_NSIG];
+
+static void
+smbw_sigaction_handler(int signum,
+                       siginfo_t *info,
+                       void *context)
+{
+        /* Our entire purpose for trapping signals is to call this! */
+        sys_select_signal();
+
+        /* Call the user's handler */
+        if (user_action[signum].sa_handler != SIG_IGN &&
+            user_action[signum].sa_handler != SIG_DFL &&
+            user_action[signum].sa_handler != SIG_ERR) {
+                (* user_action[signum].sa_sigaction)(signum, info, context);
+        }
+}
+
+
+/*
+ * Every Samba signal handler must call sys_select_signal() to avoid a race
+ * condition, so we'll take whatever signal handler is currently assigned,
+ * call call sys_select_signal() in addition to their call.
+ */
+static int
+do_select(int n,
+          fd_set *readfds,
+          fd_set *writefds,
+          fd_set *exceptfds,
+          struct timeval *timeout,
+          int (* select_fn)(int n,
+                            fd_set *readfds,
+                            fd_set *writefds,
+                            fd_set *exceptfds,
+                            struct timeval *timeout))
+{
+        int i;
+        int ret;
+        int saved_errno;
+        sigset_t sigset;
+        struct sigaction new_action;
+
+        saved_errno = errno;
+        for (i=1; i<_NSIG; i++) {
+                sigemptyset(&sigset);
+                new_action.sa_mask = sigset;
+                new_action.sa_flags = SA_SIGINFO;
+                new_action.sa_sigaction = smbw_sigaction_handler;
+
+                if (sigaction(i, &new_action, &user_action[i]) < 0) {
+                        if (errno != EINVAL) {
+                                return -1;
+                        }
+                }
+        }
+        errno = saved_errno;
+
+        ret = (* select_fn)(n, readfds, writefds, exceptfds, timeout);
+        saved_errno = errno;
+
+        for (i=0; i<_NSIG; i++) {
+                (void) sigaction(i, &user_action[i], NULL);
+        }
+
+        errno = saved_errno;
+        return ret;
+}
+
+int
+select(int n,
+       fd_set *readfds,
+       fd_set *writefds,
+       fd_set *exceptfds,
+       struct timeval *timeout)
+{
+        check_init("select");
+
+        return do_select(n, readfds, writefds, exceptfds,
+                         timeout, smbw_libc.select);
+}
+
+int
+_select(int n,
+        fd_set *readfds,
+        fd_set *writefds,
+        fd_set *exceptfds,
+        struct timeval *timeout)
+{
+        check_init("_select");
+
+        return do_select(n, readfds, writefds, exceptfds,
+                         timeout, smbw_libc._select);
+}
+
+int
+__select(int n,
+         fd_set *readfds,
+         fd_set *writefds,
+         fd_set *exceptfds,
+         struct timeval *timeout)
+{
+        check_init("__select");
+
+        return do_select(n, readfds, writefds, exceptfds,
+                         timeout, smbw_libc.__select);
+}
+
+#endif
diff --git a/examples/libsmbclient/smbwrapper/wrapper.h b/examples/libsmbclient/smbwrapper/wrapper.h
new file mode 100644 (file)
index 0000000..6d0d9f5
--- /dev/null
@@ -0,0 +1,209 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 2.0
+   SMB wrapper functions
+   Copyright (C) Derrell Lipman 2003-2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __WRAPPER_H__
+#define __WRAPPER_H__
+
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <utime.h>
+#include <signal.h>
+#include <stdio.h>
+
+extern int smbw_fd_map[__FD_SETSIZE];
+extern int smbw_ref_count[__FD_SETSIZE];
+extern char smbw_cwd[PATH_MAX];
+extern char smbw_prefix[];
+
+typedef struct SMBW_stat {
+        unsigned long           s_dev;     /* device */
+        unsigned long           s_ino;     /* inode */
+        unsigned long           s_mode;    /* protection */
+        unsigned long           s_nlink;   /* number of hard links */
+        unsigned long           s_uid;     /* user ID of owner */
+        unsigned long           s_gid;     /* group ID of owner */
+        unsigned long           s_rdev;    /* device type (if inode device) */
+        unsigned long long      s_size;    /* total size, in bytes */
+        unsigned long           s_blksize; /* blocksize for filesystem I/O */
+        unsigned long           s_blocks;  /* number of blocks allocated */
+        unsigned long           s_atime;   /* time of last access */
+        unsigned long           s_mtime;   /* time of last modification */
+        unsigned long           s_ctime;   /* time of last change */
+} SMBW_stat;
+
+typedef struct SMBW_dirent {
+        unsigned long           d_ino;      /* inode number */
+        unsigned long long      d_off;      /* offset to the next dirent */
+        unsigned long           d_reclen;   /* length of this record */
+        unsigned long           d_type;     /* type of file */
+        char                    d_name[256]; /* filename */
+        char                    d_comment[256]; /* comment */
+} SMBW_dirent;
+
+struct kernel_sigaction {
+        __sighandler_t k_sa_handler;
+        unsigned long sa_flags;
+        sigset_t sa_mask;
+};
+
+typedef struct SMBW_libc
+{
+        /* write() is first, to allow debugging */
+        ssize_t (* write)(int fd, void *buf, size_t count);
+        int (* open)(char *name, int flags, mode_t mode);
+        int (* _open)(char *name, int flags, mode_t mode) ;
+        int (* __open)(char *name, int flags, mode_t mode) ;
+        int (* open64)(char *name, int flags, mode_t mode);
+        int (* _open64)(char *name, int flags, mode_t mode) ;
+        int (* __open64)(char *name, int flags, mode_t mode) ;
+        ssize_t (* pread)(int fd, void *buf, size_t size, off_t ofs);
+        ssize_t (* pread64)(int fd, void *buf, size_t size, off64_t ofs);
+        ssize_t (* pwrite)(int fd, void *buf, size_t size, off_t ofs);
+        ssize_t (* pwrite64)(int fd, void *buf, size_t size, off64_t ofs);
+        int (* close)(int fd);
+        int (* __close)(int fd);
+        int (* _close)(int fd);
+        int (* fcntl)(int fd, int cmd, long arg);
+        int (* __fcntl)(int fd, int cmd, long arg);
+        int (* _fcntl)(int fd, int cmd, long arg);
+        int (* getdents)(int fd, struct dirent *dirp, unsigned int count);
+        int (* __getdents)(int fd, struct dirent *dirp, unsigned int count);
+        int (* _getdents)(int fd, struct dirent *dirp, unsigned int count);
+        int (* getdents64)(int fd, struct dirent64 *dirp, unsigned int count);
+        off_t (* lseek)(int fd, off_t offset, int whence);
+        off_t (* __lseek)(int fd, off_t offset, int whence);
+        off_t (* _lseek)(int fd, off_t offset, int whence);
+        off64_t (* lseek64)(int fd, off64_t offset, int whence);
+        off64_t (* __lseek64)(int fd, off64_t offset, int whence);
+        off64_t (* _lseek64)(int fd, off64_t offset, int whence);
+        ssize_t (* read)(int fd, void *buf, size_t count);
+        ssize_t (* __read)(int fd, void *buf, size_t count);
+        ssize_t (* _read)(int fd, void *buf, size_t count);
+        ssize_t (* __write)(int fd, void *buf, size_t count);
+        ssize_t (* _write)(int fd, void *buf, size_t count);
+        int (* access)(char *name, int mode);
+        int (* chmod)(char *name, mode_t mode);
+        int (* fchmod)(int fd, mode_t mode);
+        int (* chown)(char *name, uid_t owner, gid_t group);
+        int (* fchown)(int fd, uid_t owner, gid_t group);
+        int (* __xstat)(int vers, char *name, struct stat *st);
+        char * ( *getcwd)(char *buf, size_t size);
+        int (* mkdir)(char *name, mode_t mode);
+        int (* __fxstat)(int vers, int fd, struct stat *st);
+        int (* __lxstat)(int vers, char *name, struct stat *st);
+        int (* stat)(char *name, struct stat *st);
+        int (* lstat)(char *name, struct stat *st);
+        int (* fstat)(int fd, struct stat *st);
+        int (* unlink)(char *name);
+        int (* utime)(char *name, struct utimbuf *tvp);
+        int (* utimes)(char *name, struct timeval *tvp);
+        int (* readlink)(char *path, char *buf, size_t bufsize);
+        int (* rename)(char *oldname, char *newname);
+        int (* rmdir)(char *name);
+        int (* symlink)(char *topath, char *frompath);
+        int (* dup)(int fd);
+        int (* dup2)(int oldfd, int newfd);
+        DIR * (* opendir)(char *name);
+        struct dirent * (* readdir)(DIR *dir);
+        int (* closedir)(DIR *dir);
+        off_t (* telldir)(DIR *dir);
+        void (* seekdir)(DIR *dir, off_t offset);
+        int (* creat)(char *path, mode_t mode);
+        int (* creat64)(char *path, mode_t mode);
+        int (* __xstat64)(int ver, char *name, struct stat64 *st64);
+        int (* stat64)(char *name, struct stat64 *st64);
+        int (* __fxstat64)(int ver, int fd, struct stat64 *st64);
+        int (* fstat64)(int fd, struct stat64 *st64);
+        int (* __lxstat64)(int ver, char *name, struct stat64 *st64);
+        int (* lstat64)(char *name, struct stat64 *st64);
+        int (* _llseek)(unsigned int fd,  unsigned  long  offset_high, unsigned  long  offset_low,  loff_t  *result, unsigned int whence);
+        struct dirent64 * (* readdir64)(DIR *dir);
+        int (* readdir_r)(DIR *dir, struct dirent *entry, struct dirent **result);
+        int (* readdir64_r)(DIR *dir, struct dirent64 *entry, struct dirent64 **result);
+        int (* setxattr)(const char *fname,
+                         const char *name,
+                         const void *value,
+                         size_t size,
+                         int flags);
+        int (* lsetxattr)(const char *fname,
+                          const char *name,
+                          const void *value,
+                          size_t size,
+                          int flags);
+        int (* fsetxattr)(int smbw_fd,
+                          const char *name,
+                          const void *value,
+                          size_t size,
+                          int flags);
+        int (* getxattr)(const char *fname,
+                         const char *name,
+                         const void *value,
+                         size_t size);
+        int (* lgetxattr)(const char *fname,
+                          const char *name,
+                          const void *value,
+                          size_t size);
+        int (* fgetxattr)(int smbw_fd,
+                          const char *name,
+                          const void *value,
+                          size_t size);
+        int (* removexattr)(const char *fname,
+                            const char *name);
+        int (* lremovexattr)(const char *fname,
+                             const char *name);
+        int (* fremovexattr)(int smbw_fd,
+                             const char *name);
+        int (* listxattr)(const char *fname,
+                          char *list,
+                          size_t size);
+        int (* llistxattr)(const char *fname,
+                           char *list,
+                           size_t size);
+        int (* flistxattr)(int smbw_fd,
+                           char *list,
+                           size_t size);
+        int (* chdir)(const char *path);
+        int (* fchdir)(int fd);
+        pid_t (* fork)(void);
+        int (* select)(int n,
+                       fd_set *readfds,
+                       fd_set *writefds,
+                       fd_set *exceptfds,
+                       struct timeval *timeout);
+        int (* _select)(int n,
+                        fd_set *readfds,
+                        fd_set *writefds,
+                        fd_set *exceptfds,
+                        struct timeval *timeout);
+        int (* __select)(int n,
+                         fd_set *readfds,
+                         fd_set *writefds,
+                         fd_set *exceptfds,
+                         struct timeval *timeout);
+} SMBW_libc_pointers;
+
+extern SMBW_libc_pointers smbw_libc;
+
+#endif /* __WRAPPER_H__ */
index 47668f7c9c4af4f829b121f7b06487dd90d0d8f3..ce5694b331a00f6991f0af9361bcb9ba13c75f87 100644 (file)
@@ -3,6 +3,7 @@
 #include <errno.h>
 #include <popt.h>
 #include "libsmbclient.h"
+#include "get_auth_data_fn.h"
 
 enum acl_mode
 {
@@ -15,59 +16,6 @@ enum acl_mode
     SMB_ACL_CHGRP
 };
 
-static void
-get_auth_data_fn(const char * pServer,
-                 const char * pShare,
-                 char * pWorkgroup,
-                 int maxLenWorkgroup,
-                 char * pUsername,
-                 int maxLenUsername,
-                 char * pPassword,
-                 int maxLenPassword)
-    
-{
-    char temp[128];
-    
-    fprintf(stdout, "Workgroup: [%s] ", pWorkgroup);
-    fgets(temp, sizeof(temp), stdin);
-    
-    if (temp[strlen(temp) - 1] == '\n') /* A new line? */
-    {
-        temp[strlen(temp) - 1] = '\0';
-    }
-    
-    if (temp[0] != '\0')
-    {
-        strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
-    }
-    
-    fprintf(stdout, "Username: [%s] ", pUsername);
-    fgets(temp, sizeof(temp), stdin);
-    
-    if (temp[strlen(temp) - 1] == '\n') /* A new line? */
-    {
-        temp[strlen(temp) - 1] = '\0';
-    }
-    
-    if (temp[0] != '\0')
-    {
-        strncpy(pUsername, temp, maxLenUsername - 1);
-    }
-    
-    fprintf(stdout, "Password: ");
-    fgets(temp, sizeof(temp), stdin);
-    
-    if (temp[strlen(temp) - 1] == '\n') /* A new line? */
-    {
-        temp[strlen(temp) - 1] = '\0';
-    }
-    
-    if (temp[0] != '\0')
-    {
-        strncpy(pPassword, temp, maxLenPassword - 1);
-    }
-}
-
 
 int main(int argc, const char *argv[])
 {
index d2472230a206480b495f1358f685f0b508ef2fac..27d6a6973882e377f6b4429d7ac14d742408872f 100644 (file)
-/* 
-   Unix SMB/CIFS implementation.
-   SMB client library test program for browsing with different master browsers
-   Copyright (C) Derrell Lipman 2004
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
 #include <errno.h>
-#include <sys/time.h>
+#include <stdio.h>
 #include <string.h>
-#include <unistd.h>
+#include <popt.h>
 #include <stdlib.h>
 #include <libsmbclient.h>
+#include "get_auth_data_fn.h"
 
-static void
-auth_fn(const char * pServer,
-        const char * pShare,
-        char * pWorkgroup,
-        int workgroup_len,
-        char * pUsername,
-        int username_len,
-        char * pPassword,
-        int password_len)
-    
+void error_message(char * pMessage)
 {
-    strncpy(pUsername, "anonymous", username_len); /* doesn't matter what */
-    strncpy(pPassword, "password", password_len);  /* ditto */
+    printf("ERROR: %s\n", pMessage);
 }
 
 
 int
 main(int argc, char * argv[])
 {
-    int                         debug = 4;
+    int                         debug = 0;
     int                         opt;
     char *                      p;
+    char *                      q;
     char                        buf[1024];
     int                         dir;
+    struct stat                 stat;
     struct smbc_dirent *        dirent;
-    char **                     ppUrl;
-    char *                      urlList[] =
+    poptContext pc;
+    struct poptOption           long_options[] =
         {
-            "smb://",
-            "smb://?mb=.any",
-            "smb://?mb=.all",
-            "smb://?mb=xx",     /* this one is suupposed to fail */
-            NULL
+            POPT_AUTOHELP
+            {
+                "debug", 'd', POPT_ARG_INT, &debug,
+                0, "Set debug level", "integer"
+            },
+            {
+                NULL
+            }
         };
     
-    if (smbc_init(auth_fn, debug) != 0)
+    setbuf(stdout, NULL);
+
+    pc = poptGetContext("opendir", argc, (const char **)argv, long_options, 0);
+    
+    poptSetOtherOptionHelp(pc, "");
+    
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+        printf("Got option %d = %c\n", opt, opt);
+        switch (opt) {
+        }
+    }
+
+    if (smbc_init(get_auth_data_fn, debug) != 0)
     {
         printf("Could not initialize smbc_ library\n");
         return 1;
     }
     
-    for (ppUrl = urlList; *ppUrl != NULL; ppUrl++)
+    for (fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin);
+         p != NULL && *p != '\n' && *p != '\0';
+         fputs("url: ", stdout), p = fgets(buf, sizeof(buf), stdin))
     {
-        printf("Opening (%s)...\n", *ppUrl);
-    
-        if ((dir = smbc_opendir(*ppUrl)) < 0)
+        if ((p = strchr(buf, '\n')) != NULL)
         {
-            printf("Could not open [%s] (%d:%s)\n",
-                   *ppUrl, errno, strerror(errno));
+            *p = '\0';
+        }
+        
+        printf("Opening (%s)...\n", buf);
+        
+        if ((dir = smbc_opendir(buf)) < 0)
+        {
+            printf("Could not open directory [%s] (%d:%s)\n",
+                   buf, errno, strerror(errno));
             continue;
         }
-    
+
         while ((dirent = smbc_readdir(dir)) != NULL)
         {
-            printf("%s\n", dirent->name);
+            printf("%-30s", dirent->name);
+            printf("%-30s", dirent->comment);
+
+            switch(dirent->smbc_type)
+            {
+            case SMBC_WORKGROUP:
+                printf("WORKGROUP");
+                break;
+            
+            case SMBC_SERVER:
+                printf("SERVER");
+                break;
+            
+            case SMBC_FILE_SHARE:
+                printf("FILE_SHARE");
+                break;
+            
+            case SMBC_PRINTER_SHARE:
+                printf("PRINTER_SHARE");
+                break;
+            
+            case SMBC_COMMS_SHARE:
+                printf("COMMS_SHARE");
+                break;
+            
+            case SMBC_IPC_SHARE:
+                printf("IPC_SHARE");
+                break;
+            
+            case SMBC_DIR:
+                printf("DIR");
+                break;
+            
+            case SMBC_FILE:
+                printf("FILE");
+
+                q = buf + strlen(buf);
+                strcat(q, "/");
+                strcat(q+1, dirent->name);
+                if (smbc_stat(buf, &stat) < 0)
+                {
+                    printf(" unknown size (reason %d: %s)",
+                           errno, strerror(errno));
+                }
+                else
+                {
+                    printf(" size %lu", (unsigned long) stat.st_size);
+                }
+                *p = '\0';
+
+                break;
+            
+            case SMBC_LINK:
+                printf("LINK");
+                break;
+            }
+
+            printf("\n");
         }
-    
+
         smbc_closedir(dir);
     }
-    
+
     exit(0);
 }
-
diff --git a/examples/libsmbclient/testchmod.c b/examples/libsmbclient/testchmod.c
new file mode 100644 (file)
index 0000000..774daae
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdio.h> 
+#include <unistd.h>
+#include <string.h> 
+#include <time.h> 
+#include <libsmbclient.h> 
+#include "get_auth_data_fn.h"
+
+
+int main(int argc, char * argv[]) 
+{ 
+    int             ret;
+    int             debug = 0;
+    int             mode = 0666;
+    char            buffer[16384]; 
+    char *          pSmbPath = NULL;
+    struct stat     st; 
+    
+    if (argc == 1)
+    {
+        pSmbPath = "smb://RANDOM/Public/small";
+    }
+    else if (argc == 2)
+    {
+        pSmbPath = argv[1];
+    }
+    else if (argc == 3)
+    {
+        pSmbPath = argv[1];
+        mode = (int) strtol(argv[2], NULL, 8);
+    }
+    else
+    {
+        printf("usage: "
+               "%s [ smb://path/to/file [ octal_mode ] ]\n",
+               argv[0]);
+        return 1;
+    }
+
+    smbc_init(get_auth_data_fn, debug); 
+    
+    if (smbc_stat(pSmbPath, &st) < 0)
+    {
+        perror("smbc_stat");
+        return 1;
+    }
+    
+    printf("\nBefore chmod: mode = %04o\n", st.st_mode);
+    
+    if (smbc_chmod(pSmbPath, mode) < 0)
+    {
+        perror("smbc_chmod");
+        return 1;
+    }
+
+    if (smbc_stat(pSmbPath, &st) < 0)
+    {
+        perror("smbc_stat");
+        return 1;
+    }
+    
+    printf("After chmod: mode = %04o\n", st.st_mode);
+    
+    return 0; 
+}
index 888a9c0d4f9e26fb23dced9088bc6eaf5e7be343..45e67bee62c63430618f3f61b09326088e8f4575 100644 (file)
 #include <unistd.h>
 #include <stdlib.h>
 #include <libsmbclient.h>
-
-void auth_fn(const char *server, const char *share,
-            char *workgroup, int wgmaxlen, char *username, int unmaxlen,
-            char *password, int pwmaxlen)
-{
-  char temp[128];
-
-  fprintf(stdout, "Need password for //%s/%s\n", server, share);
-
-  fprintf(stdout, "Enter workgroup: [%s] ", workgroup);
-  fgets(temp, sizeof(temp), stdin);
-
-  if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
-    temp[strlen(temp) - 1] = 0x00;
-
-  if (temp[0]) strncpy(workgroup, temp, wgmaxlen - 1);
-
-  fprintf(stdout, "Enter username: [%s] ", username);
-  fgets(temp, sizeof(temp), stdin);
-
-  if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
-    temp[strlen(temp) - 1] = 0x00;
-
-  if (temp[0]) strncpy(username, temp, unmaxlen - 1);
-
-  fprintf(stdout, "Enter password: [%s] ", password);
-  fgets(temp, sizeof(temp), stdin);
-
-  if (temp[strlen(temp) - 1] == 0x0a) /* A new line? */
-    temp[strlen(temp) - 1] = 0x00;
-
-  if (temp[0]) strncpy(password, temp, pwmaxlen - 1);
-
-}
+#include "get_auth_data_fn.h"
 
 int global_id = 0;
 
@@ -84,7 +51,7 @@ int main(int argc, char *argv[])
   char *dirp;
   struct stat st1, st2;
 
-  err = smbc_init(auth_fn,  10); /* Initialize things */
+  err = smbc_init(get_auth_data_fn,  10); /* Initialize things */
 
   if (err < 0) {
 
@@ -132,7 +99,7 @@ int main(int argc, char *argv[])
              ((struct smbc_dirent *)dirp)->comment);
 
       dirp += dsize;
-      (char *)dirc -= dsize;
+      dirc -= dsize;
 
     }
 
diff --git a/examples/libsmbclient/teststat.c b/examples/libsmbclient/teststat.c
new file mode 100644 (file)
index 0000000..29517ef
--- /dev/null
@@ -0,0 +1,71 @@
+#include <stdio.h> 
+#include <unistd.h>
+#include <string.h> 
+#include <time.h> 
+#include <libsmbclient.h> 
+#include "get_auth_data_fn.h"
+
+
+int main(int argc, char * argv[]) 
+{ 
+    int             debug = 0;
+    char            buffer[16384]; 
+    char            mtime[32];
+    char            ctime[32];
+    char            atime[32];
+    char *          pSmbPath = NULL;
+    char *          pLocalPath = NULL;
+    struct stat     st; 
+    
+    if (argc == 1)
+    {
+        pSmbPath = "smb://RANDOM/Public/small";
+        pLocalPath = "/random/home/samba/small";
+    }
+    else if (argc == 2)
+    {
+        pSmbPath = argv[1];
+        pLocalPath = NULL;
+    }
+    else if (argc == 3)
+    {
+        pSmbPath = argv[1];
+        pLocalPath = argv[2];
+    }
+    else
+    {
+        printf("usage: "
+               "%s [ smb://path/to/file [ /nfs/or/local/path/to/file ] ]\n",
+               argv[0]);
+        return 1;
+    }
+
+    smbc_init(get_auth_data_fn, debug); 
+    
+    if (smbc_stat(pSmbPath, &st) < 0)
+    {
+        perror("smbc_stat");
+        return 1;
+    }
+    
+    printf("SAMBA\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
+           st.st_mtime, ctime_r(&st.st_mtime, mtime),
+           st.st_ctime, ctime_r(&st.st_ctime, ctime),
+           st.st_atime, ctime_r(&st.st_atime, atime)); 
+    
+    if (pLocalPath != NULL)
+    {
+        if (stat(pLocalPath, &st) < 0)
+        {
+            perror("stat");
+            return 1;
+        }
+        
+        printf("LOCAL\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
+               st.st_mtime, ctime_r(&st.st_mtime, mtime),
+               st.st_ctime, ctime_r(&st.st_ctime, ctime),
+               st.st_atime, ctime_r(&st.st_atime, atime)); 
+    }
+
+    return 0; 
+}
diff --git a/examples/libsmbclient/testutime.c b/examples/libsmbclient/testutime.c
new file mode 100644 (file)
index 0000000..3a1540c
--- /dev/null
@@ -0,0 +1,76 @@
+#include <stdio.h> 
+#include <unistd.h>
+#include <string.h> 
+#include <time.h> 
+#include <libsmbclient.h> 
+#include "get_auth_data_fn.h"
+
+
+int main(int argc, char * argv[]) 
+{ 
+    int             ret;
+    int             debug = 0;
+    int             mode = 0666;
+    char            buffer[16384]; 
+    char            mtime[32];
+    char            ctime[32];
+    char            atime[32];
+    char *          pSmbPath = NULL;
+    struct stat     st;
+    struct utimbuf  utimbuf;
+    
+    if (argc == 1)
+    {
+        pSmbPath = "smb://RANDOM/Public/small";
+    }
+    else if (argc == 2)
+    {
+        pSmbPath = argv[1];
+    }
+    else if (argc == 3)
+    {
+        pSmbPath = argv[1];
+        mode = (int) strtol(argv[2], NULL, 8);
+    }
+    else
+    {
+        printf("usage: "
+               "%s [ smb://path/to/file [ octal_mode ] ]\n",
+               argv[0]);
+        return 1;
+    }
+
+    smbc_init(get_auth_data_fn, debug); 
+    
+    if (smbc_stat(pSmbPath, &st) < 0)
+    {
+        perror("smbc_stat");
+        return 1;
+    }
+    
+    printf("Before\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
+           st.st_mtime, ctime_r(&st.st_mtime, mtime),
+           st.st_ctime, ctime_r(&st.st_ctime, ctime),
+           st.st_atime, ctime_r(&st.st_atime, atime)); 
+    
+    utimbuf.actime = st.st_atime - 120;  /* unchangable.  this one wont change */
+    utimbuf.modtime = st.st_mtime - 120; /* this one should succeed */
+    if (smbc_utime(pSmbPath, &utimbuf) < 0)
+    {
+        perror("smbc_utime");
+        return 1;
+    }
+
+    if (smbc_stat(pSmbPath, &st) < 0)
+    {
+        perror("smbc_stat");
+        return 1;
+    }
+    
+    printf("After\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
+           st.st_mtime, ctime_r(&st.st_mtime, mtime),
+           st.st_ctime, ctime_r(&st.st_ctime, ctime),
+           st.st_atime, ctime_r(&st.st_atime, atime)); 
+    
+    return 0; 
+}
index f50b3670cff23a8d694777eea13ec391238a7736..d8a69c8d4ccb4c48889b1f5965f91b94e9713568 100644 (file)
@@ -294,7 +294,7 @@ static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
 
       gtk_clist_append(GTK_CLIST(clist), rowdata);
 
-      (char *)dirp += dirlen;
+      dirp = (struct smbc_dirent *) ((char *) dirp + dirlen);
       err -= dirlen;
 
     }
@@ -429,7 +429,7 @@ static void cb_itemsignal( GtkWidget *item,
 
        }
 
-       (char *)dirp += dirlen;
+        dirp = (struct smbc_dirent *) ((char *) dirp + dirlen);
        err -= dirlen;
 
       }
@@ -564,7 +564,7 @@ static void cb_wholenet(GtkWidget *item, gchar *signame)
        gtk_signal_connect(GTK_OBJECT(subtree), "unselect_child",
                           GTK_SIGNAL_FUNC(cb_unselect_child), real_tree);
 
-       (char *)dirp += dirlen;
+        dirp = (struct smbc_dirent *) ((char *) dirp + dirlen);
        err -= dirlen;
 
       }
@@ -797,7 +797,7 @@ int main( int   argc,
       gtk_signal_connect (GTK_OBJECT(subtree), "unselect_child",
                          GTK_SIGNAL_FUNC(cb_unselect_child), tree);
 
-      (char *)dirp += dirlen;
+      dirp = (struct smbc_dirent *) ((char *) dirp + dirlen);
       err -= dirlen;
 
     }
index fda2bd3d93a8567f7aad3074e11413eeef48bcc7..7917db769c20bb7e0dd59de5204dc78c9d696236 100644 (file)
@@ -92,15 +92,13 @@ LOCKDIR = @lockdir@
 
 # the directory where pid files go
 PIDDIR = @piddir@
-# man pages language(s)
-man_langs = "@manlangs@"
 
 LIBSMBCLIENT=bin/libsmbclient.a @LIBSMBCLIENT_SHARED@
 LIBSMBCLIENT_MAJOR=0
 LIBSMBCLIENT_MINOR=1
 
 
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper  -I. $(CPPFLAGS) -I$(srcdir)
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir)
 FLAGS2 = 
 FLAGS3 = 
 FLAGS4 = 
@@ -173,6 +171,8 @@ SNPRINTF_OBJ = lib/snprintf.o
 
 WBCOMMON_OBJ = nsswitch/wb_common.o
 
+DUMMYROOT_OBJ = lib/dummyroot.o
+
 AFS_OBJ = lib/afs.o
 
 AFS_SETTOKEN_OBJ = lib/afs_settoken.o
@@ -206,7 +206,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
          lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
          lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
 
-LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummyroot.o lib/dummysmbd.o
+LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
 
 READLINE_OBJ = lib/readline.o
 
@@ -255,12 +255,12 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
               rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \
               rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o  \
               rpc_client/cli_ds.o rpc_client/cli_echo.o \
-              rpc_client/cli_shutdown.o
+              rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
 
 REGOBJS_OBJ = registry/reg_objects.o
 
 REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
-               registry/reg_db.o 
+               registry/reg_db.o registry/reg_eventlog.o
 
 RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o
 
@@ -277,10 +277,14 @@ RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
 
 RPC_WKS_OBJ =  rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
 
+RPC_SVCCTL_OBJ =  rpc_server/srv_svcctl.o rpc_server/srv_svcctl_nt.o
+
 RPC_DFS_OBJ =  rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
 
 RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o 
 
+RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o
+
 RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
                rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
 
@@ -298,7 +302,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
                 rpc_parse/parse_wks.o rpc_parse/parse_ds.o \
                rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
                rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
-               $(REGOBJS_OBJ)
+               rpc_parse/parse_svcctl.o \
+               rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o $(REGOBJS_OBJ)
 
 RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
 
@@ -342,6 +347,7 @@ VFS_CAP_OBJ = modules/vfs_cap.o
 VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
 VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
 VFS_AFSACL_OBJ = modules/vfs_afsacl.o
+VFS_CATIA_OBJ = modules/vfs_catia.o
 
 PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
 
@@ -434,20 +440,20 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
           $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
           $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
           $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \
-           $(PASSCHANGE_OBJ)
+           $(PASSCHANGE_OBJ) $(DUMMYROOT_OBJ) 
 
 SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
             $(PARAM_OBJ) $(LIB_NONSMBD_OBJ)
 
 STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
-            $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(ERRORMAP_OBJ) 
+            $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ) 
              
 
 SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
        $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
        $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
-       $(PRINTBASE_OBJ) $(ERRORMAP_OBJ)
+       $(PRINTBASE_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
 
 SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
@@ -463,11 +469,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) \
 SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSCHANGE_OBJ) $(PARAM_OBJ) $(SECRETS_OBJ) \
                $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
                 $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
-               $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ)
+               $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) $(DUMMYROOT_OBJ)
 
 PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
                $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
-               $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) 
+               $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ) libsmb/asn1.o
 
 SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ)
 
@@ -483,7 +489,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
              $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
              $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
             $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
-            $(SMBLDAP_OBJ) $(DCUTIL_OBJ) 
+            $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ)
 
 PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \
        nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \
@@ -505,8 +511,8 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
                   libsmb/libsmb_cache.o \
                   $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
                   $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
-                  $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
-                  $(SECRETS_OBJ) 
+                  $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
+                  $(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ)
 
 # This shared library is intended for linking with unit test programs
 # to test Samba internals.  It's called libbigballofmud.so to
@@ -516,7 +522,7 @@ LIBBIGBALLOFMUD_MAJOR = 0
 
 LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
        $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
-       $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) 
+       $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
 
 LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
 
@@ -530,15 +536,16 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
           utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
           utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
           utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
-          utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o
+          utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \
+          utils/net_rpc_service.o
 
 NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
          $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
          $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
          $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
          $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
-         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
-         $(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
+         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ) $(SERVER_MUTEX_OBJ) \
+         $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(PRINTERDB_OBJ) 
 
 CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
          $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
@@ -566,7 +573,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                  $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
 
 LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
-               $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)  
+               $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)  
 
 NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                  $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
@@ -578,17 +585,18 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ
 LOG2PCAP_OBJ = utils/log2pcaphex.o
 
 LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
-               $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+               $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
 
 SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
                           $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
-                          $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
-                          $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ)
+                          $(PASSDB_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
+                          $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ) $(SMBLDAP_OBJ)
 
 SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                $(PARAM_OBJ) \
-               $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
-               $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+               $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
+               $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
+               $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ)
 
 TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) libsmb/nterr.o
 
@@ -609,8 +617,8 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(SECRETS_OBJ) \
 
 PROTO_OBJ = $(SMBD_OBJ_MAIN) \
            $(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
-           $(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
-           $(LIBMSRPC_OBJ) \
+           $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
+           $(LIBMSRPC_OBJ) @SMBWRAP_OBJS@ \
            $(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \
            $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
            $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
@@ -619,7 +627,8 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
            $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
            $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
            $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
-           $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
+           $(RPC_ECHO_OBJ) $(RPC_SVCCTL_OBJ) $(RPC_EVENTLOG_OBJ) $(SMBLDAP_OBJ) \
+            $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
 
 WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \
        $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
@@ -631,7 +640,7 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
 
 PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
                pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
-               $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
+               $(DUMMYROOT_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
                $(SECRETS_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
 
 PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
@@ -661,7 +670,7 @@ WINBINDD_OBJ = \
                $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
                $(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
                $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
-               $(DCUTIL_OBJ) $(IDMAP_OBJ) \
+               $(DCUTIL_OBJ) $(IDMAP_OBJ) $(DUMMYROOT_OBJ) \
                $(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
 
 WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -970,7 +979,7 @@ bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy
 
 bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
        @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+       @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
 
 bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
        @echo Linking $@
@@ -1026,6 +1035,11 @@ bin/librpc_srvsvc.@SHLIBEXT@: $(RPC_SVC_OBJ)
        @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVC_OBJ) -lc \
                @SONAMEFLAG@`basename $@`
 
+bin/librpc_svcctl.@SHLIBEXT@: $(RPC_SVCCTL_OBJ)
+       @echo "Linking $@"
+       @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVCCTL_OBJ) -lc \
+               @SONAMEFLAG@`basename $@`
+
 bin/librpc_wkssvc.@SHLIBEXT@: $(RPC_WKS_OBJ)
        @echo "Linking $@"
        @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_WKS_OBJ) -lc \
@@ -1228,6 +1242,12 @@ bin/afsacl.@SHLIBEXT@: $(VFS_AFSACL_OBJ:.o=.po)
        @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AFSACL_OBJ:.o=.po) \
                @SONAMEFLAG@`basename $@`
 
+bin/catia.@SHLIBEXT@: $(VFS_CATIA_OBJ:.o=.@PICSUFFIX@)
+       @echo "Building plugin $@"
+       @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CATIA_OBJ:.o=.@PICSUFFIX@) \
+               @SONAMEFLAG@`basename $@`
+
+
 bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@
@@ -1335,7 +1355,7 @@ installclientlib: installdirs libsmbclient
 
 PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
        $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-       $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
+       $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
 
 PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
 
@@ -1368,7 +1388,7 @@ revert:
        @$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(BIN_PROGS) $(SCRIPTS)
 
 installman: installdirs
-       @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs) "@ROFF@"
+       @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
 
 .PHONY: showlayout
 
@@ -1390,7 +1410,7 @@ showlayout:
 uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules
 
 uninstallman:
-       @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs)
+       @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
 
 uninstallbin:
        @$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(SBIN_PROGS)
index ab9e6d4432c3003586fc548d20f145746e2c38bc..09052f8f2618ee0e21fa78e4065b8da708b26b4b 100644 (file)
@@ -19,7 +19,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=3
 SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=14a
+SAMBA_VERSION_RELEASE=15
 
 ########################################################
 # For 'pre' releases the version will be               #
@@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=14a
 # e.g. SAMBA_VERSION_PRE_RELEASE=1                     #
 #  ->  "2.2.9pre1"                                     #
 ########################################################
-SAMBA_VERSION_PRE_RELEASE=
+SAMBA_VERSION_PRE_RELEASE=2
 
 ########################################################
 # For 'rc' releases the version will be                #
index a70f1e98b7286b89dee21ddfa38ca1988fbaea0f..2ac70d7354663f32f4dab2bc9d989dabd60bcfce 100644 (file)
@@ -20,6 +20,9 @@
 
 #include "includes.h"
 
+extern struct auth_context *negprot_global_auth_context;
+extern BOOL global_encrypted_passwords_negotiated;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
@@ -68,7 +71,6 @@ static NTSTATUS pass_check_smb(const char *smb_name,
 
 {
        NTSTATUS nt_status;
-       extern struct auth_context *negprot_global_auth_context;
        auth_serversupplied_info *server_info = NULL;
        if (encrypted) {                
                auth_usersupplied_info *user_info = NULL;
@@ -94,7 +96,6 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
 {
 
        DATA_BLOB null_password = data_blob(NULL, 0);
-       extern BOOL global_encrypted_passwords_negotiated;
        BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
        
        if (encrypted) {
index 9da59f220aa1f06e68a1af1c3078496ff4945e8b..023e441e24161cb4fdd9a18d0a2569d2e03b76d0 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "includes.h"
 
+extern struct timeval smb_last_time;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
@@ -74,7 +76,6 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
 static BOOL logon_hours_ok(SAM_ACCOUNT *sampass)
 {
        /* In logon hours first bit is Sunday from 12AM to 1AM */
-       extern struct timeval smb_last_time;
        const uint8 *hours;
        struct tm *utctime;
        uint8 bitmask, bitpos;
index 7cab3df99e4bd9452e0aac57e9f1b4160139cd36..a50a449815c1314940a16f9f3db1f90d8d533041 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Network;
-extern DOM_SID global_sid_Builtin_Guests;
-extern DOM_SID global_sid_Authenticated_Users;
-
 
 /****************************************************************************
  Create a UNIX user on demand.
index 07eb02cf05ceeb242c6be7cfa740af5f3b66059d..be17488919df38f08ad368f97dca275a9dd678b3 100644 (file)
@@ -29,6 +29,9 @@
 #define REGISTER 0
 #endif
 
+extern BOOL AllowDebugChange;
+extern BOOL override_logfile;
+extern char tar_type;
 extern BOOL in_client;
 static int port = 0;
 pstring cur_dir = "\\";
@@ -257,6 +260,7 @@ static int do_cd(char *newdir)
        struct cli_state *targetcli;
        SMB_STRUCT_STAT sbuf;
        uint32 attributes;
+       int ret = 1;
       
        dos_format(newdir);
 
@@ -302,21 +306,23 @@ static int do_cd(char *newdir)
                        pstrcpy(cur_dir,saved_dir);
                        goto out;
                }               
-       }
-       else {
+       } else {
                pstrcat( targetpath, "\\" );
                dos_clean_name( targetpath );
                
                if ( !cli_chkpath(targetcli, targetpath) ) {
                        d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));
                        pstrcpy(cur_dir,saved_dir);
+                       goto out;
                }
        }
 
+       ret = 0;
+
 out:
+       
        pstrcpy(cd_path,cur_dir);
-
-       return 0;
+       return ret;
 }
 
 /****************************************************************************
@@ -711,7 +717,7 @@ static int do_get(char *rname, char *lname, BOOL reget)
        struct timeval tp_start;
        int read_size = io_bufsize;
        uint16 attr;
-       size_t size;
+       SMB_OFF_T size;
        off_t start = 0;
        off_t nread = 0;
        int rc = 0;
@@ -1135,7 +1141,7 @@ static int do_put(char *rname, char *lname, BOOL reput)
 {
        int fnum;
        XFILE *f;
-       size_t start = 0;
+       SMB_OFF_T start = 0;
        off_t nread = 0;
        char *buf = NULL;
        int maxwrite = io_bufsize;
@@ -2235,6 +2241,25 @@ static int cmd_rename(void)
        return 0;
 }
 
+/****************************************************************************
+ Print the volume name.
+****************************************************************************/
+
+static int cmd_volume(void)
+{
+       fstring volname;
+       uint32 serial_num;
+       time_t create_date;
+  
+       if (!cli_get_fs_volume_info(cli, volname, &serial_num, &create_date)) {
+               d_printf("Errr %s getting volume info\n",cli_errstr(cli));
+               return 1;
+       }
+       
+       d_printf("Volume: |%s| serial number 0x%x\n", volname, (unsigned int)serial_num);
+       return 0;
+}
+
 /****************************************************************************
  Hard link files using the NT call.
 ****************************************************************************/
@@ -2748,6 +2773,7 @@ static struct
   {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
   {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
   {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
+  {"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}},
   {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}},
   {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
   {"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}},
@@ -3147,7 +3173,13 @@ static int process(char *base_directory)
                return 1;
        }
 
-       if (*base_directory) do_cd(base_directory);
+       if (*base_directory) {
+               rc = do_cd(base_directory);
+               if (rc) {
+                       cli_cm_shutdown();
+                       return rc;
+               }
+       }
        
        if (cmdstr) {
                rc = process_command_string(cmdstr);
@@ -3210,7 +3242,13 @@ static int do_tar_op(char *base_directory)
 
        recurse=True;
 
-       if (*base_directory) do_cd(base_directory);
+       if (*base_directory)  {
+               ret = do_cd(base_directory);
+               if (ret) {
+                       cli_cm_shutdown();
+                       return ret;
+               }
+       }
        
        ret=process_tar();
 
@@ -3271,13 +3309,10 @@ static int do_message_op(void)
 
  int main(int argc,char *argv[])
 {
-       extern BOOL AllowDebugChange;
-       extern BOOL override_logfile;
        pstring base_directory;
        int opt;
        pstring query_host;
        BOOL message = False;
-       extern char tar_type;
        pstring term_code;
        static const char *new_name_resolve_order = NULL;
        poptContext pc;
index 524feca1d2ac5bc89ba24bf51e97bd78780a3791..b241bd0ec2a281aa79dd73614bc001559323c4ed 100644 (file)
@@ -44,7 +44,7 @@ static int clipfind(char **aret, int ret, char *tok);
 typedef struct file_info_struct file_info2;
 
 struct file_info_struct {
-       SMB_BIG_UINT size;
+       SMB_OFF_T size;
        uint16 mode;
        uid_t uid;
        gid_t gid;
@@ -63,6 +63,7 @@ typedef struct {
 } stack;
 
 #define SEPARATORS " \t\n\r"
+extern time_t newer_than;
 extern struct cli_state *cli;
 
 /* These defines are for the do_setrattr routine, to indicate
@@ -1621,7 +1622,6 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                                        return 0;
                                } else {
                                        SMB_STRUCT_STAT stbuf;
-                                       extern time_t newer_than;
        
                                        if (sys_stat(argv[Optind], &stbuf) == 0) {
                                                newer_than = stbuf.st_mtime;
index 7b30b98fa7b30d454b4e813131e7cb785cf20253..3145447cc4efe3ac4a1cc6e403011ab714c632ad 100755 (executable)
@@ -1,6 +1,6 @@
 /* 
    Mount helper utility for Linux CIFS VFS (virtual filesystem) client
-   Copyright (C) 2003 Steve French  (sfrench@us.ibm.com)
+   Copyright (C) 2003,2005 Steve French  (sfrench@us.ibm.com)
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@
 #include <fcntl.h>
 
 #define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "6"
+#define MOUNT_CIFS_VERSION_MINOR "7"
 
 #ifndef MOUNT_CIFS_VENDOR_SUFFIX
 #define MOUNT_CIFS_VENDOR_SUFFIX ""
@@ -60,7 +60,8 @@ static int got_uid = 0;
 static int got_gid = 0;
 static int free_share_name = 0;
 static char * user_name = NULL;
-char * mountpassword = NULL;
+static char * mountpassword = NULL;
+char * domain_name = NULL;
 
 
 /* BB finish BB
@@ -72,6 +73,9 @@ char * mountpassword = NULL;
                 
 BB end finish BB */
 
+static char * check_for_domain(char **);
+
+
 static void mount_cifs_usage(void)
 {
        printf("\nUsage:  %s <remotetarget> <dir> -o <options>\n", thisprogram);
@@ -79,11 +83,11 @@ static void mount_cifs_usage(void)
        printf(" to a local directory.\n\nOptions:\n");
        printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
        printf("\nLess commonly used options:");
-       printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,\n\trw,ro,sep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,directio");
-       printf("\n\nOptions not needed for servers supporting CIFS Unix extensions (e.g. most Samba versions):");
+       printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,\n\tdirectio");
+       printf("\n\nOptions not needed for servers supporting CIFS Unix extensions\n\t(e.g. most Samba versions):");
        printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>");
        printf("\n\nRarely used options:");
-       printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,dev,nodev");
+       printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,\n\tdev,nodev,nouser_xattr,netbiosname,hard,soft,intr,nointr,noacl");
        printf("\n\nOptions are described in more detail in the manual page");
        printf("\n\tman 8 mount.cifs\n");
        printf("\nTo display the version number of the mount helper:");
@@ -107,7 +111,7 @@ static char * getusername(void) {
        return username;
 }
 
-char * parse_cifs_url(char * unc_name)
+static char * parse_cifs_url(char * unc_name)
 {
        printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name);
        return NULL;
@@ -264,7 +268,9 @@ static int parse_options(char * options, int * filesys_flags)
                data = options;
 
        if(verboseflag)
-               printf("\n parsing options: %s", options);
+               printf("parsing options: %s\n", options);
+
+       /* BB fixme check for separator override BB */
 
 /* while ((data = strsep(&options, ",")) != NULL) { */
        while(data != NULL) {
@@ -276,15 +282,12 @@ static int parse_options(char * options, int * filesys_flags)
                /* data  = next keyword */
                /* value = next value ie stuff after equal sign */
 
-               next_keyword = strchr(data,',');
+               next_keyword = strchr(data,','); /* BB handle sep= */
        
                /* temporarily null terminate end of keyword=value pair */
                if(next_keyword)
                        *next_keyword = 0;
 
-               /* if (!*data)
-                       continue; */
-               
                /* temporarily null terminate keyword to make keyword and value distinct */
                if ((value = strchr(data, '=')) != NULL) {
                        *value = '\0';
@@ -298,6 +301,7 @@ static int parse_options(char * options, int * filesys_flags)
                } else if (strncmp(data, "user_xattr",10) == 0) {
                   /* do nothing - need to skip so not parsed as user name */
                } else if (strncmp(data, "user", 4) == 0) {
+
                        if (!value || !*value) {
                                if(data[4] == '\0') {
                                        if(verboseflag)
@@ -308,7 +312,6 @@ static int parse_options(char * options, int * filesys_flags)
                                                data[1] = ',';
                                                data[2] = ',';
                                                data[3] = ',';
-                                       /* BB remove it from mount line so as not to confuse kernel code */
                                } else {
                                        printf("username specified with no parameter\n");
                                        return 1;       /* needs_arg; */
@@ -334,6 +337,13 @@ static int parse_options(char * options, int * filesys_flags)
                                                        }
                                                }
                                        }
+                                       /* this is only case in which the user
+                                       name buf is not malloc - so we have to
+                                       check for domain name embedded within
+                                       the user name here since the later
+                                       call to check_for_domain will not be
+                                       invoked */
+                                       domain_name = check_for_domain(&value);
                                } else {
                                        printf("username too long\n");
                                        return 1;
@@ -516,15 +526,135 @@ static int parse_options(char * options, int * filesys_flags)
        
                /* put previous overwritten comma back */
                if(next_keyword)
-                       *next_keyword = ',';
+                       *next_keyword = ','; /* BB handle sep= */
                else
                        data = NULL;
        }
        return 0;
 }
 
+/* replace all (one or more) commas with double commas */
+static void check_for_comma(char ** ppasswrd)
+{
+       char *new_pass_buf;
+       char *pass;
+       int i,j;
+       int number_of_commas = 0;
+       int len = strlen(*ppasswrd);
+
+       if(ppasswrd == NULL)
+               return;
+       else 
+               (pass = *ppasswrd);
+
+       for(i=0;i<len;i++)  {
+               if(pass[i] == ',')
+                       number_of_commas++;
+       }
+
+       if(number_of_commas == 0)
+               return;
+       if(number_of_commas > 64) {
+               /* would otherwise overflow the mount options buffer */
+               printf("\nInvalid password. Password contains too many commas.\n");
+               return;
+       }
+
+       new_pass_buf = malloc(len+number_of_commas+1);
+       if(new_pass_buf == NULL)
+               return;
+
+       for(i=0,j=0;i<len;i++,j++) {
+               new_pass_buf[j] = pass[i];
+               if(pass[i] == ',') {
+                       j++;
+                       new_pass_buf[j] = pass[i];
+               }
+       }
+       new_pass_buf[len+number_of_commas] = 0;
+
+       free(*ppasswrd);
+       *ppasswrd = new_pass_buf;
+       
+       return;
+}
+
+/* Usernames can not have backslash in them and we use
+   [BB check if usernames can have forward slash in them BB] 
+   backslash as domain\user separator character
+*/
+static char * check_for_domain(char **ppuser)
+{
+       char * original_string;
+       char * usernm;
+       char * domainnm;
+       int    original_len;
+       int    len;
+       int    i;
+
+       if(ppuser == NULL)
+               return NULL;
+
+       original_string = *ppuser;
+
+       if (original_string == NULL)
+               return NULL;
+       
+       original_len = strlen(original_string);
+
+       usernm = strchr(*ppuser,'/');
+       if (usernm == NULL) {
+               usernm = strchr(*ppuser,'\\');
+               if (usernm == NULL)
+                       return NULL;
+       }
+
+       if(got_domain) {
+               printf("Domain name specified twice. Username probably malformed\n");
+               return NULL;
+       }
+
+       usernm[0] = 0;
+       domainnm = *ppuser;
+       if (domainnm[0] != 0) {
+               got_domain = 1;
+       } else {
+               printf("null domain\n");
+       }
+       len = strlen(domainnm);
+       /* reset domainm to new buffer, and copy
+       domain name into it */
+       domainnm = malloc(len+1);
+       if(domainnm == NULL)
+               return NULL;
+
+       strcpy(domainnm,*ppuser);
+
+/*     move_string(*ppuser, usernm+1) */
+       len = strlen(usernm+1);
+
+       if(len >= original_len) {
+               /* should not happen */
+               return domainnm;
+       }
+
+       for(i=0;i<original_len;i++) {
+               if(i<len)
+                       original_string[i] = usernm[i+1];
+               else /* stuff with commas to remove last parm */
+                       original_string[i] = ',';
+       }
+
+       /* BB add check for more than one slash? 
+         strchr(*ppuser,'/');
+         strchr(*ppuser,'\\') 
+       */
+       
+       return domainnm;
+}
+
 /* Note that caller frees the returned buffer if necessary */
-char * parse_server(char ** punc_name)
+static char * parse_server(char ** punc_name)
 {
        char * unc_name = *punc_name;
        int length = strnlen(unc_name,1024);
@@ -645,7 +775,6 @@ int main(int argc, char ** argv)
        int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */
        char * orgoptions = NULL;
        char * share_name = NULL;
-       char * domain_name = NULL;
        char * ipaddr = NULL;
        char * uuid = NULL;
        char * mountpoint;
@@ -756,7 +885,7 @@ int main(int argc, char ** argv)
                        user_name = optarg;
                        break;
                case 'd':
-                       domain_name = optarg;
+                       domain_name = optarg; /* BB fix this - currently ignored */
                        break;
                case 'p':
                        if(mountpassword == NULL)
@@ -796,14 +925,12 @@ int main(int argc, char ** argv)
 
         if (orgoptions && parse_options(orgoptions, &flags))
                 return -1;
-       
        ipaddr = parse_server(&share_name);
        if((ipaddr == NULL) && (got_ip == 0)) {
                printf("No ip address specified and hostname not found\n");
                return -1;
        }
        
-
        /* BB save off path and pop after mount returns? */
        resolved_path = malloc(PATH_MAX+1);
        if(resolved_path) {
@@ -841,8 +968,10 @@ int main(int argc, char ** argv)
                }
        }
 
-       if(got_user == 0)
+       if(got_user == 0) {
                user_name = getusername();
+               got_user = 1;
+       }
        
        if(got_password == 0) {
                mountpassword = getpass("Password: "); /* BB obsolete */
@@ -864,7 +993,7 @@ mount_retry:
                optlen += strlen(ipaddr) + 4;
        if(mountpassword)
                optlen += strlen(mountpassword) + 6;
-       options = malloc(optlen + 10);
+       options = malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain=  , domain name itself was counted as part of the length username string above */);
 
        if(options == NULL) {
                printf("Could not allocate memory for mount options\n");
@@ -882,15 +1011,31 @@ mount_retry:
        if(ipaddr) {
                strncat(options,",ip=",4);
                strcat(options,ipaddr);
-       } 
+       }
+
        if(user_name) {
+               /* check for syntax like user=domain\user */
+               domain_name = check_for_domain(&user_name);
                strncat(options,",user=",6);
                strcat(options,user_name);
-       } 
+       }
+       if(retry == 0) {
+               if(domain_name) { 
+                       /* extra length accounted for in option string above */
+                       strncat(options,",domain=",8);
+                       strcat(options,domain_name);
+               }
+       }
        if(mountpassword) {
+               /* Commas have to be doubled, or else they will
+               look like the parameter separator */
+/*             if(sep is not set)*/
+               if(retry == 0)
+                       check_for_comma(&mountpassword);
                strncat(options,",pass=",6);
                strcat(options,mountpassword);
        }
+
        strncat(options,",ver=",5);
        strcat(options,MOUNT_CIFS_VERSION_MAJOR);
 
@@ -978,7 +1123,8 @@ mount_retry:
                }
        }
        if(mountpassword) {
-               memset(mountpassword,0,64);
+               int len = strlen(mountpassword);
+               memset(mountpassword,0,len);
                free(mountpassword);
        }
 
index 5df6bfe407e57035ed9dc42bf412902678e9d7bd..aeb4c91b19c5dc56a4812538cb2a97c54edfe2dd 100644 (file)
@@ -148,12 +148,12 @@ static int                smb_print(struct cli_state *, char *, FILE *);
     if ((password = strchr_m(username, ':')) != NULL)
       *password++ = '\0';
     else
-      password = "";
+      password = CONST_DISCARD(char *, "");
   }
   else
   {
     username = "";
-    password = "";
+    password = CONST_DISCARD(char *, "");
     server   = uri + 6;
   }
 
diff --git a/source/client/umount.cifs.c b/source/client/umount.cifs.c
new file mode 100644 (file)
index 0000000..6e330a4
--- /dev/null
@@ -0,0 +1,287 @@
+/* 
+   Unmount utility program for Linux CIFS VFS (virtual filesystem) client
+   Copyright (C) 2005 Steve French  (sfrench@us.ibm.com)
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <errno.h>
+#include <string.h>
+#include <mntent.h>
+
+#define UNMOUNT_CIFS_VERSION_MAJOR "0"
+#define UNMOUNT_CIFS_VERSION_MINOR "2"
+
+#ifndef UNMOUNT_CIFS_VENDOR_SUFFIX
+#define UNMOUNT_CIFS_VENDOR_SUFFIX ""
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH 0x02
+#endif
+
+#ifndef MNT_EXPIRE
+#define MNT_EXPIRE 0x04
+#endif
+
+#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
+#define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDU */
+   
+static struct option longopts[] = {
+       { "all", 0, NULL, 'a' },
+       { "help",0, NULL, 'h' },
+       { "read-only", 0, NULL, 'r' },
+       { "ro", 0, NULL, 'r' },
+       { "verbose", 0, NULL, 'v' },
+       { "version", 0, NULL, 'V' },
+       { "expire", 0, NULL, 'e' },
+       { "force", 0, 0, 'f' },
+       { "lazy", 0, 0, 'l' },
+       { "no-mtab", 0, 0, 'n' },
+       { NULL, 0, NULL, 0 }
+};
+
+char * thisprogram;
+int verboseflg = 0;
+
+static void umount_cifs_usage(void)
+{
+       printf("\nUsage:  %s <remotetarget> <dir>\n", thisprogram);
+       printf("\nUnmount the specified directory\n");
+       printf("\nLess commonly used options:");
+       printf("\n\t-r\tIf mount fails, retry with readonly remount.");
+       printf("\n\t-n\tDo not write to mtab.");
+       printf("\n\t-f\tAttempt a forced unmount, even if the fs is busy.");
+       printf("\n\t-l\tAttempt lazy unmount, Unmount now, cleanup later.");
+       printf("\n\t-v\tEnable verbose mode (may be useful for debugging).");
+       printf("\n\t-h\tDisplay this help.");
+       printf("\n\nOptions are described in more detail in the manual page");
+       printf("\n\tman 8 umount.cifs\n");
+       printf("\nTo display the version number of the cifs umount utility:");
+       printf("\n\t%s -V\n",thisprogram);
+}
+
+static int umount_check_perm(char * dir)
+{
+       int fileid;
+       int rc;
+
+       /* presumably can not chdir into the target as we do on mount */
+
+       fileid = open(dir, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, 0);
+       if(fileid == -1) {
+               if(verboseflg)
+                       printf("error opening mountpoint %d %s",errno,strerror(errno));
+               return errno;
+       }
+
+       rc = ioctl(fileid, CIFS_IOC_CHECKUMOUNT, NULL);
+
+       if(verboseflg)
+               printf("ioctl returned %d with errno %d %s\n",rc,errno,strerror(errno));
+
+       if(rc == ENOTTY)
+               printf("user unmounting via %s is an optional feature of the cifs filesystem driver (cifs.ko)\n\tand requires cifs.ko version 1.32 or later\n",thisprogram);
+       else if (rc > 0)
+               printf("user unmount of %s failed with %d %s\n",dir,errno,strerror(errno));
+       close(fileid);
+
+       return rc;
+}
+
+int main(int argc, char ** argv)
+{
+       int c;
+       int rc;
+       int flags = 0;
+       int nomtab = 0;
+       int retry_remount = 0;
+       struct mntent mountent;
+       struct statfs statbuf;
+       char * mountpoint;
+       FILE * pmntfile;
+
+       if(argc && argv) {
+               thisprogram = argv[0];
+       } else {
+               umount_cifs_usage();
+               return -EINVAL;
+       }
+
+       if(argc < 2) {
+               umount_cifs_usage();
+               return -EINVAL;
+       }
+
+       if(thisprogram == NULL)
+               thisprogram = "umount.cifs";
+
+       /* add sharename in opts string as unc= parm */
+
+       while ((c = getopt_long (argc, argv, "afhilnrvV",
+                        longopts, NULL)) != -1) {
+               switch (c) {
+/* No code to do the following  option yet */
+/*             case 'a':              
+                       ++umount_all;
+                       break; */
+               case '?':
+               case 'h':   /* help */
+                       umount_cifs_usage();
+                       exit(1);
+               case 'n':
+                       ++nomtab;
+                       break;
+               case 'f':
+                       flags |= MNT_FORCE;
+                       break;
+               case 'l':
+                       flags |= MNT_DETACH; /* lazy unmount */
+                       break;
+               case 'e':
+                       flags |= MNT_EXPIRE; /* gradually timeout */
+                       break;
+               case 'r':
+                       ++retry_remount;
+                       break;
+               case 'v':
+                       ++verboseflg;
+                       break;
+               case 'V':          
+                       printf ("umount.cifs version: %s.%s%s\n",
+                               UNMOUNT_CIFS_VERSION_MAJOR,
+                               UNMOUNT_CIFS_VERSION_MINOR,
+                               UNMOUNT_CIFS_VENDOR_SUFFIX);
+                       exit (0);
+               default:
+                       printf("unknown unmount option %c\n",c);
+                       umount_cifs_usage();
+                       exit(1);
+               }
+       }
+
+       /* move past the umount options */
+       argv += optind;
+       argc -= optind;
+
+       mountpoint = argv[0];
+
+       if((argc < 1) || (argv[0] == NULL)) {
+               printf("\nMissing name of unmount directory\n");
+               umount_cifs_usage();
+               return -EINVAL;
+       }
+
+       if(verboseflg)
+               printf("optind %d unmount dir %s\n",optind, mountpoint);
+
+       /* check if running effectively root */
+       if(geteuid() != 0) {
+               printf("Trying to unmount when %s not installed suid\n",thisprogram);
+               if(verboseflg)
+                       printf("euid = %d\n",geteuid());
+               return -EACCES;
+       }
+
+       /* fixup path if needed */
+
+       /* make sure that this is a cifs filesystem */
+       rc = statfs(mountpoint, &statbuf);
+       
+       if(rc || (statbuf.f_type != CIFS_MAGIC_NUMBER)) {
+               printf("Wrong filesystem. This utility only unmounts cifs filesystems.\n");
+               return -EINVAL;
+       }
+
+       /* check if our uid was the one who mounted */
+       rc = umount_check_perm(mountpoint);
+       if (rc) {
+               printf("Not permitted to unmount\n");
+               return rc;
+       }
+
+       if(umount2(mountpoint, flags)) {
+       /* remember to kill daemon on error */
+               switch (errno) {
+               case 0:
+                       printf("unmount failed but no error number set\n");
+                       break;
+               default:
+                       printf("unmount error %d = %s\n",errno,strerror(errno));
+               }
+               printf("Refer to the umount.cifs(8) manual page (e.g.man 8 umount.cifs)\n");
+               return -1;
+       } else {
+               pmntfile = setmntent(MOUNTED, "a+");
+               if(pmntfile) {
+/*                     mountent.mnt_fsname = share_name;
+                       mountent.mnt_dir = mountpoint; 
+                       mountent.mnt_type = "cifs"; 
+                       mountent.mnt_opts = malloc(220);
+                       if(mountent.mnt_opts) {
+                               char * mount_user = getusername();
+                               memset(mountent.mnt_opts,0,200);
+                               if(flags & MS_RDONLY)
+                                       strcat(mountent.mnt_opts,"ro");
+                               else
+                                       strcat(mountent.mnt_opts,"rw");
+                               if(flags & MS_MANDLOCK)
+                                       strcat(mountent.mnt_opts,",mand");
+                               else
+                                       strcat(mountent.mnt_opts,",nomand");
+                               if(flags & MS_NOEXEC)
+                                       strcat(mountent.mnt_opts,",noexec");
+                               if(flags & MS_NOSUID)
+                                       strcat(mountent.mnt_opts,",nosuid");
+                               if(flags & MS_NODEV)
+                                       strcat(mountent.mnt_opts,",nodev");
+                               if(flags & MS_SYNCHRONOUS)
+                                       strcat(mountent.mnt_opts,",synch");
+                               if(mount_user) {
+                                       if(getuid() != 0) {
+                                               strcat(mountent.mnt_opts,",user=");
+                                               strcat(mountent.mnt_opts,mount_user);
+                                       }
+                                       free(mount_user);
+                               }
+                       }
+                       mountent.mnt_freq = 0;
+                       mountent.mnt_passno = 0;
+                       rc = addmntent(pmntfile,&mountent);
+                       endmntent(pmntfile);
+                       if(mountent.mnt_opts)
+                               free(mountent.mnt_opts);*/
+               } else {
+                   printf("could not update mount table\n");
+               }
+       }
+
+       return 0;
+}
+
index f81d7fbb17d934bd5483ac8562d1a24964e2f16f..d4021283934227dcf60b3fb46c2b4b717ed5b6e4 100644 (file)
@@ -225,6 +225,8 @@ AC_SUBST(KRB5_LIBS)
 AC_SUBST(LDAP_LIBS)
 AC_SUBST(SHLIB_PROGS)
 AC_SUBST(SMBWRAPPER)
+AC_SUBST(SMBWRAP_OBJS)
+AC_SUBST(SMBWRAP_INC)
 AC_SUBST(EXTRA_BIN_PROGS)
 AC_SUBST(EXTRA_SBIN_PROGS)
 AC_SUBST(EXTRA_ALL_TARGETS)
@@ -248,7 +250,7 @@ fi
 AC_ARG_ENABLE(developer, [  --enable-developer      Turn on developer warnings and debugging (default=no)],
     [if eval "test x$enable_developer = xyes"; then
         developer=yes
-       CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+       CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
        # Add -Wdeclaration-after-statement if compiler supports it
        AC_CACHE_CHECK(
           [that the C compiler understands -Wdeclaration-after-statement],
@@ -416,7 +418,7 @@ DYNEXP=
 
 dnl Add modules that have to be built by default here
 dnl These have to be built static:
-default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
+default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin printerdb_file"
 
 dnl These are preferably build shared, and static if dlopen() is not available
 default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437"
@@ -691,8 +693,10 @@ AC_HEADER_TIME
 AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
 AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h)
-AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
-AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h)
+AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
+## These fail to compile on IRIX so just check for their presence
+AC_CHECK_HEADERS(rpcsvc/yp_prot.h, sys/mode.h, [], [] -)
+AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h)
 AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
 AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
 AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
@@ -727,8 +731,10 @@ AC_CHECK_HEADERS(shadow.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
 AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h)
 AC_CHECK_HEADERS(stropts.h poll.h)
 AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/cdefs.h glob.h)
-# These faile to compile on Solaris so just check for their presence
+AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h)
+AC_CHECK_HEADERS(sys/cdefs.h glob.h)
+
+## These faile to compile on Solaris so just check for their presence
 AC_CHECK_HEADERS(security/pam_modules.h net/if.h netinet/ip.h, [], [], -)
 
 # For experimental utmp support (lastlog on some BSD-like systems)
@@ -1162,6 +1168,18 @@ AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
 AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
 AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
 AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
+# Check if we have extattr
+case "$host_os" in
+  *freebsd4* | *DragonFly* )
+    AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work])
+    ;;
+  *)
+    AC_CHECK_FUNCS(extattr_delete_fd extattr_delete_file extattr_delete_link)
+    AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_get_link)
+    AC_CHECK_FUNCS(extattr_list_fd extattr_list_file extattr_list_link)
+    AC_CHECK_FUNCS(extattr_set_fd extattr_set_file extattr_set_link)
+    ;;
+esac
 
 # Assume non-shared by default and override below
 BLDSHARED="false"
@@ -1177,7 +1195,7 @@ SHLIBEXT="so"
 
 if test "$enable_shared" = "yes"; then
   # this bit needs to be modified for each OS that is suported by
-  # smbwrapper. You need to specify how to created a shared library and
+  # smbwrapper. You need to specify how to create a shared library and
   # how to compile C code to produce PIC object files
 
   AC_MSG_CHECKING([ability to build shared libraries])
@@ -2078,7 +2096,7 @@ fi
 
 AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt  -I${srcdir-.}/smbwrapper"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt"
 AC_TRY_COMPILE([
 #define REPLACE_GETPASS 1
 #define NO_PROTO_H 1
@@ -2394,6 +2412,8 @@ AC_ARG_WITH(smbwrapper,
     AC_DEFINE(WITH_SMBWRAPPER,1,[Whether to include smbwrapper support])
        WRAPPROG="bin/smbsh\$(EXEEXT)"
        WRAP="bin/smbwrapper.$SHLIBEXT"
+       WRAP_OBJS="\$(SMBW_OBJ1) \$(SMBWRAPPER_OBJ1)"
+       WRAP_INC="-I\$(srcdir)/smbwrapper"
 
 # Conditions under which smbwrapper should not be built.
 
@@ -2401,13 +2421,19 @@ AC_ARG_WITH(smbwrapper,
           echo No support for PIC code - disabling smbwrapper and smbsh
           WRAPPROG=""
           WRAP=""
+          WRAP_OBJS=""
+          WRAP_INC=""
        elif test x$ac_cv_func_syscall = xno; then
           AC_MSG_RESULT([No syscall() -- disabling smbwrapper and smbsh])
           WRAPPROG=""
           WRAP=""
+          WRAP_OBJS=""
+          WRAP_INC=""
        fi
        EXTRA_ALL_TARGETS="$EXTRA_ALL_TARGETS $WRAPPROG $WRAP"
        SMBWRAPPER="$WRAPPROG $WRAP"
+       SMBWRAP_OBJS="$WRAP_OBJS"
+       SMBWRAP_INC="$WRAP_INC"
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -3523,7 +3549,7 @@ fi
 if test x"$samba_cv_SYSQUOTA_FOUND" != x"no"; then
 AC_CACHE_CHECK([whether the sys_quota interface works],samba_cv_SYSQUOTA_WORKS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt  -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/nsswitch"
 AC_TRY_COMPILE([
 #include "confdefs.h"
 #define NO_PROTO_H 1
@@ -3550,7 +3576,7 @@ fi
 if test x"$samba_cv_SYSQUOTA_FOUND" != x"no" -a x"$samba_cv_found_xfs_header" = x"yes"; then
 AC_CACHE_CHECK([whether the sys_quota interface works with XFS],samba_cv_SYSQUOTA_WORKS_XFS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt  -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/nsswitch"
 AC_TRY_COMPILE([
 #include "confdefs.h"
 #define NO_PROTO_H 1
@@ -3570,7 +3596,7 @@ fi
 
 AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt  -I${srcdir-.}/smbwrapper -I${srcdir-.}/nsswitch"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/nsswitch"
 AC_TRY_COMPILE([
 #include "confdefs.h"
 #define NO_PROTO_H 1
@@ -3631,30 +3657,6 @@ else
         AC_MSG_RESULT(no$utmp_no_reason)
 fi
 
-#################################################
-# choose native language(s) of man pages
-AC_MSG_CHECKING(chosen man pages' language(s))
-AC_ARG_WITH(manpages-langs,
-[  --with-manpages-langs={en,ja,pl}  Choose man pages' language(s). (en)],
-[ case "$withval" in
-  yes|no)
-    AC_MSG_WARN(--with-manpages-langs called without argument - will use default)
-    manlangs="en"
-  ;;
-  *)
-    manlangs="$withval"
-  ;;
-  esac
-
-  AC_MSG_RESULT($manlangs)
-  manlangs=`echo $manlangs | sed "s/,/ /g"`   # replacing commas with spaces to produce a list
-  AC_SUBST(manlangs)],
-
-  [manlangs="en"
-  AC_MSG_RESULT($manlangs)
-  AC_SUBST(manlangs)]
-)
-
 #################################################
 # should we build libsmbclient?
 
@@ -4555,10 +4557,12 @@ SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_svcctl, \$(RPC_SVCCTL_OBJ), "bin/librpc_svcctl.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_eventlog, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
 SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
 SMB_SUBSYSTEM(RPC,smbd/server.o)
@@ -4595,6 +4599,7 @@ SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_catia, \$(VFS_AFSACL_OBJ), "bin/catia.$SHLIBEXT", VFS)
 SMB_SUBSYSTEM(VFS,smbd/vfs.o)
 
 AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
index 5613240a12162bbe66990662549d54a57ba9a6fc..459c66bdf79be9d72055e1850a61eecd99225ac3 100644 (file)
@@ -518,7 +518,7 @@ static NTSTATUS one_alias_membership(const DOM_SID *member,
                if (!string_to_sid(&alias, string_sid))
                        continue;
 
-               add_sid_to_array_unique(&alias, sids, num);
+               add_sid_to_array_unique(NULL, &alias, sids, num);
 
                if (sids == NULL)
                        return NT_STATUS_NO_MEMORY;
@@ -665,7 +665,7 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
                if (!string_to_sid(&member, member_string))
                        continue;
                
-               add_sid_to_array(&member, closure->sids, closure->num);
+               add_sid_to_array(NULL, &member, closure->sids, closure->num);
        }
 
        return 0;
@@ -1247,55 +1247,6 @@ NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
                NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
 }
 
-NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
-                                 const DOM_SID *sid,
-                                 uint32 start_idx, uint32 max_entries,
-                                 uint32 *num_aliases,
-                                 struct acct_info **info)
-{
-       extern DOM_SID global_sid_Builtin;
-
-       GROUP_MAP *map;
-       int i, num_maps;
-       enum SID_NAME_USE type = SID_NAME_UNKNOWN;
-
-       if (sid_compare(sid, get_global_sam_sid()) == 0)
-               type = SID_NAME_ALIAS;
-
-       if (sid_compare(sid, &global_sid_Builtin) == 0)
-               type = SID_NAME_WKN_GRP;
-
-       if (!pdb_enum_group_mapping(type, &map, &num_maps, False) ||
-           (num_maps == 0)) {
-               *num_aliases = 0;
-               *info = NULL;
-               goto done;
-       }
-
-       if (start_idx > num_maps) {
-               *num_aliases = 0;
-               *info = NULL;
-               goto done;
-       }
-
-       *num_aliases = num_maps - start_idx;
-
-       if (*num_aliases > max_entries)
-               *num_aliases = max_entries;
-
-       *info = SMB_MALLOC_ARRAY(struct acct_info, *num_aliases);
-
-       for (i=0; i<*num_aliases; i++) {
-               fstrcpy((*info)[i].acct_name, map[i+start_idx].nt_name);
-               fstrcpy((*info)[i].acct_desc, map[i+start_idx].comment);
-               sid_peek_rid(&map[i].sid, &(*info)[i+start_idx].rid);
-       }
-
- done:
-       SAFE_FREE(map);
-       return NT_STATUS_OK;
-}
-
 NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,
                                   const DOM_SID *sid,
                                   struct acct_info *info)
@@ -1348,11 +1299,42 @@ NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
 }
 
 NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
+                                      TALLOC_CTX *mem_ctx,
+                                      const DOM_SID *domain_sid,
                                       const DOM_SID *members,
                                       int num_members,
-                                      DOM_SID **aliases, int *num)
+                                      uint32 **alias_rids,
+                                      int *num_alias_rids)
 {
-       return alias_memberships(members, num_members, aliases, num);
+       DOM_SID *alias_sids;
+       int i, num_alias_sids;
+       NTSTATUS result;
+
+       alias_sids = NULL;
+       num_alias_sids = 0;
+
+       result = alias_memberships(members, num_members,
+                                  &alias_sids, &num_alias_sids);
+
+       if (!NT_STATUS_IS_OK(result))
+               return result;
+
+       *alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
+       if ((alias_sids != 0) && (*alias_rids == NULL))
+               return NT_STATUS_NO_MEMORY;
+
+       *num_alias_rids = 0;
+
+       for (i=0; i<num_alias_sids; i++) {
+               if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
+                                       &(*alias_rids)[*num_alias_rids]))
+                       continue;
+               *num_alias_rids += 1;
+       }
+
+       SAFE_FREE(alias_sids);
+
+       return NT_STATUS_OK;
 }
 
 /**********************************************************************
index c6d6b1fac90c982795893b07bf558fb03bd3fa38..60a3c335ec4046e7cc2628394f3b28a323cd0511 100644 (file)
 #define WERR_INVALID_OWNER W_ERROR(1307)
 #define WERR_IO_PENDING W_ERROR(997)
 #define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
+#define WERR_NO_SUCH_SERVICE W_ERROR(1060)
+#define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052)
 #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
 #define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
 #define WERR_INVALID_FORM_NAME W_ERROR(1902)
index 982eee1886273ddfc5312a0086a2068f1f21f3f1..a6db058708d532d61bffe7bf4e08e0c85f22ba66 100644 (file)
 #include <sys/xattr.h>
 #endif
 
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
 #if HAVE_LOCALE_H
 #include <locale.h>
 #endif
@@ -856,7 +864,9 @@ extern int errno;
 
 #include "client.h"
 
+#ifdef WITH_SMBWRAPPER
 #include "smbw.h"
+#endif
 
 #include "session.h"
 
@@ -1372,4 +1382,7 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to);
 #undef HAVE_MMAP
 #endif
 
+#define CONST_DISCARD(type, ptr)      ((type) ((void *) (ptr)))
+#define CONST_ADD(type, ptr)          ((type) ((const void *) (ptr)))
+
 #endif /* _INCLUDES_H */
index a1db5c27926aa46dfd7b3f08747f6a3147847bd3..2eca879cbe2a03f76bc8ceba98d1c98228fbd2e9 100644 (file)
@@ -35,7 +35,7 @@ struct smbc_dir_list {
 struct _SMBCFILE {
        int cli_fd; 
        char *fname;
-       off_t offset;
+       SMB_OFF_T offset;
        struct _SMBCSRV *srv;
        BOOL file;
        struct smbc_dir_list *dir_list, *dir_end, *dir_next;
index 636083b41d4ffaeedbad8f811402027601ccd14e..ea013c113a0ca86c2ebefbdb31268ba6e18e6906 100644 (file)
 #ifndef SMBCLIENT_H_INCLUDED
 #define SMBCLIENT_H_INCLUDED
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*-------------------------------------------------------------------*/
 /* The following are special comments to instruct DOXYGEN (automated 
  * documentation tool:
@@ -550,13 +554,7 @@ struct _SMBCCTX {
  *
  * @note            Do not forget to smbc_init_context() the returned SMBCCTX pointer !
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 SMBCCTX * smbc_new_context(void);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup misc
  * Delete a SBMCCTX (a context) acquired from smbc_new_context().
@@ -579,13 +577,8 @@ SMBCCTX * smbc_new_context(void);
  *                  just before exit()'ing. When shutdown_ctx is 0, this function can be
  *                  use in periodical cleanup functions for example.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup misc
  * Initialize a SBMCCTX (a context).
@@ -605,13 +598,8 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
  *                  but it might leak memory on smbc_context_init() failure. Avoid this.
  *                  You'll have to call smbc_free_context() yourself on failure.  
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
+
 SMBCCTX * smbc_init_context(SMBCCTX * context);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup misc
  * Initialize the samba client library.
@@ -631,13 +619,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context);
  *
  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_init(smbc_get_auth_data_fn fn, int debug);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup misc
  * Set or retrieve the compatibility library's context pointer
@@ -661,13 +643,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug);
  *                  authentication functions have been freed, if necessary.
  */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 SMBCCTX * smbc_set_context(SMBCCTX * new_context);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup file
  * Open a file on an SMB server.
@@ -720,13 +696,8 @@ SMBCCTX * smbc_set_context(SMBCCTX * new_context);
  *                  try again with an empty username and password. This 
  *                  often gets mapped to the guest account on some machines.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
+
 int smbc_open(const char *furl, int flags, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup file
  * Create a file on an SMB server.
@@ -759,13 +730,8 @@ int smbc_open(const char *furl, int flags, mode_t mode);
  * @see             smbc_open()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
+
 int smbc_creat(const char *furl, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup file
  * Read from a file using an opened file handle.
@@ -787,13 +753,8 @@ int smbc_creat(const char *furl, mode_t mode);
  * @see             smbc_open(), smbc_write()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 ssize_t smbc_read(int fd, void *buf, size_t bufsize);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup file
  * Write to a file using an opened file handle.
@@ -815,13 +776,8 @@ ssize_t smbc_read(int fd, void *buf, size_t bufsize);
  * @see             smbc_open(), smbc_read()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 ssize_t smbc_write(int fd, void *buf, size_t bufsize);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup file
  * Seek to a specific location in a file.
@@ -851,13 +807,8 @@ ssize_t smbc_write(int fd, void *buf, size_t bufsize);
  * 
  * @todo Are errno values complete and correct?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 off_t smbc_lseek(int fd, off_t offset, int whence);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup file
  * Close an open file handle.
@@ -870,13 +821,8 @@ off_t smbc_lseek(int fd, off_t offset, int whence);
  *
  * @see             smbc_open(), smbc_creat()
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_close(int fd);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Unlink (delete) a file or directory.
@@ -899,13 +845,8 @@ int smbc_close(int fd);
  *
  * @todo Are errno values complete and correct?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_unlink(const char *furl);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Rename or move a file or directory.
@@ -947,13 +888,8 @@ int smbc_unlink(const char *furl);
  *       share?  I say no... NOTE. I agree for the moment.
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_rename(const char *ourl, const char *nurl);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Open a directory used to obtain directory entries.
@@ -975,13 +911,8 @@ int smbc_rename(const char *ourl, const char *nurl);
  * @see             smbc_getdents(), smbc_readdir(), smbc_closedir()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_opendir(const char *durl);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Close a directory handle opened by smbc_opendir().
@@ -993,13 +924,8 @@ int smbc_opendir(const char *durl);
  *
  * @see             smbc_opendir()
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_closedir(int dh);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Get multiple directory entries.
@@ -1027,13 +953,8 @@ int smbc_closedir(int dh);
  *
  * @todo Add example code so people know how to parse buffers.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Get a single directory entry.
@@ -1047,13 +968,8 @@ int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
  *
  * @see             smbc_dirent, smbc_getdents(), smbc_open()
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 struct smbc_dirent* smbc_readdir(unsigned int dh);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Get the current directory offset.
@@ -1075,13 +991,8 @@ struct smbc_dirent* smbc_readdir(unsigned int dh);
  * @see             smbc_readdir()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 off_t smbc_telldir(int dh);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * lseek on directories.
@@ -1105,13 +1016,7 @@ off_t smbc_telldir(int dh);
  *
  * @todo In what does the reture and errno values mean?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_lseekdir(int fd, off_t offset);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup directory
  * Create a directory.
@@ -1134,13 +1039,8 @@ int smbc_lseekdir(int fd, off_t offset);
  * @see             smbc_rmdir()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_mkdir(const char *durl, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup directory
  * Remove a directory.
@@ -1160,13 +1060,8 @@ int smbc_mkdir(const char *durl, mode_t mode);
  *
  * @todo Are errno values complete and correct?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_rmdir(const char *durl);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Get information about a file or directory.
@@ -1187,13 +1082,8 @@ int smbc_rmdir(const char *durl);
  * @see             Unix stat()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_stat(const char *url, struct stat *st);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Get file information via an file descriptor.
@@ -1213,13 +1103,8 @@ int smbc_stat(const char *url, struct stat *st);
  * @see             smbc_stat(), Unix stat()
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_fstat(int fd, struct stat *st);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribue
  * Change the ownership of a file or directory.
@@ -1244,13 +1129,8 @@ int smbc_fstat(int fd, struct stat *st);
  * @todo How do we abstract owner and group uid and gid?
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_chown(const char *url, uid_t owner, gid_t group);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Change the permissions of a file.
@@ -1272,13 +1152,7 @@ int smbc_chown(const char *url, uid_t owner, gid_t group);
  *
  * @todo Are errno values complete and correct?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_chmod(const char *url, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup attribute
  * Change the last modification time on a file
@@ -1295,13 +1169,7 @@ int smbc_chmod(const char *url, mode_t mode);
  *                  - EPERM  Permission was denied.
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_utimes(const char *url, struct timeval *tbuf);
-#ifdef __cplusplus
-}
-#endif
 
 #ifdef HAVE_UTIME_H
 /**@ingroup attribute
@@ -1320,13 +1188,7 @@ int smbc_utimes(const char *url, struct timeval *tbuf);
  *                  - EPERM  Permission was denied.
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_utime(const char *fname, struct utimbuf *utbuf);
-#ifdef __cplusplus
-}
-#endif
 #endif
 
 /**@ingroup attribute
@@ -1428,17 +1290,12 @@ int smbc_utime(const char *fname, struct utimbuf *utbuf);
  *                    sYsTeM.nt_sEc_desc.owNER
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_setxattr(const char *url,
                   const char *name,
                   const void *value,
                   size_t size,
                   int flags);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Set extended attributes for a file.  This is used for modifying a file's
@@ -1543,17 +1400,12 @@ int smbc_setxattr(const char *url,
  *                    sYsTeM.nt_sEc_desc.owNER
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_lsetxattr(const char *url,
                    const char *name,
                    const void *value,
                    size_t size,
                    int flags);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Set extended attributes for a file.  This is used for modifying a file's
@@ -1655,17 +1507,12 @@ int smbc_lsetxattr(const char *url,
  *                    sYsTeM.nt_sEc_desc.owNER
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_fsetxattr(int fd,
                    const char *name,
                    const void *value,
                    size_t size,
                    int flags);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Get extended attributes for a file.
@@ -1723,16 +1570,11 @@ int smbc_fsetxattr(int fd,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_getxattr(const char *url,
                   const char *name,
                   const void *value,
                   size_t size);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Get extended attributes for a file.  The POSIX function which this maps to
@@ -1793,16 +1635,11 @@ int smbc_getxattr(const char *url,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_lgetxattr(const char *url,
                    const char *name,
                    const void *value,
                    size_t size);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Get extended attributes for a file.
@@ -1861,16 +1698,11 @@ int smbc_lgetxattr(const char *url,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_fgetxattr(int fd,
                    const char *name,
                    const void *value,
                    size_t size);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Remove extended attributes for a file.  This is used for modifying a file's
@@ -1915,14 +1747,9 @@ int smbc_fgetxattr(int fd,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_removexattr(const char *url,
                      const char *name);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Remove extended attributes for a file.  This is used for modifying a file's
@@ -1970,14 +1797,9 @@ int smbc_removexattr(const char *url,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_lremovexattr(const char *url,
                       const char *name);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * Remove extended attributes for a file.  This is used for modifying a file's
@@ -2023,14 +1845,9 @@ int smbc_lremovexattr(const char *url,
  *                            extended attributes
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_fremovexattr(int fd,
                       const char *name);
-#ifdef __cplusplus
-}
-#endif
+
 
 /**@ingroup attribute
  * List the supported extended attribute names associated with a file
@@ -2062,15 +1879,9 @@ int smbc_fremovexattr(int fd,
  *                  extended attributes at all.  Whether this is a feature or
  *                  a bug is yet to be decided.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_listxattr(const char *url,
                    char *list,
                    size_t size);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup attribute
  * List the supported extended attribute names associated with a file The
@@ -2106,15 +1917,9 @@ int smbc_listxattr(const char *url,
  *                  extended attributes at all.  Whether this is a feature or
  *                  a bug is yet to be decided.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_llistxattr(const char *url,
                     char *list,
                     size_t size);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup attribute
  * List the supported extended attribute names associated with a file
@@ -2147,15 +1952,9 @@ int smbc_llistxattr(const char *url,
  *                  extended attributes at all.  Whether this is a feature or
  *                  a bug is yet to be decided.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_flistxattr(int fd,
                     char *list,
                     size_t size);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup print
  * Print a file given the name in fname. It would be a URL ...
@@ -2172,13 +1971,7 @@ int smbc_flistxattr(int fd,
  *                  and errors returned by smbc_open
  *
  */                                     
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_print_file(const char *fname, const char *printq);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup print
  * Open a print file that can be written to by other calls. This simply
@@ -2193,13 +1986,7 @@ int smbc_print_file(const char *fname, const char *printq);
  *                  - all errors returned by smbc_open
  *
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_open_print_job(const char *fname);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup print
  * List the print jobs on a print share, for the moment, pass a callback 
@@ -2212,13 +1999,7 @@ int smbc_open_print_job(const char *fname);
  *                  - EINVAL fname was NULL or smbc_init not called
  *                  - EACCES ???
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup print
  * Delete a print job 
@@ -2232,13 +2013,7 @@ int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
  *
  * @todo    what errno values are possible here?
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_unlink_print_job(const char *purl, int id);
-#ifdef __cplusplus
-}
-#endif
 
 /**@ingroup callback
  * Remove a server from the cached server list it's unused.
@@ -2250,10 +2025,8 @@ int smbc_unlink_print_job(const char *purl, int id);
  * @return On success, 0 is returned. 1 is returned if the server could not
  *         be removed. Also useable outside libsmbclient.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
 int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv);
+
 #ifdef __cplusplus
 }
 #endif
index afbbe738fe1a8fbd41a1cd0e40086a46d0aa6fca..8d6b23bcbfb3f70fe2f65c3757c2f0209894f7ad 100644 (file)
@@ -68,18 +68,17 @@ struct dfs_path
 #define RESOLVE_DFSPATH(name, conn, inbuf, outbuf)             \
 { if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) &&         \
       lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&          \
-      dfs_redirect(name,conn,False))                           \
+      dfs_redirect(name, conn, False))                         \
              return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED,     \
                               ERRSRV, ERRbadpath);; }          
 
-#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf)           \
+#define RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf)        \
 { if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) &&         \
       lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&          \
-      dfs_redirect(name,conn,True))                            \
+      dfs_redirect(name,conn, True))                           \
              return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED,     \
                               ERRSRV, ERRbadpath);; }          
 
 #define init_dfsroot(conn, inbuf, outbuf)                      \
 { if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {          \
         DEBUG(2,("Serving %s as a Dfs root\n",                         \
index 9747f73eb18a465133e6d9854e56bc274813fe24..ab768258df17fbccf04ad58c4567b9a1a00e2d91 100644 (file)
@@ -56,6 +56,7 @@ typedef uint32 WERROR;
 
 #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0)
 #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000)
+#define NT_STATUS_IS_INVALID(x) (NT_STATUS_V(x) == 0xFFFFFFFF)
 #define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y))
 #define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0)
 #define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y))
index 45d64cf6331eabefd384e09dda685ba8d4344325..87fac492db39124aafff55692318f4b6eb4565fd 100644 (file)
@@ -391,13 +391,16 @@ typedef struct {
 #include "authdata.h"
 
 /* different dce/rpc pipes */
+#include "rpc_buffer.h"
 #include "rpc_lsa.h"
 #include "rpc_netlogon.h"
 #include "rpc_reg.h"
 #include "rpc_samr.h"
 #include "rpc_srvsvc.h"
 #include "rpc_wkssvc.h"
+#include "rpc_svcctl.h"
 #include "rpc_spoolss.h"
+#include "rpc_eventlog.h"
 #include "rpc_dfs.h"
 #include "rpc_ds.h"
 #include "rpc_echo.h"
index 6cf5a756d297ae4aa3a1e6062b1a2728fa4437ed..417719625e712d9f8af737a570197e7eb41ff815 100644 (file)
@@ -37,6 +37,9 @@
 #define STATUS_NOTIFY_ENUM_DIR            NT_STATUS(0x010c)
 #define ERROR_INVALID_DATATYPE           NT_STATUS(0x070c)
 
+/* Special "invalid" NT status code. */
+#define NT_STATUS_INVALID                NT_STATUS(0xFFFFFFFF)
+
 /* Win32 Error codes extracted using a loop in smbclient then printing a
    netmon sniff to a file. */
 
index 5a70bb45a8cc24265e761d6d0de32215eb4cbdfd..0c816271b02b1e41915703bb0ce5f443ec60a2d9 100644 (file)
@@ -232,6 +232,30 @@ struct acct_info
     uint32 rid; /* domain-relative RID */
 };
 
+struct samr_displayentry {
+       uint32 rid;
+       uint16 acct_flags;
+       const char *account_name;
+       const char *fullname;
+       const char *description;
+};
+
+enum pdb_search_type {
+       PDB_USER_SEARCH,
+       PDB_GROUP_SEARCH,
+       PDB_ALIAS_SEARCH
+};
+
+struct pdb_search {
+       TALLOC_CTX *mem_ctx;
+       enum pdb_search_type type;
+       struct samr_displayentry *cache;
+       uint32 num_entries;
+       ssize_t cache_size;
+       BOOL search_ended;
+       void *private;
+};
+
 /*****************************************************************
  Functions to be implemented by the new (v2) passdb API 
 ****************************************************************/
@@ -310,12 +334,6 @@ typedef struct pdb_context
        NTSTATUS (*pdb_delete_alias)(struct pdb_context *context,
                                     const DOM_SID *sid);
 
-       NTSTATUS (*pdb_enum_aliases)(struct pdb_context *context,
-                                    const DOM_SID *domain_sid,
-                                    uint32 start_idx, uint32 num_entries,
-                                    uint32 *num_aliases,
-                                    struct acct_info **aliases);
-
        NTSTATUS (*pdb_get_aliasinfo)(struct pdb_context *context,
                                      const DOM_SID *sid,
                                      struct acct_info *info);
@@ -337,10 +355,34 @@ typedef struct pdb_context
                                      DOM_SID **members, int *num_members);
 
        NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
+                                              TALLOC_CTX *mem_ctx,
+                                              const DOM_SID *domain_sid,
                                               const DOM_SID *members,
                                               int num_members,
-                                              DOM_SID **aliases,
-                                              int *num_aliases);
+                                              uint32 **alias_rids,
+                                              int *num_alias_rids);
+
+       NTSTATUS (*pdb_lookup_rids)(struct pdb_context *context,
+                                   TALLOC_CTX *mem_ctx,
+                                   const DOM_SID *domain_sid,
+                                   int num_rids,
+                                   uint32 *rids,
+                                   const char ***names,
+                                   uint32 **attrs);
+
+       BOOL (*pdb_search_users)(struct pdb_context *context,
+                                struct pdb_search *search,
+                                uint16 acct_flags);
+       BOOL (*pdb_search_groups)(struct pdb_context *context,
+                                 struct pdb_search *search);
+       BOOL (*pdb_search_aliases)(struct pdb_context *context,
+                                  struct pdb_search *search,
+                                  const DOM_SID *sid);
+       BOOL (*pdb_search_next_entry)(struct pdb_context *context,
+                                     struct pdb_search *search,
+                                     struct samr_displayentry *entry);
+       void (*pdb_search_end)(struct pdb_context *context,
+                              struct pdb_search *search);
 
        void (*free_fn)(struct pdb_context **);
        
@@ -416,11 +458,6 @@ typedef struct pdb_methods
        NTSTATUS (*delete_alias)(struct pdb_methods *methods,
                                 const DOM_SID *sid);
 
-       NTSTATUS (*enum_aliases)(struct pdb_methods *methods,
-                                const DOM_SID *domain_sid,
-                                uint32 start_idx, uint32 max_entries,
-                                uint32 *num_aliases, struct acct_info **info);
-
        NTSTATUS (*get_aliasinfo)(struct pdb_methods *methods,
                                  const DOM_SID *sid,
                                  struct acct_info *info);
@@ -437,9 +474,33 @@ typedef struct pdb_methods
                                  const DOM_SID *alias, DOM_SID **members,
                                  int *num_members);
        NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
+                                          TALLOC_CTX *mem_ctx,
+                                          const DOM_SID *domain_sid,
                                           const DOM_SID *members,
                                           int num_members,
-                                          DOM_SID **aliases, int *num);
+                                          uint32 **alias_rids,
+                                          int *num_alias_rids);
+       NTSTATUS (*lookup_rids)(struct pdb_methods *methods,
+                               TALLOC_CTX *mem_ctx,
+                               const DOM_SID *domain_sid,
+                               int num_rids,
+                               uint32 *rids,
+                               const char ***names,
+                               uint32 **attrs);
+
+       BOOL (*search_users)(struct pdb_methods *methods,
+                            struct pdb_search *search,
+                            uint16 acct_flags);
+       BOOL (*search_groups)(struct pdb_methods *methods,
+                             struct pdb_search *search);
+       BOOL (*search_aliases)(struct pdb_methods *methods,
+                              struct pdb_search *search,
+                              const DOM_SID *sid);
+       BOOL (*search_next_entry)(struct pdb_methods *methods,
+                                 struct pdb_search *search,
+                                 struct samr_displayentry *entry);
+       void (*search_end)(struct pdb_methods *methods,
+                          struct pdb_search *search);
 
        void *private_data;  /* Private data of some kind */
        
diff --git a/source/include/rpc_buffer.h b/source/include/rpc_buffer.h
new file mode 100644 (file)
index 0000000..da2be8a
--- /dev/null
@@ -0,0 +1,35 @@
+/* 
+   Unix SMB/Netbios implementation.
+
+   Copyright (C) Andrew Tridgell              1992-2000,
+   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+   Copyright (C) Jean Francois Micouleau      1998-2000.
+   Copyright (C) Gerald Carter                2001-2005.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_BUFFER_H          /* _RPC_SPOOLSS_H */
+#define _RPC_BUFFER_H
+
+typedef struct {
+       uint32 size;
+       prs_struct prs;
+       uint32 struct_start;
+       uint32 string_at_end;
+} RPC_BUFFER;
+
+
+#endif         /* _RPC_BUFFER_H */
index bce9ec7f2739508c259bdcdc2399feb4eda147f2..4ac2f43ee00a5424db87d7cd4765d2b19a9fbc69 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    SMB parameters and setup
-   Copyright (C) Elrond                            2000
+   Copyright (C) Gerald (Jerry) Carter         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
 #ifndef _RPC_CLIENT_H
 #define _RPC_CLIENT_H
 
-#if 0  /* JERRY */
-#include "rpc_client_proto.h"
-#endif 
+/* macro to expand cookie-cutter code in cli_xxx() */
+                  
+#define CLI_DO_RPC( pcli, ctx, pipe_num, opnum, q_in, r_out, q_ps, r_ps, q_io_fn, r_io_fn, default_error) \
+{      r_out.status = default_error;\
+       prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
+       prs_init( &r_ps, 0, ctx, UNMARSHALL );\
+       if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
+               if ( rpc_api_pipe_req(pcli, pipe_num, opnum, &q_ps, &r_ps) ) {\
+                       if (!r_io_fn("", &r_out, &r_ps, 0)) {\
+                               r_out.status = default_error;\
+                       }\
+               }\
+       }\
+       prs_mem_free( &q_ps );\
+       prs_mem_free( &r_ps );\
+}
 
 #endif /* _RPC_CLIENT_H */
diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h
new file mode 100644 (file)
index 0000000..b692a76
--- /dev/null
@@ -0,0 +1,193 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _RPC_EVENTLOG_H                /* _RPC_EVENTLOG_H */
+#define _RPC_EVENTLOG_H
+
+/* opcodes */
+
+#define EVENTLOG_CLEAREVENTLOG         0x00
+#define EVENTLOG_CLOSEEVENTLOG         0x02
+#define EVENTLOG_GETNUMRECORDS         0x04
+#define EVENTLOG_GETOLDESTENTRY                0x05
+#define EVENTLOG_OPENEVENTLOG          0x07
+#define EVENTLOG_READEVENTLOG          0x0a
+
+/* Eventlog read flags */
+
+#define EVENTLOG_SEQUENTIAL_READ      0x0001
+#define EVENTLOG_SEEK_READ            0x0002
+#define EVENTLOG_FORWARDS_READ        0x0004
+#define EVENTLOG_BACKWARDS_READ       0x0008
+
+/* Event types */
+
+#define EVENTLOG_SUCCESS              0x0000
+#define EVENTLOG_ERROR_TYPE           0x0001
+#define EVENTLOG_WARNING_TYPE         0x0002
+#define EVENTLOG_INFORMATION_TYPE     0x0004
+#define EVENTLOG_AUDIT_SUCCESS        0x0008
+#define EVENTLOG_AUDIT_FAILURE        0x0010
+
+
+typedef struct eventlog_q_open_eventlog
+{
+       uint32 unknown1;
+       uint16 unknown2;
+       uint16 unknown3;
+       uint16 sourcename_length;
+       uint16 sourcename_size;
+       uint32 sourcename_ptr;
+       UNISTR2 sourcename;
+       uint32 servername_ptr;
+       UNISTR2 servername;
+}
+EVENTLOG_Q_OPEN_EVENTLOG;
+
+typedef struct eventlog_r_open_eventlog
+{
+       POLICY_HND handle;
+       WERROR status;
+}
+EVENTLOG_R_OPEN_EVENTLOG;
+
+typedef struct eventlog_q_close_eventlog
+{
+       POLICY_HND handle;
+}
+EVENTLOG_Q_CLOSE_EVENTLOG;
+
+typedef struct eventlog_r_close_eventlog
+{
+       POLICY_HND handle;
+       WERROR status;
+} 
+EVENTLOG_R_CLOSE_EVENTLOG;
+
+typedef struct eventlog_q_get_num_records
+{
+       POLICY_HND handle;
+} 
+EVENTLOG_Q_GET_NUM_RECORDS;
+
+typedef struct eventlog_r_get_num_records
+{
+       uint32 num_records;
+       WERROR status;
+}
+EVENTLOG_R_GET_NUM_RECORDS;
+
+typedef struct eventlog_q_get_oldest_entry
+{
+       POLICY_HND handle;
+}
+EVENTLOG_Q_GET_OLDEST_ENTRY;
+
+typedef struct eventlog_r_get_oldest_entry
+{
+       uint32 oldest_entry;
+       WERROR status;
+}
+EVENTLOG_R_GET_OLDEST_ENTRY;
+
+typedef struct eventlog_q_read_eventlog
+{
+       POLICY_HND handle;
+       uint32 flags;
+       uint32 offset;
+       uint32 max_read_size;
+}
+EVENTLOG_Q_READ_EVENTLOG;
+
+typedef struct eventlog_record
+{
+       uint32 length;
+       uint32 reserved1;
+       uint32 record_number;
+       uint32 time_generated;
+       uint32 time_written;
+       uint32 event_id;
+       uint16 event_type;
+       uint16 num_strings;
+       uint16 event_category;
+       uint16 reserved2;
+       uint32 closing_record_number;
+       uint32 string_offset;
+       uint32 user_sid_length;
+       uint32 user_sid_offset;
+       uint32 data_length;
+       uint32 data_offset;
+} Eventlog_record;
+
+typedef struct eventlog_data_record
+{
+       uint32 source_name_len;
+       wpstring source_name;
+       uint32 computer_name_len;
+       wpstring computer_name;
+       uint32 sid_padding;
+       wpstring sid;
+       uint32 strings_len;
+       wpstring strings;
+       uint32 user_data_len;
+       pstring user_data;
+       uint32 data_padding;
+} Eventlog_data_record;
+
+typedef struct eventlog_entry
+{
+       Eventlog_record record;
+       Eventlog_data_record data_record;
+       uint8 *data;
+       uint8 *end_of_data_padding;
+       struct eventlog_entry *next;
+} Eventlog_entry;
+typedef struct eventlog_r_read_eventlog
+{
+       uint32 num_bytes_in_resp;
+       uint32 bytes_in_next_record;
+       uint32 num_records;
+       Eventlog_entry *entry;
+       uint8 *end_of_entries_padding;
+       uint32 sent_size;
+       uint32 real_size;
+       WERROR status;
+}
+EVENTLOG_R_READ_EVENTLOG;
+
+typedef struct eventlog_q_clear_eventlog
+{
+       POLICY_HND handle;
+       uint32 unknown1;
+       uint16 backup_file_length;
+       uint16 backup_file_size;
+       uint32 backup_file_ptr;
+       UNISTR2 backup_file;
+}
+EVENTLOG_Q_CLEAR_EVENTLOG;
+
+typedef struct eventlog_r_clear_eventlog
+{
+       WERROR status;
+}
+EVENTLOG_R_CLEAR_EVENTLOG;
+
+#endif /* _RPC_EVENTLOG_H */
index a0d78280c20835f448b8d409692f27e9dfb98c62..8eaf68a234d6ae1cbce854cd3e88a598229f9384 100644 (file)
@@ -1,9 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
    SMB parameters and setup
-   Copyright (C) Andrew Tridgell 1992-1997
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
-   Copyright (C) Paul Ashton 1997
+   Copyright (C) Andrew Tridgell               1992-1997
+   Copyright (C) Luke Kenneth Casson Leighton  1996-1997
+   Copyright (C) Paul Ashton                   1997
+   Copyright (C) Gerald (Jerry) Carter         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
@@ -68,7 +69,7 @@
 #define LSA_LOOKUPPRIVNAME     0x20
 #define LSA_PRIV_GET_DISPNAME  0x21
 #define LSA_DELETEOBJECT       0x22
-#define LSA_ENUMACCTWITHRIGHT  0x23
+#define LSA_ENUMACCTWITHRIGHT  0x23    /* TODO: implement this one  -- jerry */
 #define LSA_ENUMACCTRIGHTS     0x24
 #define LSA_ADDACCTRIGHTS      0x25
 #define LSA_REMOVEACCTRIGHTS   0x26
@@ -305,32 +306,33 @@ typedef struct lsa_r_query_info2
        NTSTATUS status;
 } LSA_R_QUERY_INFO2;
 
-/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
-typedef struct lsa_enum_trust_dom_info
-{
-       POLICY_HND pol; /* policy handle */
-       uint32 enum_context; /* enumeration context handle */
-       uint32 preferred_len; /* preferred maximum length */
+/*******************************************************/
 
+typedef struct {
+       POLICY_HND pol; 
+       uint32 enum_context; 
+       uint32 preferred_len;   /* preferred maximum length */
 } LSA_Q_ENUM_TRUST_DOM;
 
-/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
-typedef struct lsa_r_enum_trust_dom_info
-{
-       uint32 enum_context; /* enumeration context handle */
-       uint32 num_domains; /* number of domains */
-       uint32 ptr_enum_domains; /* buffer pointer to num domains */
-
-       /* this lot is only added if ptr_enum_domains is non-NULL */
-       uint32 num_domains2; /* number of domains */
-       UNIHDR2 *hdr_domain_name;
-       UNISTR2 *uni_domain_name;
-       DOM_SID2 *domain_sid;
+typedef struct {
+       UNISTR4 name;
+       DOM_SID2 *sid;
+} DOMAIN_INFO;
 
-       NTSTATUS status; /* return code */
+typedef struct {
+       uint32 count;
+       DOMAIN_INFO *domains;
+} DOMAIN_LIST;
 
+typedef struct {
+       uint32 enum_context;
+       uint32 count;
+       DOMAIN_LIST *domlist;
+       NTSTATUS status; 
 } LSA_R_ENUM_TRUST_DOM;
 
+/*******************************************************/
+
 /* LSA_Q_CLOSE */
 typedef struct lsa_q_close_info
 {
@@ -423,7 +425,7 @@ typedef struct lsa_q_lookup_sids
        POLICY_HND          pol; /* policy handle */
        LSA_SID_ENUM        sids;
        LSA_TRANS_NAME_ENUM names;
-       LOOKUP_LEVEL        level;
+       uint16              level;
        uint32              mapped_count;
 
 } LSA_Q_LOOKUP_SIDS;
@@ -532,7 +534,7 @@ typedef struct
 typedef struct
 {
        uint32 count;
-       UNISTR2_ARRAY rights;
+       UNISTR4_ARRAY *rights;
        NTSTATUS status;
 } LSA_R_ENUM_ACCT_RIGHTS;
 
@@ -542,8 +544,8 @@ typedef struct
 {
        POLICY_HND pol; /* policy handle */
        DOM_SID2 sid;
-       UNISTR2_ARRAY rights;
        uint32 count;
+       UNISTR4_ARRAY *rights;
 } LSA_Q_ADD_ACCT_RIGHTS;
 
 /* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */
@@ -559,8 +561,8 @@ typedef struct
        POLICY_HND pol; /* policy handle */
        DOM_SID2 sid;
        uint32 removeall;
-       UNISTR2_ARRAY rights;
        uint32 count;
+       UNISTR4_ARRAY *rights;
 } LSA_Q_REMOVE_ACCT_RIGHTS;
 
 /* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */
index 6abc85a4cac6c36fd9ec512fe64acfe217b23a84..dcc0ecc554ab49ab47a96d649fffa7e5a708c4f5 100644 (file)
@@ -1,9 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
-   SMB parameters and setup
-   Copyright (C) Andrew Tridgell 1992-1997
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
-   Copyright (C) Paul Ashton 1997
+
+   Copyright (C) Andrew Tridgell                1992-1997
+   Copyright (C) Luke Kenneth Casson Leighton   1996-1997
+   Copyright (C) Paul Ashton                    1997
+   Copyright (C) Gerald (Jerry) Carter          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
 #define _RPC_MISC_H 
 
 #define SMB_RPC_INTERFACE_VERSION 1
+#define PRS_POINTER_CAST BOOL (*)(const char*, prs_struct*, int, void*)
+
+enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
+
+
 
-/* well-known RIDs - Relative IDs */
+/********************************************************************** 
+ * well-known RIDs - Relative IDs
+ **********************************************************************/
 
 /* RIDs - Well-known users ... */
 #define DOMAIN_USER_RID_ADMIN          (0x000001F4L)
 #define BUILTIN_ALIAS_RID_RAS_SERVERS   (0x00000229L)
 #define BUILTIN_ALIAS_RID_PRE_2K_ACCESS (0x0000022aL)
 
-/*
+
+/********************************************************************** 
  * Masks for mappings between unix uid and gid types and
  * NT RIDS.
- */
-
+ **********************************************************************/
 
 #define BASE_RID (0x000003E8L)
 
 /* Take the bottom bit. */
-#define RID_TYPE_MASK 1
-#define RID_MULTIPLIER 2
+#define RID_TYPE_MASK          1
+#define RID_MULTIPLIER                 2
 
 /* The two common types. */
-#define USER_RID_TYPE 0
-#define GROUP_RID_TYPE 1
+#define USER_RID_TYPE          0
+#define GROUP_RID_TYPE                 1
 
-/* ENUM_HND */
-typedef struct enum_hnd_info
-{
+
+
+/********************************************************************** 
+ * RPC policy handle used pretty much everywhere
+ **********************************************************************/
+typedef struct {
        uint32 ptr_hnd;          /* pointer to enumeration handle */
        uint32 handle;           /* enumeration handle */
 } ENUM_HND;
 
-/* LOOKUP_LEVEL - switch value */
-typedef struct lookup_level_info
-{
-       uint16 value;
-} LOOKUP_LEVEL;
 
-/* DOM_SID2 - security id */
-typedef struct sid_info_2
-{
-       uint32 num_auths; /* length, bytes, including length of len :-) */
-       DOM_SID sid;
-} DOM_SID2;
 
-/* STRHDR - string header */
-typedef struct header_info
-{
-       uint16 str_str_len;
-       uint16 str_max_len;
-       uint32 buffer; /* non-zero */
-} STRHDR;
+/********************************************************************** 
+ * RPC policy handle used pretty much everywhere
+ **********************************************************************/
 
-/* UNIHDR - unicode string header */
-typedef struct unihdr_info
-{
-       uint16 uni_str_len;
-       uint16 uni_max_len;
-       uint32 buffer; /* usually has a value of 4 */
-} UNIHDR;
+typedef struct {
+       uint32 data1;
+       uint32 data2;
+       uint16 data3;
+       uint16 data4;
+       uint8 data5[8];
+#ifdef __INSURE__
 
-/* UNIHDR2 - unicode string header and undocumented buffer */
-typedef struct unihdr2_info
-{
-       UNIHDR unihdr;
-       uint32 buffer; /* 32 bit buffer pointer */
-} UNIHDR2;
+       /* To prevent the leakage of policy handles mallocate a bit of
+          memory when a policy handle is created and free it when the
+          handle is closed.  This should cause Insure to flag an error
+          when policy handles are overwritten or fall out of scope without
+          being freed. */
 
-/* UNISTR - unicode string size and buffer */
-typedef struct unistr_info
-{
-       /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
-       uint16 *buffer;
-} UNISTR;
+       char *marker;
+#endif
+} POLICY_HND;
 
-/* BUFHDR - buffer header */
-typedef struct bufhdr_info
-{
+
+/********************************************************************** 
+ * Buffer Headers -- use by SEC_DESC_BUF in winreg and netlogon code
+ **********************************************************************/
+typedef struct {
        uint32 buf_max_len;
        uint32 buf_len;
 } BUFHDR;
 
-/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
-/* pathetic.  some stupid team of \PIPE\winreg writers got the concept */
-/* of a unicode string different from the other \PIPE\ writers */
-typedef struct buffer2_info
-{
+typedef struct {
+       uint32 info_level;
+       uint32 length;          /* uint8 chars */
+       uint32 buffer;
+} BUFHDR2;
+
+typedef struct {
+       uint32 size;
+       uint32 buffer;
+} BUFHDR4;
+
+
+/********************************************************************** 
+ * Buffers 
+ **********************************************************************/
+
+/* buffer used by \winreg\ calls to fill in arbitrary REG_XXX values.
+   It *may* look like a UNISTR2 but it is *not*.  This is not a goof
+   by the winreg developers.  It is a generic buffer */
+
+typedef struct {
        uint32 buf_max_len;
        uint32 offset;
        uint32 buf_len;
-       /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
        uint16 *buffer;
-} BUFFER2;
+} REGVAL_BUFFER;
 
-/* BUFFER3 */
-typedef struct buffer3_info
-{
-       uint32 buf_max_len;
-       uint8  *buffer; /* Data */
+/* generic rpc version of the DATA_BLOB.  Just a length and uint8 array */
+
+typedef struct {
        uint32 buf_len;
-} BUFFER3;
+       uint8 *buffer;
+} RPC_DATA_BLOB;
 
-/* BUFFER5 */
-typedef struct buffer5_info
-{
+/********************************************************************** 
+ * Buffers use by spoolss (i might be able to replace it with
+ * an RPC_DATA_BLOB)
+ **********************************************************************/
+
+typedef struct {
        uint32 buf_len;
        uint16 *buffer; /* data */
 } BUFFER5;
 
-/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
-typedef struct unistr2_info
-{
+
+/********************************************************************** 
+ * Unicode and basic string headers 
+ **********************************************************************/
+typedef struct {
+       uint16 str_str_len;
+       uint16 str_max_len;
+       uint32 buffer; /* non-zero */
+} STRHDR;
+
+typedef struct {
+       uint16 uni_str_len;
+       uint16 uni_max_len;
+       uint32 buffer; 
+} UNIHDR;
+
+/********************************************************************** 
+ * UNICODE string variations
+ **********************************************************************/
+
+
+typedef struct {               /* UNISTR - unicode string size and buffer */
+       uint16 *buffer;         /* unicode characters. ***MUST*** be 
+                                  little-endian. ***MUST*** be null-terminated */
+} UNISTR;
+
+typedef struct {               /* UNISTR2 - unicode string size (in 
+                                  uint16 unicode chars) and buffer */
        uint32 uni_max_len;
        uint32 offset;
        uint32 uni_str_len;
-       /* unicode characters. ***MUST*** be little-endian. 
-               **must** be null-terminated and the uni_str_len should include
-               the NULL character */
-       uint16 *buffer;
+       uint16 *buffer;         /* unicode characters. ***MUST*** be little-endian. 
+                                 **must** be null-terminated and the uni_str_len 
+                                 should include the NULL character */
 } UNISTR2;
 
-/* STRING2 - string size (in uint8 chars) and buffer */
-typedef struct string2_info
-{
+typedef struct {               /* UNISTR3 - XXXX not sure about this structure */
+       uint32 uni_str_len;
+       UNISTR str;
+
+} UNISTR3;
+
+typedef struct {               /* Buffer wrapped around a UNISTR2 */
+       uint16 length;          /* number of bytes not counting NULL terminatation */
+       uint16 size;            /* number of bytes including NULL terminatation */
+       UNISTR2 *string;
+} UNISTR4;
+
+typedef struct {
+       uint32 count;
+       UNISTR4 *strings;
+} UNISTR4_ARRAY;
+
+
+/********************************************************************** 
+ * String variations
+ **********************************************************************/
+
+typedef struct {               /* STRING2 - string size (in uint8 chars) and buffer */
        uint32 str_max_len;
        uint32 offset;
        uint32 str_str_len;
-       uint8  *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
+       uint8  *buffer;         /* uint8 characters. **NOT** necessarily null-terminated */
 } STRING2;
 
-/* UNISTR3 - XXXX not sure about this structure */
-typedef struct unistr3_info
-{
-       uint32 uni_str_len;
-       UNISTR str;
 
-} UNISTR3;
 
-/* an element in a unicode string array */
-typedef struct
-{
-       uint16 length;
-       uint16 size;
-       uint32 ref_id;
-       UNISTR2 string;
-} UNISTR2_ARRAY_EL;
-
-/* an array of unicode strings */
-typedef struct 
-{
-       uint32 ref_id;
-       uint32 count;
-       UNISTR2_ARRAY_EL *strings;
-} UNISTR2_ARRAY;
 
+/********************************************************************** 
+ * Domain SID structures
+ **********************************************************************/
 
-/* an element in a sid array */
-typedef struct
-{
-       uint32 ref_id;
-       DOM_SID2 sid;
-} SID_ARRAY_EL;
+typedef struct {
+       uint32 num_auths; /* length, bytes, including length of len :-) */
+       DOM_SID sid;
+} DOM_SID2;
 
-/* an array of sids */
-typedef struct 
-{
-       uint32 ref_id;
-       uint32 count;
-       SID_ARRAY_EL *sids;
-} SID_ARRAY;
+
+/********************************************************************** 
+ * Domain SID structures
+ **********************************************************************/
 
 /* DOM_RID2 - domain RID structure for ntlsa pipe */
-typedef struct domrid2_info
-{
+typedef struct {
        uint8 type; /* value is SID_NAME_USE enum */
        uint32 rid;
        uint32 rid_idx; /* referenced domain index */
-
 } DOM_RID2;
 
-/* DOM_RID3 - domain RID structure for samr pipe */
-typedef struct domrid3_info
-{
+
+typedef struct {               /* DOM_RID3 - domain RID structure for samr pipe */
        uint32 rid;        /* domain-relative (to a SID) id */
        uint32 type1;      /* value is 0x1 */
        uint32 ptr_type;   /* undocumented pointer */
        uint32 type2;      /* value is 0x1 */
        uint32 unk; /* value is 0x2 */
-
 } DOM_RID3;
 
 /* DOM_RID4 - rid + user attributes */
@@ -255,6 +285,16 @@ typedef struct domrid4_info
        uint32 rid;  /* user RID */
 } DOM_RID4;
 
+/* DOM_GID - group id + user attributes */
+typedef struct {
+       uint32 g_rid;  /* a group RID */
+       uint32 attr;
+} DOM_GID;
+
+/********************************************************************** 
+ * ????
+ **********************************************************************/
+
 /* DOM_CLNT_SRV - client / server names */
 typedef struct clnt_srv_info
 {
@@ -316,32 +356,8 @@ typedef struct owf_info
 } OWF_INFO;
 
 
-/* DOM_GID - group id + user attributes */
-typedef struct gid_info
-{
-       uint32 g_rid;  /* a group RID */
-       uint32 attr;
-} DOM_GID;
 
-/* POLICY_HND */
-typedef struct lsa_policy_info
-{
-       uint32 data1;
-       uint32 data2;
-       uint16 data3;
-       uint16 data4;
-       uint8 data5[8];
-#ifdef __INSURE__
-
-       /* To prevent the leakage of policy handles mallocate a bit of
-          memory when a policy handle is created and free it when the
-          handle is closed.  This should cause Insure to flag an error
-          when policy handles are overwritten or fall out of scope without
-          being freed. */
 
-       char *marker;
-#endif
-} POLICY_HND;
 
 /*
  * A client connection's state, pipe name, 
@@ -380,33 +396,8 @@ typedef struct uint64_s
        uint32 high;
 } UINT64_S;
 
-/* BUFHDR2 - another buffer header, with info level */
-typedef struct bufhdr2_info
-{
-       uint32 info_level;
-       uint32 length;          /* uint8 chars */
-       uint32 buffer;
 
-}
-BUFHDR2;
 
-/* BUFHDR4 - another buffer header */
-typedef struct bufhdr4_info
-{
-       uint32 size;
-       uint32 buffer;
 
-}
-BUFHDR4;
 
-/* BUFFER4 - simple length and buffer */
-typedef struct buffer4_info
-{
-       uint32 buf_len;
-       uint8 *buffer;
-
-}
-BUFFER4;
-
-enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
 #endif /* _RPC_MISC_H */
index 3ba1ce6465bf2c5c38930047f8a0fe139506a895..6812358575ac5d9237fe5eefb3e64380e2e66413 100644 (file)
@@ -643,7 +643,7 @@ typedef struct sam_domain_info_info
        UNISTR2 uni_dom_name;
        UNISTR2 buf_oem_info; 
 
-       BUFFER4 buf_sec_desc;
+       RPC_DATA_BLOB buf_sec_desc;
 
        LOCKOUT_STRING account_lockout;
 
@@ -670,7 +670,7 @@ typedef struct sam_group_info_info
 
        UNISTR2 uni_grp_name;
        UNISTR2 uni_grp_desc;
-       BUFFER4 buf_sec_desc;
+       RPC_DATA_BLOB buf_sec_desc;
 
 } SAM_GROUP_INFO;
 
@@ -748,11 +748,11 @@ typedef struct sam_account_info_info
        uint32 unknown1; /* 0x4EC */
        uint32 unknown2; /* 0 */
 
-       BUFFER4 buf_logon_hrs;
+       RPC_DATA_BLOB buf_logon_hrs;
        UNISTR2 uni_comment;
        UNISTR2 uni_parameters;
        SAM_PWD pass;
-       BUFFER4 buf_sec_desc;
+       RPC_DATA_BLOB buf_sec_desc;
        UNISTR2 uni_profile;
 
 } SAM_ACCOUNT_INFO;
@@ -783,7 +783,7 @@ typedef struct sam_alias_info_info
        uint8 reserved[40];
 
        UNISTR2 uni_als_name;
-       BUFFER4 buf_sec_desc;
+       RPC_DATA_BLOB buf_sec_desc;
        UNISTR2 uni_als_desc;
 
 } SAM_ALIAS_INFO;
@@ -829,7 +829,7 @@ typedef struct
        UNISTR2  domain_name;
        DOM_SID2 domain_sid;
 
-       BUFFER4  buf_sec_desc;
+       RPC_DATA_BLOB  buf_sec_desc;
 } SAM_DELTA_POLICY;
 
 /* SAM_DELTA_TRUST_DOMS */
@@ -881,7 +881,7 @@ typedef struct
        UNIHDR *hdr_privslist;
        UNISTR2 *uni_privslist;
 
-       BUFFER4 buf_sec_desc;
+       RPC_DATA_BLOB buf_sec_desc;
 } SAM_DELTA_PRIVS;
 
 /* SAM_DELTA_SECRET */
index bfb5f1e0763472c7c51cf6ec88cbf8e0309e8a6e..f70fb5f03cf218412ad3c82f140fa3c3ae16bb3d 100644 (file)
@@ -4,7 +4,8 @@
    Copyright (C) Andrew Tridgell                 1992-1997.
    Copyright (C) Luke Kenneth Casson Leighton    1996-1997.
    Copyright (C) Paul Ashton                          1997.
-   Copyright (C) Gerald Carter                        2002.
+   Copyright (C) Jeremy Cooper                        2004.
+   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
 #ifndef _RPC_REG_H /* _RPC_REG_H */
 #define _RPC_REG_H 
 
+/* RPC opnum */
 
-/* winreg pipe defines 
-   NOT IMPLEMENTED !!
-#define _REG_UNK_01            0x01
-#define _REG_UNK_03            0x03
-#define REG_CREATE_KEY         0x06
-#define REG_DELETE_KEY         0x07
-#define REG_DELETE_VALUE       0x08
-#define REG_FLUSH_KEY          0x0b
-#define REG_GET_KEY_SEC                0x0c
-#define        _REG_UNK_0D             0x0d
-#define _REG_UNK_0E            0x0e
-#define        _REG_UNK_12             0x12
-#define _REG_UNK_13            0x13
-#define REG_SET_KEY_SEC                0x15
-#define REG_CREATE_VALUE       0x16
-#define        _REG_UNK_17             0x17
-*/
-
-/* Implemented */
 #define REG_OPEN_HKCR          0x00
 #define REG_OPEN_HKLM          0x02
+#define REG_OPEN_HKPD          0x03
 #define REG_OPEN_HKU           0x04
 #define REG_CLOSE              0x05
+#define REG_CREATE_KEY         0x06
+#define REG_DELETE_KEY         0x07
+#define REG_DELETE_VALUE       0x08
 #define REG_ENUM_KEY           0x09
 #define REG_ENUM_VALUE         0x0a
+#define REG_FLUSH_KEY          0x0b
+#define REG_GET_KEY_SEC                0x0c
 #define REG_OPEN_ENTRY         0x0f
 #define REG_QUERY_KEY          0x10
 #define REG_INFO               0x11
+#define REG_RESTORE_KEY                0x13
+#define REG_SAVE_KEY           0x14
+#define REG_SET_KEY_SEC                0x15
+#define REG_SET_VALUE          0x16
 #define REG_SHUTDOWN           0x18
 #define REG_ABORT_SHUTDOWN     0x19
-#define        REG_SAVE_KEY            0x14    /* no idea what the real name is */
-#define REG_UNKNOWN_1A         0x1a
+#define REG_GETVERSION         0x1a
+#define REG_SHUTDOWN_EX                0x1e
 
 
 #define HKEY_CLASSES_ROOT      0x80000000
 #define HKEY_CURRENT_USER      0x80000001
 #define HKEY_LOCAL_MACHINE     0x80000002
 #define HKEY_USERS             0x80000003
+#define HKEY_PERFORMANCE_DATA  0x80000004
 
 #define KEY_HKLM       "HKLM"
 #define KEY_HKU                "HKU"
 #define KEY_HKCR       "HKCR"
 #define KEY_PRINTING   "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
+#define KEY_EVENTLOG   "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog"
 #define KEY_TREE_ROOT  ""
 
 /* Registry data types */
 #define REG_FULL_RESOURCE_DESCRIPTOR   9
 #define REG_RESOURCE_REQUIREMENTS_LIST 10
 
+/*
+ * INTERNAL REGISTRY STRUCTURES 
+ */
+
 /* structure to contain registry values */
 
 typedef struct {
@@ -94,7 +93,7 @@ typedef struct {
        uint8           *data_p;
 } REGISTRY_VALUE;
 
-/* container for regostry values */
+/* container for registry values */
 
 typedef struct {
        TALLOC_CTX      *ctx;
@@ -143,379 +142,253 @@ typedef struct _RegistryKey {
        
 } REGISTRY_KEY;
 
+/*
+ * RPC REGISTRY STRUCTURES
+ */
 
-/* REG_Q_OPEN_HKCR   */
-typedef struct q_reg_open_hkcr_info
-{
-       uint32 ptr;
-       uint16 unknown_0; /* 0x5428      - 16 bit unknown */
-       uint16 unknown_1; /* random.  changes */
-       uint32 level;     /* 0x0000 0002 - 32 bit unknown */
-
-} REG_Q_OPEN_HKCR  ;
-
-/* REG_R_OPEN_HKCR   */
-typedef struct r_reg_open_hkcr_info
-{
-       POLICY_HND pol;       /* policy handle */
-       WERROR status;         /* return status */
-
-} REG_R_OPEN_HKCR;
-
-
-/* REG_Q_OPEN_HKLM   */
-typedef struct q_reg_open_hklm_info
-{
-       uint32 ptr;
-       uint16 unknown_0;       /* 0xE084      - 16 bit unknown */
-       uint16 unknown_1;       /* random.  changes */
-       uint32 access_mask;
+/***********************************************/
 
-}
-REG_Q_OPEN_HKLM;
-
-/* REG_R_OPEN_HKLM   */
-typedef struct r_reg_open_hklm_info
-{
-       POLICY_HND pol;         /* policy handle */
-       WERROR status;          /* return status */
-
-}
-REG_R_OPEN_HKLM;
-
-
-/* REG_Q_OPEN_HKU */
-typedef struct q_reg_open_hku_info
-{
-       uint32 ptr;
-       uint16 unknown_0; 
-       uint16 unknown_1; 
-       uint32 access_mask;    
-
-} REG_Q_OPEN_HKU;
-
-/* REG_R_OPEN_HKU */
-typedef struct r_reg_open_hku_info
-{
-       POLICY_HND pol;      /* policy handle */
-       WERROR status;     /* return status */
+typedef struct {
+       uint16 *server;
+       uint32 access;     
+} REG_Q_OPEN_HIVE;
 
-} REG_R_OPEN_HKU;
+typedef struct {
+       POLICY_HND pol;
+       WERROR status; 
+} REG_R_OPEN_HIVE;
 
 
-/* REG_Q_FLUSH_KEY */
-typedef struct q_reg_open_flush_key_info
-{
-       POLICY_HND pol;       /* policy handle */
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol;
 } REG_Q_FLUSH_KEY;
 
-/* REG_R_FLUSH_KEY */
-typedef struct r_reg_open_flush_key_info
-{
-       WERROR status;         /* return status */
-
+typedef struct {
+       WERROR status; 
 } REG_R_FLUSH_KEY;
 
 
-/* REG_Q_SET_KEY_SEC */
-typedef struct q_reg_set_key_sec_info
-{
-       POLICY_HND pol;         /* policy handle */
-
-       uint32 sec_info;       /* xxxx_SECURITY_INFORMATION */
+/***********************************************/
 
-       uint32 ptr;       /* pointer */
-       BUFHDR hdr_sec;    /* header for security data */
-       SEC_DESC_BUF *data;    /* security data */
-       
+typedef struct {
+       POLICY_HND pol;
+       uint32 sec_info;
+       uint32 ptr; 
+       BUFHDR hdr_sec;
+       SEC_DESC_BUF *data;
 } REG_Q_SET_KEY_SEC;
 
-/* REG_R_SET_KEY_SEC */
-typedef struct r_reg_set_key_sec_info
-{
+typedef struct {
        WERROR status;
-       
 } REG_R_SET_KEY_SEC;
 
 
-/* REG_Q_GET_KEY_SEC */
-typedef struct q_reg_get_key_sec_info
-{
-       POLICY_HND pol;         /* policy handle */
-
-       uint32 sec_info;       /* xxxx_SECURITY_INFORMATION */
+/***********************************************/
 
-       uint32 ptr;       /* pointer */
-       BUFHDR hdr_sec;    /* header for security data */
-       SEC_DESC_BUF *data;    /* security data */
-       
+typedef struct {
+       POLICY_HND pol;
+       uint32 sec_info;
+       uint32 ptr; 
+       BUFHDR hdr_sec; 
+       SEC_DESC_BUF *data; 
 } REG_Q_GET_KEY_SEC;
 
-/* REG_R_GET_KEY_SEC */
-typedef struct r_reg_get_key_sec_info
-{
-       uint32 sec_info;       /* xxxx_SECURITY_INFORMATION */
-
-       uint32 ptr;       /* pointer */
-       BUFHDR hdr_sec;    /* header for security data */
-       SEC_DESC_BUF *data;    /* security data */
-
+typedef struct {
+       uint32 sec_info; 
+       uint32 ptr; 
+       BUFHDR hdr_sec; 
+       SEC_DESC_BUF *data;
        WERROR status;
-       
 } REG_R_GET_KEY_SEC;
 
-/* REG_Q_CREATE_VALUE */
-typedef struct q_reg_create_value_info
-{
-       POLICY_HND pol;    /* policy handle */
-
-       UNIHDR hdr_name;   /* name of value */
-       UNISTR2 uni_name;
-
-       uint32 type;       /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
-       BUFFER3 *buf_value; /* value, in byte buffer */
-
-} REG_Q_CREATE_VALUE;
+/***********************************************/
 
-/* REG_R_CREATE_VALUE */
-typedef struct r_reg_create_value_info
-{ 
-       WERROR status;         /* return status */
-
-} REG_R_CREATE_VALUE;
-
-/* REG_Q_ENUM_VALUE */
-typedef struct q_reg_query_value_info
-{
-       POLICY_HND pol;    /* policy handle */
-
-       uint32 val_index;  /* index */
-
-       UNIHDR hdr_name;   /* name of value */
-       UNISTR2 uni_name;
-
-       uint32 ptr_type;   /* pointer */
-       uint32 type;       /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
-       uint32 ptr_value;  /* pointer */
-       BUFFER2 buf_value; /* value, in byte buffer */
-
-       uint32 ptr1;       /* pointer */
-       uint32 len_value1; /* */
-
-       uint32 ptr2;       /* pointer */
-       uint32 len_value2; /* */
+typedef struct {
+       POLICY_HND pol;   
+       UNISTR4 name;           
+       uint32 type;  
+       RPC_DATA_BLOB value; 
+       uint32 size;
+} REG_Q_SET_VALUE;
+
+typedef struct { 
+       WERROR status;
+} REG_R_SET_VALUE;
 
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol;
+       uint32 val_index;
+       UNISTR4 name;
+       uint32 *type;  
+       REGVAL_BUFFER *value; /* value, in byte buffer */
+       uint32 *len_value1; 
+       uint32 *len_value2; 
 } REG_Q_ENUM_VALUE;
 
-/* REG_R_ENUM_VALUE */
-typedef struct r_reg_enum_value_info
-{ 
-       UNIHDR hdr_name;        /* name of value */
-       UNISTR2 uni_name;
-
-       uint32 ptr_type;            /* pointer */
-       uint32 type;        /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
-       uint32 ptr_value;       /* pointer */
-       BUFFER2 buf_value;    /* value, in byte buffer */
-
-       uint32 ptr1;            /* pointer */
-       uint32 len_value1;       /* */
-
-       uint32 ptr2;            /* pointer */
-       uint32 len_value2;       /* */
-
-       WERROR status;         /* return status */
-
+typedef struct { 
+       UNISTR4 name;
+       uint32 *type;
+       REGVAL_BUFFER *value;
+       uint32 *len_value1;
+       uint32 *len_value2;
+       WERROR status;
 } REG_R_ENUM_VALUE;
 
-/* REG_Q_CREATE_KEY */
-typedef struct q_reg_create_key_info
-{
-       POLICY_HND pnt_pol;       /* parent key policy handle */
+/***********************************************/
 
-       UNIHDR hdr_name;
-       UNISTR2 uni_name;
-
-       UNIHDR hdr_class;
-       UNISTR2 uni_class;
-
-       uint32 reserved; /* 0x0000 0000 */
-       SEC_ACCESS sam_access; /* access rights flags, see rpc_secdes.h */
-
-       uint32 ptr1;
-       uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
-
-       uint32 ptr2;       /* pointer */
-       BUFHDR hdr_sec;    /* header for security data */
-       uint32 ptr3;       /* pointer */
+typedef struct {
+       POLICY_HND pnt_pol;
+       UNISTR4 name;
+       UNISTR4 class;
+       uint32 reserved;
+       uint32 access;
+       uint32 *sec_info;
+       uint32 ptr2;
+       BUFHDR hdr_sec;
+       uint32 ptr3;
        SEC_DESC_BUF *data;
-
        uint32 unknown_2; /* 0x0000 0000 */
-
 } REG_Q_CREATE_KEY;
 
-/* REG_R_CREATE_KEY */
-typedef struct r_reg_create_key_info
-{
-       POLICY_HND key_pol;       /* policy handle */
-       uint32 unknown; /* 0x0000 0000 */
-
-       WERROR status;         /* return status */
-
+typedef struct {
+       POLICY_HND key_pol;
+       uint32 unknown;
+       WERROR status; 
 } REG_R_CREATE_KEY;
 
-/* REG_Q_DELETE_KEY */
-typedef struct q_reg_delete_key_info
-{
-       POLICY_HND pnt_pol;       /* parent key policy handle */
+/***********************************************/
 
-       UNIHDR hdr_name;
-       UNISTR2 uni_name;
+typedef struct {
+       POLICY_HND pnt_pol;
+       UNISTR4 name;
 } REG_Q_DELETE_KEY;
 
-/* REG_R_DELETE_KEY */
-typedef struct r_reg_delete_key_info
-{
-       POLICY_HND key_pol;       /* policy handle */
-
-       WERROR status;         /* return status */
-
+typedef struct {
+       POLICY_HND key_pol;
+       WERROR status; 
 } REG_R_DELETE_KEY;
 
-/* REG_Q_DELETE_VALUE */
-typedef struct q_reg_delete_val_info
-{
-       POLICY_HND pnt_pol;       /* parent key policy handle */
-
-       UNIHDR hdr_name;
-       UNISTR2 uni_name;
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pnt_pol;
+       UNISTR4 name;
 } REG_Q_DELETE_VALUE;
 
-/* REG_R_DELETE_VALUE */
-typedef struct r_reg_delete_val_info
-{
-       POLICY_HND key_pol;       /* policy handle */
-
-       WERROR status;         /* return status */
-
+typedef struct {
+       POLICY_HND key_pol;
+       WERROR status;
 } REG_R_DELETE_VALUE;
 
-/* REG_Q_QUERY_KEY */
-typedef struct q_reg_query_info
-{
-       POLICY_HND pol;       /* policy handle */
-       UNIHDR hdr_class;
-       UNISTR2 uni_class;
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol;
+       UNISTR4 class;
 } REG_Q_QUERY_KEY;
 
-/* REG_R_QUERY_KEY */
-typedef struct r_reg_query_key_info
-{
-       UNIHDR hdr_class;
-       UNISTR2 uni_class;
-
+typedef struct {
+       UNISTR4 class;
        uint32 num_subkeys;
        uint32 max_subkeylen;
-       uint32 reserved; /* 0x0000 0000 - according to MSDN (max_subkeysize?) */
+       uint32 reserved;        /* 0x0000 0000 - according to MSDN (max_subkeysize?) */
        uint32 num_values;
        uint32 max_valnamelen;
        uint32 max_valbufsize; 
-       uint32 sec_desc; /* 0x0000 0078 */
-       NTTIME mod_time;  /* modified time */
-
-       WERROR status;         /* return status */
-
+       uint32 sec_desc;        /* 0x0000 0078 */
+       NTTIME mod_time;        /* modified time */
+       WERROR status;         
 } REG_R_QUERY_KEY;
 
 
-/* REG_Q_UNKNOWN_1A */
-typedef struct q_reg_unk_1a_info
-{
-       POLICY_HND pol;       /* policy handle */
+/***********************************************/
 
-} REG_Q_UNKNOWN_1A;
+typedef struct {
+       POLICY_HND pol;       /* policy handle */
+} REG_Q_GETVERSION;
 
-/* REG_R_UNKNOWN_1A */
-typedef struct r_reg_unk_1a_info
-{
+typedef struct {
        uint32 unknown;         /* 0x0500 0000 */
        WERROR status;         /* return status */
+} REG_R_GETVERSION;
 
-} REG_R_UNKNOWN_1A;
 
+/***********************************************/
 
-/* REG_Q_UNKNOWN_1A */
-typedef struct q_reg_unknown_14
-{
-       POLICY_HND pol;       /* policy handle */
-       
-       UNIHDR  hdr_file;       /* unicode product type header */
-       UNISTR2 uni_file;       /* local filename to save key as from regedt32.exe */
-                               /* e.g. "c:\temp\test.dat" */
-       
-       uint32 unknown;         /* 0x0000 0000 */
+typedef struct {
+       POLICY_HND pol; 
+       UNISTR4 filename;
+       uint32 flags;
+} REG_Q_RESTORE_KEY;
 
-} REG_Q_SAVE_KEY;
+typedef struct {
+       WERROR status;         /* return status */
+} REG_R_RESTORE_KEY;
 
 
-/* REG_R_UNKNOWN_1A */
-typedef struct r_reg_unknown_14
-{
-       WERROR status;         /* return status */
+/***********************************************/
 
-} REG_R_SAVE_KEY;
 
+/* I have no idea if this is correct since I 
+   have not seen the full structure on the wire 
+   as of yet */
+   
+typedef struct {
+       uint32 max_len;
+       uint32 len;
+       SEC_DESC *secdesc;
+} REG_SEC_DESC_BUF;
 
+typedef struct {
+       uint32 size;            /* size in bytes of security descriptor */
+       REG_SEC_DESC_BUF secdesc;
+       uint8  inherit;         /* see MSDN for a description */
+} SECURITY_ATTRIBUTE;
 
-/* REG_Q_CLOSE */
-typedef struct reg_q_close_info
-{
-       POLICY_HND pol; /* policy handle */
+typedef struct {
+       POLICY_HND pol; 
+       UNISTR4 filename;
+       SECURITY_ATTRIBUTE *sec_attr;
+} REG_Q_SAVE_KEY;
 
-} REG_Q_CLOSE;
+typedef struct {
+       WERROR status;         /* return status */
+} REG_R_SAVE_KEY;
 
-/* REG_R_CLOSE */
-typedef struct reg_r_close_info
-{
-       POLICY_HND pol; /* policy handle.  should be all zeros. */
 
-       WERROR status; /* return code */
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol; /* policy handle */
+} REG_Q_CLOSE;
+
+typedef struct {
+       POLICY_HND pol; 
+       WERROR status; 
 } REG_R_CLOSE;
 
 
-/* REG_Q_ENUM_KEY */
-typedef struct q_reg_enum_value_info
-{
-       POLICY_HND pol;         /* policy handle */
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol; 
        uint32 key_index;       
-
        uint16 key_name_len;    /* 0x0000 */
        uint16 unknown_1;       /* 0x0414 */
-
        uint32 ptr1;            /* pointer */
        uint32 unknown_2;       /* 0x0000 020A */
        uint8  pad1[8];         /* padding - zeros */
-
        uint32 ptr2;            /* pointer */
        uint8  pad2[8];         /* padding - zeros */
-
        uint32 ptr3;            /* pointer */
        NTTIME time;            /* current time? */
-
 } REG_Q_ENUM_KEY;
 
-/* REG_R_ENUM_KEY */
-typedef struct r_reg_enum_key_info
-{ 
+typedef struct { 
        uint16 key_name_len;    /* number of bytes in key name */
        uint16 unknown_1;       /* 0x0414 - matches with query unknown_1 */
 
@@ -532,17 +405,14 @@ typedef struct r_reg_enum_key_info
        NTTIME time;            /* current time? */
 
        WERROR status;         /* return status */
-
 } REG_R_ENUM_KEY;
 
 
-/* REG_Q_INFO */
-typedef struct q_reg_info_info
-{
-       POLICY_HND pol;         /* policy handle */
+/***********************************************/
 
-       UNIHDR  hdr_type;       /* unicode product type header */
-       UNISTR2 uni_type;       /* unicode product type - "ProductType" */
+typedef struct {
+       POLICY_HND pol;         /* policy handle */
+       UNISTR4  name;
 
        uint32 ptr_reserved;    /* pointer */
   
@@ -560,83 +430,66 @@ typedef struct q_reg_info_info
 
 } REG_Q_INFO;
 
-/* REG_R_INFO */
-typedef struct r_reg_info_info
-{ 
-       uint32 ptr_type;        /* key type pointer */
-       uint32 type;            /* key datatype  */
-
-       uint32 ptr_uni_val;     /* key value pointer */
-       BUFFER2 uni_val;        /* key value */
-
-       uint32 ptr_max_len;
-       uint32 buf_max_len;
-
-       uint32 ptr_len;
-       uint32 buf_len;
-  
+typedef struct { 
+       uint32 *type;
+       REGVAL_BUFFER *value;   /* key value */
+       uint32 *buf_max_len;
+       uint32 *buf_len;
        WERROR status;  /* return status */
-
 } REG_R_INFO;
 
 
-/* REG_Q_OPEN_ENTRY */
-typedef struct q_reg_open_entry_info
-{
-       POLICY_HND pol;        /* policy handle */
-
-       UNIHDR  hdr_name;       /* unicode registry string header */
-       UNISTR2 uni_name;       /* unicode registry string name */
+/***********************************************/
 
+typedef struct {
+       POLICY_HND pol;
+       UNISTR4 name; 
        uint32 unknown_0;       /* 32 bit unknown - 0x0000 0000 */
-       uint32 access_desired; 
-
+       uint32 access; 
 } REG_Q_OPEN_ENTRY;
 
-
-
-/* REG_R_OPEN_ENTRY */
-typedef struct r_reg_open_entry_info
-{
-       POLICY_HND pol;       /* policy handle */
-       WERROR status;         /* return status */
-
+typedef struct {
+       POLICY_HND pol;
+       WERROR status;
 } REG_R_OPEN_ENTRY;
 
-/* REG_Q_SHUTDOWN */
-typedef struct q_reg_shutdown_info
-{
-       uint32 ptr_0;
-       uint32 ptr_1;
-       uint32 ptr_2;
-       UNIHDR hdr_msg;         /* shutdown message */
-       UNISTR2 uni_msg;        /* seconds */
-       uint32 timeout;         /* seconds */
+/***********************************************/
+typedef struct {
+       uint16 *server;
+       UNISTR4 *message;       
+       uint32 timeout;         /* in seconds */
        uint8 force;            /* boolean: force shutdown */
-       uint8 reboot;           /* boolean: reboot on shutdown */
-               
+       uint8 reboot;           /* boolean: reboot on shutdown */               
 } REG_Q_SHUTDOWN;
 
-/* REG_R_SHUTDOWN */
-typedef struct r_reg_shutdown_info
-{
+typedef struct {
        WERROR status;          /* return status */
-
 } REG_R_SHUTDOWN;
 
-/* REG_Q_ABORT_SHUTDOWN */
-typedef struct q_reg_abort_shutdown_info
-{
-       uint32 ptr_server;
-       uint16 server;
+/***********************************************/
+typedef struct {
+       uint16 *server;
+       UNISTR4 *message;       
+       uint32 timeout;         /* in seconds */
+       uint8 force;            /* boolean: force shutdown */
+       uint8 reboot;           /* boolean: reboot on shutdown */
+       uint32 reason;          /* reason - must be defined code */
+} REG_Q_SHUTDOWN_EX;
 
-} REG_Q_ABORT_SHUTDOWN;
+typedef struct {
+       WERROR status;
+} REG_R_SHUTDOWN_EX;
+
+/***********************************************/
 
-/* REG_R_ABORT_SHUTDOWN */
-typedef struct r_reg_abort_shutdown_info
-{ 
-       WERROR status; /* return status */
+typedef struct {
+       uint16 *server;
+} REG_Q_ABORT_SHUTDOWN;
 
+typedef struct { 
+       WERROR status; 
 } REG_R_ABORT_SHUTDOWN;
 
 
index 3e4c47dce9a06622a8b3dfc37f93d01a126b48a9..ea987f9e4e0a964cdc25abf1fcb9685881aa4504 100644 (file)
@@ -472,4 +472,51 @@ typedef struct standard_mapping {
                (STANDARD_RIGHTS_EXECUTE_ACCESS | \
                SA_RIGHT_ALIAS_LOOKUP_INFO )    /* 0x00020008 */
 
+/*
+ * Acces bits for the svcctl objects
+ */
+
+/* Service Control Manager Bits */ 
+
+#define SC_RIGHT_MGR_CONNECT                   0x0001
+#define SC_RIGHT_MGR_CREATE_SERVICE            0x0002
+#define SC_RIGHT_MGR_ENUMERATE_SERVICE         0x0004
+#define SC_RIGHT_MGR_LOCK                      0x0008
+#define SC_RIGHT_MGR_QUERY_LOCK_STATUS         0x0010
+#define SC_RIGHT_MGR_MODIFY_BOOT_CONFIG                0x0020
+
+#define SC_MANAGER_ALL_ACCESS \
+       ( STANDARD_RIGHTS_REQUIRED_ACCESS       | \
+         SC_RIGHT_MGR_CONNECT                  | \
+         SC_RIGHT_MGR_CREATE_SERVICE           | \
+         SC_RIGHT_MGR_ENUMERATE_SERVICE        | \
+         SC_RIGHT_MGR_LOCK                     | \
+         SC_RIGHT_MGR_QUERY_LOCK_STATUS        | \
+         SC_RIGHT_MGR_MODIFY_BOOT_CONFIG )
+
+/* Service Object Bits */ 
+
+#define SC_RIGHT_SVC_QUERY_CONFIG              0x0001
+#define SC_RIGHT_SVC_CHANGE_CONFIG             0x0002
+#define SC_RIGHT_SVC_QUERY_STATUS              0x0004
+#define SC_RIGHT_SVC_ENUMERATE_DEPENDENTS      0x0008
+#define SC_RIGHT_SVC_START                     0x0010
+#define SC_RIGHT_SVC_STOP                      0x0020
+#define SC_RIGHT_SVC_PAUSE_CONTINUE            0x0040
+#define SC_RIGHT_SVC_INTERROGATE               0x0080
+#define SC_RIGHT_SVC_USER_DEFINED_CONTROL      0x0100
+
+#define SERVICE_ALL_ACCESS \
+       ( STANDARD_RIGHTS_REQUIRED_ACCESS       | \
+         SC_RIGHT_SVC_QUERY_CONFIG             | \
+         SC_RIGHT_SVC_CHANGE_CONFIG            | \
+         SC_RIGHT_SVC_QUERY_STATUS             | \
+         SC_RIGHT_SVC_ENUMERATE_DEPENDENTS     | \
+         SC_RIGHT_SVC_START                    | \
+         SC_RIGHT_SVC_STOP                     | \
+         SC_RIGHT_SVC_PAUSE_CONTINUE           | \
+         SC_RIGHT_SVC_INTERROGATE              | \
+         SC_RIGHT_SVC_USER_DEFINED_CONTROL )
+
+
 #endif /* _RPC_SECDES_H */
index b8e50b835f527fa9e9dd46a04b6481488c22c94a..a9d86aec26c1bb33fcfd38fc7f8beaf8981dd2d3 100644 (file)
@@ -1,7 +1,8 @@
 /* 
    Unix SMB/CIFS implementation.
-   SMB parameters and setup
+   
    Copyright (C) Jim McDonough (jmcd@us.ibm.com)      2003.
+   Copyright (C) Gerald (Jerry) Carter                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
 #define _RPC_SHUTDOWN_H 
 
 
-/* Implemented */
+/* opnums */
+
 #define SHUTDOWN_INIT          0x00
 #define SHUTDOWN_ABORT         0x01
-/* NOT IMPLEMENTED
 #define SHUTDOWN_INIT_EX       0x02
-*/
 
-/* SHUTDOWN_Q_INIT */
-typedef struct q_shutodwn_init_info
-{
-       uint32 ptr_server;
-       uint16 server;
-       uint32 ptr_msg;
-       UNIHDR hdr_msg;         /* shutdown message */
-       UNISTR2 uni_msg;        /* seconds */
-       uint32 timeout;         /* seconds */
+
+/***********************************************/
+typedef struct {
+       uint16 *server;
+       UNISTR4 *message;       
+       uint32 timeout;         /* in seconds */
        uint8 force;            /* boolean: force shutdown */
-       uint8 reboot;           /* boolean: reboot on shutdown */
-               
+       uint8 reboot;           /* boolean: reboot on shutdown */               
 } SHUTDOWN_Q_INIT;
 
-/* SHUTDOWN_R_INIT */
-typedef struct r_shutdown_init_info
-{
-       NTSTATUS status;                /* return status */
-
+typedef struct {
+       WERROR status;          /* return status */
 } SHUTDOWN_R_INIT;
 
-/* SHUTDOWN_Q_ABORT */
-typedef struct q_shutdown_abort_info
-{
-       uint32 ptr_server;
-       uint16 server;
+/***********************************************/
+typedef struct {
+       uint16 *server;
+       UNISTR4 *message;       
+       uint32 timeout;         /* in seconds */
+       uint8 force;            /* boolean: force shutdown */
+       uint8 reboot;           /* boolean: reboot on shutdown */
+       uint32 reason;          /* reason - must be defined code */
+} SHUTDOWN_Q_INIT_EX;
 
-} SHUTDOWN_Q_ABORT;
+typedef struct {
+       WERROR status;
+} SHUTDOWN_R_INIT_EX;
 
-/* SHUTDOWN_R_ABORT */
-typedef struct r_shutdown_abort_info
-{ 
-       NTSTATUS status; /* return status */
+/***********************************************/
 
+typedef struct {
+       uint16 *server;
+} SHUTDOWN_Q_ABORT;
+
+typedef struct { 
+       WERROR status; 
 } SHUTDOWN_R_ABORT;
 
 
+
 #endif /* _RPC_SHUTDOWN_H */
 
index 7c5942759f4290263b1fbd467b54094dad1b601f..64533635083a7dbaca56ba2a4782695c4ade7891 100755 (executable)
@@ -1,11 +1,10 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 1.9.
-   SMB parameters and setup
+
    Copyright (C) Andrew Tridgell              1992-2000,
    Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
    Copyright (C) Jean Francois Micouleau      1998-2000.
-   Copyright (C) Gerald Carter                2001-2002.
+   Copyright (C) Gerald Carter                2001-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
@@ -427,27 +426,22 @@ PRINTER_MESSAGE_INFO;
 
 /* this struct is undocumented */
 /* thanks to the ddk ... */
-typedef struct spool_user_1
-{
+typedef struct {
        uint32 size;            /* length of user_name & client_name + 2? */
-       uint32 client_name_ptr;
-       uint32 user_name_ptr;
+       UNISTR2 *client_name;
+       UNISTR2 *user_name;
        uint32 build;
        uint32 major;
        uint32 minor;
        uint32 processor;
-       UNISTR2 client_name;
-       UNISTR2 user_name;
-}
-SPOOL_USER_1;
+} SPOOL_USER_1;
 
-typedef struct spool_user_ctr_info
-{
+typedef struct {
        uint32 level;
-       uint32 ptr;
-       SPOOL_USER_1 user1;
-}
-SPOOL_USER_CTR;
+       union {
+               SPOOL_USER_1 *user1;
+       } user;
+SPOOL_USER_CTR;
 
 /*
  * various bits in the DEVICEMODE.fields member
@@ -544,41 +538,33 @@ typedef struct _printer_default
 }
 PRINTER_DEFAULT;
 
-/* SPOOL_Q_OPEN_PRINTER request to open a printer */
-typedef struct spool_q_open_printer
-{
-       uint32 printername_ptr;
-       UNISTR2 printername;
+/********************************************/
+
+typedef struct {
+       UNISTR2 *printername;
        PRINTER_DEFAULT printer_default;
-}
-SPOOL_Q_OPEN_PRINTER;
+} SPOOL_Q_OPEN_PRINTER;
 
-/* SPOOL_R_OPEN_PRINTER reply to an open printer */
-typedef struct spool_r_open_printer
-{
+typedef struct {
        POLICY_HND handle;      /* handle used along all transactions (20*uint8) */
        WERROR status;
-}
-SPOOL_R_OPEN_PRINTER;
+} SPOOL_R_OPEN_PRINTER;
 
-/* SPOOL_Q_OPEN_PRINTER_EX request to open a printer */
-typedef struct spool_q_open_printer_ex
-{
-       uint32 printername_ptr;
-       UNISTR2 printername;
+/********************************************/
+
+typedef struct {
+       UNISTR2 *printername;
        PRINTER_DEFAULT printer_default;
        uint32 user_switch;
        SPOOL_USER_CTR user_ctr;
-}
-SPOOL_Q_OPEN_PRINTER_EX;
+} SPOOL_Q_OPEN_PRINTER_EX;
 
-/* SPOOL_R_OPEN_PRINTER_EX reply to an open printer */
-typedef struct spool_r_open_printer_ex
-{
+typedef struct {
        POLICY_HND handle;      /* handle used along all transactions (20*uint8) */
        WERROR status;
-}
-SPOOL_R_OPEN_PRINTER_EX;
+} SPOOL_R_OPEN_PRINTER_EX;
+
+/********************************************/
 
 typedef struct spool_notify_option_type
 {
@@ -614,15 +600,6 @@ typedef struct s_header_type
 }
 HEADER_TYPE;
 
-typedef struct new_buffer
-{
-       uint32 ptr;
-       uint32 size;
-       prs_struct prs;
-       uint32 struct_start;
-       uint32 string_at_end;
-}
-NEW_BUFFER;
 
 typedef struct spool_q_getprinterdata
 {
@@ -1014,7 +991,7 @@ typedef struct spool_q_enumprinters
        uint32 servername_ptr;
        UNISTR2 servername;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPRINTERS;
@@ -1033,7 +1010,7 @@ PRINTER_INFO_CTR;
 
 typedef struct spool_r_enumprinters
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;          /* bytes needed */
        uint32 returned;        /* number of printers */
        WERROR status;
@@ -1045,7 +1022,7 @@ typedef struct spool_q_getprinter
 {
        POLICY_HND handle;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_GETPRINTER;
@@ -1063,7 +1040,7 @@ typedef struct printer_info_info
 
 typedef struct spool_r_getprinter
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 } SPOOL_R_GETPRINTER;
@@ -1137,7 +1114,7 @@ typedef struct spool_q_getprinterdriver2
        uint32 architecture_ptr;
        UNISTR2 architecture;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
        uint32 clientmajorversion;
        uint32 clientminorversion;
@@ -1146,7 +1123,7 @@ SPOOL_Q_GETPRINTERDRIVER2;
 
 typedef struct spool_r_getprinterdriver2
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 servermajorversion;
        uint32 serverminorversion;
@@ -1167,14 +1144,14 @@ typedef struct spool_q_addjob
 {
        POLICY_HND handle;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ADDJOB;
 
 typedef struct spool_r_addjob
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 }
@@ -1251,7 +1228,7 @@ typedef struct spool_q_enumjobs
        uint32 firstjob;
        uint32 numofjobs;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMJOBS;
@@ -1269,7 +1246,7 @@ typedef struct job_info_ctr_info
 
 typedef struct spool_r_enumjobs
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 returned;
        WERROR status;
@@ -1316,7 +1293,7 @@ typedef struct spool_q_enumports
        uint32 name_ptr;
        UNISTR2 name;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPORTS;
@@ -1335,7 +1312,7 @@ PORT_INFO_CTR;
 
 typedef struct spool_r_enumports
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;          /* bytes needed */
        uint32 returned;        /* number of printers */
        WERROR status;
@@ -1385,14 +1362,14 @@ typedef struct spool_q_enumprinterdrivers
        uint32 environment_ptr;
        UNISTR2 environment;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPRINTERDRIVERS;
 
 typedef struct spool_r_enumprinterdrivers
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 returned;
        WERROR status;
@@ -1420,14 +1397,14 @@ typedef struct spool_q_enumforms
 {
        POLICY_HND handle;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMFORMS;
 
 typedef struct spool_r_enumforms
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 numofforms;
        WERROR status;
@@ -1439,14 +1416,14 @@ typedef struct spool_q_getform
        POLICY_HND handle;
        UNISTR2 formname;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_GETFORM;
 
 typedef struct spool_r_getform
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 }
@@ -1601,28 +1578,6 @@ typedef struct spool_printer_driver_info_level
 SPOOL_PRINTER_DRIVER_INFO_LEVEL;
 
 
-/* this struct is undocumented */
-/* thanks to the ddk ... */
-typedef struct spool_user_level_1
-{
-       uint32 size;
-       uint32 client_name_ptr;
-       uint32 user_name_ptr;
-       uint32 build;
-       uint32 major;
-       uint32 minor;
-       uint32 processor;
-       UNISTR2 client_name;
-       UNISTR2 user_name;
-}
-SPOOL_USER_LEVEL_1;
-
-typedef struct spool_user_level
-{
-       SPOOL_USER_LEVEL_1 *user_level_1;
-}
-SPOOL_USER_LEVEL;
-
 typedef struct spool_q_setprinter
 {
        POLICY_HND handle;
@@ -1642,70 +1597,46 @@ typedef struct spool_r_setprinter
 }
 SPOOL_R_SETPRINTER;
 
-typedef struct spool_q_addprinter
-{
-       UNISTR2 server_name;
-       uint32 level;
-       SPOOL_PRINTER_INFO_LEVEL info;
-       DEVMODE_CTR devmode_ctr;
-       SEC_DESC_BUF *secdesc_ctr;
-       uint32 user_level;
-       SPOOL_USER_LEVEL user;
-}
-SPOOL_Q_ADDPRINTER;
-
-typedef struct spool_r_addprinter
-{
-       WERROR status;
-}
-SPOOL_R_ADDPRINTER;
+/********************************************/
 
-typedef struct spool_q_deleteprinter
-{
+typedef struct {
        POLICY_HND handle;
-}
-SPOOL_Q_DELETEPRINTER;
+} SPOOL_Q_DELETEPRINTER;
 
-typedef struct spool_r_deleteprinter
-{
+typedef struct {
        POLICY_HND handle;
        WERROR status;
-}
-SPOOL_R_DELETEPRINTER;
+} SPOOL_R_DELETEPRINTER;
 
-typedef struct spool_q_abortprinter
-{
+/********************************************/
+
+typedef struct {
        POLICY_HND handle;
-}
-SPOOL_Q_ABORTPRINTER;
+} SPOOL_Q_ABORTPRINTER;
 
-typedef struct spool_r_abortprinter
-{
+typedef struct {
        WERROR status;
-}
-SPOOL_R_ABORTPRINTER;
+} SPOOL_R_ABORTPRINTER;
 
 
-typedef struct spool_q_addprinterex
-{
-       uint32 server_name_ptr;
-       UNISTR2 server_name;
+/********************************************/
+
+typedef struct {
+       UNISTR2 *server_name;
        uint32 level;
        SPOOL_PRINTER_INFO_LEVEL info;
        DEVMODE_CTR devmode_ctr;
        SEC_DESC_BUF *secdesc_ctr;
        uint32 user_switch;
        SPOOL_USER_CTR user_ctr;
-}
-SPOOL_Q_ADDPRINTEREX;
+} SPOOL_Q_ADDPRINTEREX;
 
-typedef struct spool_r_addprinterex
-{
+typedef struct {
        POLICY_HND handle;
        WERROR status;
-}
-SPOOL_R_ADDPRINTEREX;
+} SPOOL_R_ADDPRINTEREX;
 
+/********************************************/
 
 typedef struct spool_q_addprinterdriver
 {
@@ -1758,14 +1689,14 @@ typedef struct spool_q_getprinterdriverdirectory
        uint32 environment_ptr;
        UNISTR2 environment;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_GETPRINTERDRIVERDIR;
 
 typedef struct spool_r_getprinterdriverdirectory
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 }
@@ -1795,7 +1726,7 @@ typedef struct spool_q_enumprintprocessors
        uint32 environment_ptr;
        UNISTR2 environment;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPRINTPROCESSORS;
@@ -1808,7 +1739,7 @@ PRINTPROCESSOR_1;
 
 typedef struct spool_r_enumprintprocessors
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 returned;
        WERROR status;
@@ -1822,7 +1753,7 @@ typedef struct spool_q_enumprintprocdatatypes
        uint32 processor_ptr;
        UNISTR2 processor;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPRINTPROCDATATYPES;
@@ -1835,7 +1766,7 @@ PRINTPROCDATATYPE_1;
 
 typedef struct spool_r_enumprintprocdatatypes
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 returned;
        WERROR status;
@@ -1861,14 +1792,14 @@ typedef struct spool_q_enumprintmonitors
        uint32 name_ptr;
        UNISTR2 name;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_ENUMPRINTMONITORS;
 
 typedef struct spool_r_enumprintmonitors
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        uint32 returned;
        WERROR status;
@@ -1996,7 +1927,7 @@ typedef struct spool_q_getjob
        POLICY_HND handle;
        uint32 jobid;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_GETJOB;
@@ -2016,7 +1947,7 @@ PJOB_INFO;
 
 typedef struct spool_r_getjob
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 }
@@ -2217,14 +2148,14 @@ typedef struct spool_q_getprintprocessordirectory
        UNISTR2 name;
        UNISTR2 environment;
        uint32 level;
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 offered;
 }
 SPOOL_Q_GETPRINTPROCESSORDIRECTORY;
 
 typedef struct spool_r_getprintprocessordirectory
 {
-       NEW_BUFFER *buffer;
+       RPC_BUFFER *buffer;
        uint32 needed;
        WERROR status;
 }
index 5ebb77a8c217d1055f9b8353e37ecc9562b690fb..f84054b878bc355348116e88fd935d67b55a8a60 100644 (file)
@@ -29,6 +29,7 @@
 #define SRV_NET_FILE_ENUM          0x09
 #define SRV_NET_FILE_CLOSE         0x0b
 #define SRV_NET_SESS_ENUM          0x0c
+#define SRV_NET_SESS_DEL           0x0d
 #define SRV_NET_SHARE_ADD          0x0e
 #define SRV_NET_SHARE_ENUM_ALL     0x0f
 #define SRV_NET_SHARE_GET_INFO     0x10
@@ -193,6 +194,27 @@ typedef struct r_net_sess_enum_info
 
 } SRV_R_NET_SESS_ENUM;
 
+/* SRV_Q_NET_SESS_DEL */
+typedef struct q_net_sess_del
+{
+       uint32 ptr_srv_name;         /* pointer (to server name?) */
+       UNISTR2 uni_srv_name;        /* server name */
+
+       uint32 ptr_cli_name;         /* pointer (to qualifier name) */
+       UNISTR2 uni_cli_name;        /* qualifier name "\\qualifier" */
+
+       uint32 ptr_user_name;         /* pointer (to user name */
+       UNISTR2 uni_user_name;        /* user name */
+
+} SRV_Q_NET_SESS_DEL;
+
+/* SRV_R_NET_SESS_DEL */
+typedef struct r_net_sess_del
+{
+       WERROR status;               /* return status */
+
+} SRV_R_NET_SESS_DEL;
+
 /* CONN_INFO_0 (pointers to level 0 connection info strings) */
 typedef struct ptr_conn_info0
 {
diff --git a/source/include/rpc_svcctl.h b/source/include/rpc_svcctl.h
new file mode 100644 (file)
index 0000000..90b90bd
--- /dev/null
@@ -0,0 +1,246 @@
+/* 
+   Unix SMB/CIFS implementation.
+   SMB parameters and setup
+   Copyright (C) Andrew Tridgell              1992-1997,
+   Copyright (C) Gerald (Jerry) Carter        2005
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
+#define _RPC_SVCCTL_H 
+
+
+/* svcctl pipe */
+
+#define SVCCTL_CLOSE_SERVICE                   0x00
+#define SVCCTL_CONTROL_SERVICE                 0x01
+#define SVCCTL_QUERY_STATUS                    0x06
+#define SVCCTL_ENUM_DEPENDENT_SERVICES_W       0x0d
+#define SVCCTL_ENUM_SERVICES_STATUS_W          0x0e
+#define SVCCTL_OPEN_SCMANAGER_W                        0x0f
+#define SVCCTL_OPEN_SERVICE_W                  0x10
+#define SVCCTL_QUERY_SERVICE_CONFIG_W          0x11
+#define SVCCTL_START_SERVICE_W                 0x13
+#define SVCCTL_GET_DISPLAY_NAME                        0x14
+#define SVCCTL_QUERY_SERVICE_CONFIG2_W         0x27
+
+/* ANSI versions not implemented currently 
+#define SVCCTL_ENUM_SERVICES_STATUS_A          0x0e
+#define SVCCTL_OPEN_SCMANAGER_A                        0x1b
+*/
+
+/* SERVER_STATUS - type */
+
+#define SVCCTL_TYPE_WIN32              0x00000030
+#define SVCCTL_TYPE_DRIVER             0x0000000f
+
+/* SERVER_STATUS - state */
+#define SVCCTL_STATE_ACTIVE            0x00000001
+#define SVCCTL_STATE_INACTIVE          0x00000002
+#define SVCCTL_STATE_ALL               ( SVCCTL_STATE_ACTIVE | SVCCTL_STATE_INACTIVE )
+
+/* SERVER_STATUS - CurrentState */
+
+#define SVCCTL_STOPPED                 0x00000001
+#define SVCCTL_START_PENDING           0x00000002
+#define SVCCTL_STOP_PENDING            0x00000003
+#define SVCCTL_RUNNING                 0x00000004
+#define SVCCTL_CONTINUE_PENDING                0x00000005
+#define SVCCTL_PAUSE_PENDING           0x00000006
+#define SVCCTL_PAUSED                  0x00000007
+
+/* SERVER_STATUS - ControlAccepted */
+
+#define SVCCTL_ACCEPT_STOP                     0x00000001
+#define SVCCTL_ACCEPT_PAUSE_CONTINUE           0x00000002
+#define SVCCTL_ACCEPT_SHUTDOWN                 0x00000004
+#define SVCCTL_ACCEPT_PARAMCHANGE              0x00000008
+#define SVCCTL_ACCEPT_NETBINDCHANGE            0x00000010
+#define SVCCTL_ACCEPT_HARDWAREPROFILECHANGE    0x00000020
+#define SVCCTL_ACCEPT_POWEREVENT               0x00000040
+
+/* Service Controls */
+
+#define SVCCTL_CONTROL_STOP                    0x00000001
+#define SVCCTL_CONTROL_PAUSE                   0x00000002
+#define SVCCTL_CONTROL_CONTINUE                        0x00000003
+
+/* utility structures for RPCs */
+
+typedef struct {
+       uint32 type;
+       uint32 state;
+       uint32 controls_accepted;
+       uint32 win32_exit_code;
+       uint32 service_exit_code;
+       uint32 check_point;
+       uint32 wait_hint;
+} SERVICE_STATUS;
+
+typedef struct {
+       UNISTR servicename;
+       UNISTR displayname;
+       SERVICE_STATUS status;
+} ENUM_SERVICES_STATUS;
+
+typedef struct {
+       uint32 service_type;
+       uint32 start_type;
+       uint32 error_control;
+       UNISTR2 *executablepath;
+       UNISTR2 *loadordergroup;
+       uint32 tag_id;
+       UNISTR2 *dependencies;
+       UNISTR2 *startname;
+       UNISTR2 *displayname;
+} SERVICE_CONFIG;
+
+
+/* rpc structures */
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+} SVCCTL_Q_CLOSE_SERVICE;
+
+typedef struct {
+       WERROR status;
+} SVCCTL_R_CLOSE_SERVICE;
+
+/**************************/
+
+typedef struct {
+       UNISTR2 *servername;
+       UNISTR2 *database; 
+       uint32 access;
+} SVCCTL_Q_OPEN_SCMANAGER;
+
+typedef struct {
+       POLICY_HND handle;
+       WERROR status;
+} SVCCTL_R_OPEN_SCMANAGER;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       UNISTR2 servicename;
+       uint32  display_name_len;
+} SVCCTL_Q_GET_DISPLAY_NAME;
+
+typedef struct {
+       UNISTR2 displayname;
+       uint32 display_name_len;
+       WERROR status;
+} SVCCTL_R_GET_DISPLAY_NAME;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       UNISTR2 servicename;
+       uint32 access;
+} SVCCTL_Q_OPEN_SERVICE;
+
+typedef struct {
+       POLICY_HND handle;
+       WERROR status;
+} SVCCTL_R_OPEN_SERVICE;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       uint32 parmcount;
+       UNISTR4_ARRAY *parameters;
+} SVCCTL_Q_START_SERVICE;
+
+typedef struct {
+       WERROR status;
+} SVCCTL_R_START_SERVICE;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       uint32 control;
+} SVCCTL_Q_CONTROL_SERVICE;
+
+typedef struct {
+       SERVICE_STATUS svc_status;
+       WERROR status;
+} SVCCTL_R_CONTROL_SERVICE;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+} SVCCTL_Q_QUERY_STATUS;
+
+typedef struct {
+       SERVICE_STATUS svc_status;
+       WERROR status;
+} SVCCTL_R_QUERY_STATUS;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       uint32 type;
+       uint32 state;
+       uint32 buffer_size;
+       uint32 *resume;
+} SVCCTL_Q_ENUM_SERVICES_STATUS;
+
+typedef struct {
+       RPC_BUFFER buffer;
+       uint32 needed;
+       uint32 returned;
+       uint32 *resume;
+       WERROR status;
+} SVCCTL_R_ENUM_SERVICES_STATUS;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       uint32 state;
+       uint32 buffer_size;
+} SVCCTL_Q_ENUM_DEPENDENT_SERVICES;
+
+typedef struct {
+       RPC_BUFFER buffer;
+       uint32 needed;
+       uint32 returned;
+       WERROR status;
+} SVCCTL_R_ENUM_DEPENDENT_SERVICES;
+
+/**************************/
+
+typedef struct {
+       POLICY_HND handle;
+       uint32 buffer_size;
+} SVCCTL_Q_QUERY_SERVICE_CONFIG;
+
+typedef struct {
+       SERVICE_CONFIG config;
+       uint32 needed;
+       WERROR status;
+} SVCCTL_R_QUERY_SERVICE_CONFIG;
+
+#endif /* _RPC_SVCCTL_H */
+
index 91ec52df2375b7c7c3c52a1b67a4f1051852187a..f96d79fd06367fea4485e64b73ac2c53932b7bf2 100644 (file)
@@ -103,6 +103,7 @@ typedef int BOOL;
 #define DOS_OPEN_RDONLY 0
 #define DOS_OPEN_WRONLY 1
 #define DOS_OPEN_RDWR 2
+#define DOS_OPEN_EXEC 3
 #define DOS_OPEN_FCB 0xF
 
 /* define shifts and masks for share and open modes. */
@@ -193,6 +194,9 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
 #define PIPE_NETDFS   "\\PIPE\\netdfs"
 #define PIPE_ECHO     "\\PIPE\\rpcecho"
 #define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
+#define PIPE_EPM      "\\PIPE\\epmapper"
+#define PIPE_SVCCTL   "\\PIPE\\svcctl"
+#define PIPE_EVENTLOG "\\PIPE\\eventlog"
 
 #define PIPE_NETLOGON_PLAIN "\\NETLOGON"
 
@@ -207,7 +211,9 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
 #define PI_NETDFS              8
 #define PI_ECHO                9
 #define PI_SHUTDOWN            10
-#define PI_MAX_PIPES           11
+#define PI_SVCCTL              11
+#define PI_EVENTLOG            12
+#define PI_MAX_PIPES           13
 
 /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
 typedef struct nttime_info
@@ -281,10 +287,28 @@ typedef struct sid_info
 
 } DOM_SID;
 
-typedef struct sid_list {
-       uint32 count;
-       DOM_SID *list;
-} SID_LIST;
+/* Some well-known SIDs */
+extern const DOM_SID global_sid_World_Domain;
+extern const DOM_SID global_sid_World;
+extern const DOM_SID global_sid_Creator_Owner_Domain;
+extern const DOM_SID global_sid_NT_Authority;
+extern const DOM_SID global_sid_System;
+extern const DOM_SID global_sid_NULL;
+extern const DOM_SID global_sid_Authenticated_Users;
+extern const DOM_SID global_sid_Network;
+extern const DOM_SID global_sid_Creator_Owner;
+extern const DOM_SID global_sid_Creator_Group;
+extern const DOM_SID global_sid_Anonymous;
+extern const DOM_SID global_sid_Builtin;
+extern const DOM_SID global_sid_Builtin_Administrators;
+extern const DOM_SID global_sid_Builtin_Users;
+extern const DOM_SID global_sid_Builtin_Guests;
+extern const DOM_SID global_sid_Builtin_Power_Users;
+extern const DOM_SID global_sid_Builtin_Account_Operators;
+extern const DOM_SID global_sid_Builtin_Server_Operators;
+extern const DOM_SID global_sid_Builtin_Print_Operators;
+extern const DOM_SID global_sid_Builtin_Backup_Operators;
+extern const DOM_SID global_sid_Builtin_Replicator;
 
 /*
  * The complete list of SIDS belonging to this user.
@@ -355,14 +379,14 @@ typedef struct time_info
 } UTIME;
 
 /* Structure used when SMBwritebmpx is active */
-typedef struct
-{
-  size_t wr_total_written; /* So we know when to discard this */
-  int32 wr_timeout;
-  int32 wr_errclass;
-  int32 wr_error; /* Cached errors */
-  BOOL  wr_mode; /* write through mode) */
-  BOOL  wr_discard; /* discard all further data */
+typedef struct {
+       size_t wr_total_written; /* So we know when to discard this */
+       int32 wr_timeout;
+       int32 wr_errclass; /* Cached errors */
+       int32 wr_error; /* Cached errors */
+       NTSTATUS wr_status; /* Cached errors */
+       BOOL  wr_mode; /* write through mode) */
+       BOOL  wr_discard; /* discard all further data */
 } write_bmpx_struct;
 
 typedef struct write_cache
@@ -388,6 +412,7 @@ typedef struct files_struct {
        int fnum;
        struct connection_struct *conn;
        int fd;
+       unsigned int num_smb_operations;
        uint16 rap_print_jobid;
        SMB_DEV_T dev;
        SMB_INO_T inode;
@@ -509,6 +534,7 @@ typedef struct connection_struct
        time_t lastused;
        BOOL used;
        int num_files_open;
+       unsigned int num_smb_operations; /* Count of smb operations on this tree. */
 
        BOOL case_sensitive;
        BOOL case_preserve;
@@ -1382,13 +1408,6 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
  */
 #define COPYBUF_SIZE (8*1024)
 
-/* 
- * Values used to override error codes. 
- */
-extern int unix_ERR_class;
-extern int unix_ERR_code;
-extern NTSTATUS unix_ERR_ntstatus;
-
 /*
  * Used in chaining code.
  */
@@ -1717,6 +1736,11 @@ struct ea_struct {
        DATA_BLOB value;
 };
 
+struct ea_list {
+       struct ea_list *next, *prev;
+       struct ea_struct ea;
+};
+
 /* EA names used internally in Samba. KEEP UP TO DATE with prohibited_ea_names in trans2.c !. */
 #define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
 /* EA to use for DOS attributes */
index de8d5b011f047d9a6356c96de04b5a5fdee832b3..6d1e382bb8281b270ebb121fecc3c0d1414cc298 100644 (file)
@@ -43,7 +43,7 @@
  * @note You are explicitly allowed to pass NULL pointers -- they will
  * always be ignored.
  **/
-#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(CONST_DISCARD(void *, (x))); x=NULL;} } while(0)
 #endif
 
 /* zero a structure */
 #define OPEN_CONN(conn)    ((conn) && (conn)->open)
 #define IS_IPC(conn)       ((conn) && (conn)->ipc)
 #define IS_PRINT(conn)       ((conn) && (conn)->printer)
+/* you must add the following extern declaration to files using this macro
+ * extern struct current_user current_user;
+ */
 #define FSP_BELONGS_CONN(fsp,conn) do {\
-                       extern struct current_user current_user;\
                        if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
                                return(ERROR_DOS(ERRDOS,ERRbadfid));\
                        } while(0)
 
 #define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
 
+/* you must add the following extern declaration to files using this macro
+ * extern struct current_user current_user;
+ */
 #define CHECK_FSP(fsp,conn) do {\
-                       extern struct current_user current_user;\
                        if (!FNUM_OK(fsp,conn)) \
                                return(ERROR_DOS(ERRDOS,ERRbadfid)); \
                        else if((fsp)->fd == -1) \
                                return(ERROR_DOS(ERRDOS,ERRbadaccess));\
+                       (fsp)->num_smb_operations++;\
                        } while(0)
 
 #define CHECK_READ(fsp) if (!(fsp)->can_read) \
 #define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
                                return(ERROR_DOS(ERRDOS,ERRbadaccess))
 
-#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
-                               return(CACHED_ERROR(fsp))
-
 #define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
                                NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
 
 #define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
 #define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
 
-/* Macro to cache an error in a write_bmpx_struct */
-#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
-                w->wr_discard = True, -1)
 /* Macro to test if an error has been cached for this fnum */
 #define HAS_CACHED_ERROR(fsp) ((fsp)->wbmpx_ptr && \
                 (fsp)->wbmpx_ptr->wr_discard)
 /* Macro to turn the cached error into an error packet */
 #define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__)
 
-/* these are the datagram types */
-#define DGRAM_DIRECT_UNIQUE 0x10
-
-#define ERROR_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,False,__LINE__,__FILE__)
-#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,True,__LINE__,__FILE__)
-#define ERROR_NT(status) error_packet(outbuf,status,0,0,False,__LINE__,__FILE__)
-#define ERROR_BOTH(status,class,code) error_packet(outbuf,status,class,code,False,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
+#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_INVALID,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
+#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
+#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
 
 /* this is how errors are generated */
-#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
+#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
+
+/* these are the datagram types */
+#define DGRAM_DIRECT_UNIQUE 0x10
 
 #define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x))
 
@@ -297,6 +297,8 @@ copy an IP address from one buffer to another
 #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array_((ctx),(ptr),sizeof(type),(count))
 
 #define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem_((ps),sizeof(type),(count))
+#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem_((ps),(size),1)
+
 
 /* Get medieval on our ass about malloc.... */
 
@@ -345,6 +347,7 @@ copy an IP address from one buffer to another
 #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array((ctx),(ptr),sizeof(type),(count))
 
 #define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem((ps),sizeof(type),(count))
+#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem((ps),(size),1)
 
 /* Regular malloc code. */
 
@@ -356,4 +359,17 @@ copy an IP address from one buffer to another
 
 #endif
 
+#define ADD_TO_ARRAY(mem_ctx, type, elem, array, num) \
+do { \
+       *(array) = ((mem_ctx) != NULL) ? \
+               TALLOC_REALLOC_ARRAY(mem_ctx, (*(array)), type, (*(num))+1) : \
+               SMB_REALLOC_ARRAY((*(array)), type, (*(num))+1); \
+       SMB_ASSERT((*(array)) != NULL); \
+       (*(array))[*(num)] = (elem); \
+       (*(num)) += 1; \
+} while (0)
+
+#define ADD_TO_LARGE_ARRAY(mem_ctx, type, elem, array, num, size) \
+       add_to_large_array((mem_ctx), sizeof(type), &(elem), (void **)(array), (num), (size));
+
 #endif /* _SMB_MACROS_H */
index e6a6a1b7c6825bfc2fc177374e24b30689d2572b..b54b3f432563cc15fceac593d7bc671ce20e2eac 100644 (file)
@@ -185,5 +185,6 @@ struct ldapsam_privates {
 struct smbldap_state;
 
 #define LDAP_CONNECT_DEFAULT_TIMEOUT   15
+#define LDAP_PAGE_SIZE 1024
 
 #endif /* _SMBLDAP_H */
index 68358344f4e071a3184688b95b29590458cfd80c..2aae1137dd784d1479d38b0de3d5a63757bf27d5 100644 (file)
@@ -226,6 +226,9 @@ Byte offset   Type     name                description
 #define SMB_QUERY_FILE_STREAM_INFO     0x109
 #define SMB_QUERY_COMPRESSION_INFO     0x10b
 
+#define SMB_FIND_INFO_STANDARD                 1
+#define SMB_FIND_EA_SIZE                       2
+#define SMB_FIND_EA_LIST                       3
 #define SMB_FIND_FILE_DIRECTORY_INFO           0x101
 #define SMB_FIND_FILE_FULL_DIRECTORY_INFO      0x102
 #define SMB_FIND_FILE_NAMES_INFO               0x103
@@ -437,6 +440,9 @@ Offset Size         Name
 #define SMB_QUERY_XATTR                0x205 /* need for non-user XATTRs */
 #define SMB_QUERY_ATTR_FLAGS           0x206 /* chflags, chattr */
 #define SMB_SET_ATTR_FLAGS             0x206 
+#define SMB_QUERY_POSIX_PERMISSION     0x207
+#define SMB_QUERY_POSIX_LOCK          0x208
+#define SMB_SET_POSIX_LOCK            0x208
 
 /* Transact 2 Find First levels */
 #define SMB_FIND_FILE_UNIX             0x202
@@ -461,6 +467,12 @@ Offset Size         Name
 
 #define CIFS_UNIX_FCNTL_LOCKS_CAP           0x1
 #define CIFS_UNIX_POSIX_ACLS_CAP            0x2
+#define CIFS_UNIX_XATTTR_CAP               0x4 /* for support of other xattr
+                                               namespaces such as system,
+                                               security and trusted */
+#define CIFS_UNIX_EXTATTR_CAP              0x8 /* for support of chattr
+                                               (chflags) and lsattr */
+                                               
 
 #define SMB_QUERY_POSIX_FS_INFO     0x201
 
index d3422f0d78ac03d599ac2fc2898455ca083bf1be..d8f7fc8c933198e88cdb1c871fac21bc455140dd 100644 (file)
@@ -231,7 +231,7 @@ const char *lang_msg(const char *msgid)
 void lang_msg_free(const char *msgstr)
 {
        if (!tdb) return;
-       free((void *)msgstr);
+       free(CONST_DISCARD(void *, msgstr));
 }
 
 
@@ -248,7 +248,7 @@ const char *lang_msg_rotate(const char *msgid)
        static pstring bufs[NUM_LANG_BUFS];
        static int next;
 
-       msgstr = (char *)lang_msg(msgid);
+       msgstr = CONST_DISCARD(char *, lang_msg(msgid));
        if (!msgstr) return msgid;
 
        pstrcpy(bufs[next], msgstr);
index fcc795d1f266c15f80f3160990b4595a00a1f9e9..d8e40c99f76aa6790d0e4c42361f36660ac90c6e 100644 (file)
@@ -133,7 +133,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
 /* client_match - match host name and address against token */
 static BOOL client_match(const char *tok, const char *item)
 {
-       const char **client = (const char **)item;
+        const char **client = CONST_ADD(const char **, item);
        BOOL match;
        char invalid_char = '\0';
 
index 72d6e77ddda8fd5b2b681ec06f25490a742f5fe5..423dc1675a6d9b9cba04145de964586b0aa46e2a 100644 (file)
@@ -24,14 +24,6 @@ static TDB_CONTEXT *tdb;
 
 #define DATABASE_VERSION 2
 
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Builtin_Administrators;
-extern DOM_SID global_sid_Builtin_Account_Operators;
-extern DOM_SID global_sid_Builtin_Server_Operators;
-extern DOM_SID global_sid_Builtin_Print_Operators;
-extern DOM_SID global_sid_Builtin_Backup_Operators;
-
-
 /****************************************************************************
  Set default for a field if it is empty
 ****************************************************************************/
index b9b9d90db670e017905b597a90bd6eac76b9530d..4fbad0f3d18aca24cd6227182b39f307a448b670 100644 (file)
@@ -1268,6 +1268,21 @@ size_t pull_utf8_allocate(char **dest, const char *src)
        return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest, True);
 }
  
+/**
+ * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
+ *
+ * @param dest always set at least to NULL 
+ *
+ * @returns The number of bytes occupied by the string in the destination
+ **/
+
+size_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+{
+       size_t src_len = strlen(src)+1;
+       *dest = NULL;
+       return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, True);
+}
+
 /**
  Copy a string from a char* src to a unicode or ascii
  dos codepage destination choosing unicode or ascii based on the 
index a1c3af2d492e8e47a2c6ea96801f0e3e52c103e8..35805f861c5f4d0b75a8e7c89f29827abbffa27f 100644 (file)
@@ -47,7 +47,7 @@ DATA_BLOB data_blob(const void *p, size_t length)
        if (p) {
                ret.data = smb_xmemdup(p, length);
        } else {
-               ret.data = SMB_XMALLOC_ARRAY(char, length);
+               ret.data = SMB_XMALLOC_ARRAY(unsigned char, length);
        }
        ret.length = length;
        ret.free = free_data_blob;
index d58165fed03271457f6ec31de9796215ce891d47..f23e4351c02ee97940c7e7fe64d7dae0efb07f6c 100644 (file)
@@ -135,7 +135,7 @@ static size_t sys_iconv(void *cd,
 {
 #ifdef HAVE_NATIVE_ICONV
        size_t ret = iconv((iconv_t)cd, 
-                          (char **)inbuf, inbytesleft, 
+                          CONST_DISCARD(char **, inbuf), inbytesleft, 
                           outbuf, outbytesleft);
        if (ret == (size_t)-1) {
                int saved_errno = errno;
index a0cbfd2ee21cbad8cdcbe119524727484420e93c..c7cf54d26b5426af80c9cc035c83efabae0a6734 100644 (file)
@@ -146,7 +146,7 @@ static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
        return -1;
 }
 
-int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol, 
+int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
               BOOL is_case_sensitive)
 {
        wpstring p, s;
@@ -179,7 +179,7 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot
                return -1;
        }
 
-       if (protocol <= PROTOCOL_LANMAN2) {
+       if (translate_pattern) {
                /*
                  for older negotiated protocols it is possible to
                  translate the pattern to produce a "new style"
index 8b5348e1f25026eaf69589258b83557865cc39c9..e01561de06f4d2dea1dc96da2be2bfd0e8bfd556 100644 (file)
@@ -95,7 +95,12 @@ PRIVS privs[] = {
        {SE_END,                        "",                                     ""}
 };
 
-typedef struct priv_sid_list {
+typedef struct {
+       int count;
+       DOM_SID *list;
+} SID_LIST;
+
+typedef struct {
        SE_PRIV privilege;
        SID_LIST sids;
 } PRIV_SID_LIST;
@@ -492,7 +497,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
                return 0;
        }
 
-       add_sid_to_array( &sid, &priv->sids.list, &priv->sids.count );
+       add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count );
        
        return 0;
 }
index e44d9aa940ed763c5ee2aea7570855cdd513b4c9..c550dcce31190a32d05db97e60823784e06bdf6a 100644 (file)
@@ -57,7 +57,7 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
  Sets up a SEC_ACE structure.
 ********************************************************************/
 
-void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
 {
        t->type = type;
        t->flags = flag;
index 686a4edf77ccb60f9a6ba9e661abc484cc3a0bfa..ace0aee866464e2d0ba8a8169b750d6ccb44ffd8 100644 (file)
@@ -179,7 +179,7 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU
 ********************************************************************/
 
 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
-                       DOM_SID *owner_sid, DOM_SID *grp_sid,
+                       const DOM_SID *owner_sid, const DOM_SID *grp_sid,
                        SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
 {
        SEC_DESC *dst;
@@ -269,7 +269,7 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
  Creates a SEC_DESC structure with typical defaults.
 ********************************************************************/
 
-SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
+SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
                                 SEC_ACL *dacl, size_t *sd_size)
 {
        return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
index f3d119bdb153e488a41b70af359547adae7e0de4..2e55f9753dbea30d8deed99fd2eb288f1d967c41 100644 (file)
@@ -99,20 +99,23 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s
                        FD_ZERO(writefds);
                if (errorfds)
                        FD_ZERO(errorfds);
-       }
-
-       if (FD_ISSET(select_pipe[0], readfds2)) {
+       } else if (FD_ISSET(select_pipe[0], readfds2)) {
                char c;
                saved_errno = errno;
                if (read(select_pipe[0], &c, 1) == 1) {
                        pipe_read++;
-               }
-               errno = saved_errno;
-               FD_CLR(select_pipe[0], readfds2);
-               ret--;
-               if (ret == 0) {
+                       /* Mark Weaver <mark-clist@npsl.co.uk> pointed out a critical
+                          fix to ensure we don't lose signals. We must always
+                          return -1 when the select pipe is set, otherwise if another
+                          fd is also ready (so ret == 2) then we used to eat the
+                          byte in the pipe and lose the signal. JRA.
+                       */
                        ret = -1;
                        errno = EINTR;
+               } else {
+                       FD_CLR(select_pipe[0], readfds2);
+                       ret--;
+                       errno = saved_errno;
                }
        }
 
@@ -167,7 +170,12 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf
                        ptval->tv_usec = tdif % 1000000;
                }
 
-               ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
+               /* We must use select and not sys_select here. If we use
+                  sys_select we'd lose the fact a signal occurred when sys_select
+                  read a byte from the pipe. Fix from Mark Weaver
+                  <mark-clist@npsl.co.uk>
+               */
+               ret = select(maxfd, readfds2, writefds2, errorfds2, ptval);
        } while (ret == -1 && errno == EINTR);
 
        if (readfds)
index 68084b04045e5b3f1c871758fd8bde1d7a4ce9d2..e2d78e0ecca62bb6baaa9bcc5e2afe0153111f90 100644 (file)
@@ -856,6 +856,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
        }
 
        ldap_state->num_failures = 0;
+       ldap_state->paged_results = False;
 
        ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
 
@@ -864,7 +865,8 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
        }
 
        DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
-       DEBUGADD(3, ("ldap_connect_system: LDAP server %s support paged results\n", ldap_state->paged_results?"does":"does not"));
+       DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n", 
+               ldap_state->paged_results ? "does" : "does not"));
        return rc;
 }
 
@@ -1022,20 +1024,22 @@ static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
 /*********************************************************************
  ********************************************************************/
 
-int smbldap_search(struct smbldap_state *ldap_state, 
-                  const char *base, int scope, const char *filter, 
-                  const char *attrs[], int attrsonly, 
-                  LDAPMessage **res)
+static int smbldap_search_ext(struct smbldap_state *ldap_state,
+                             const char *base, int scope, const char *filter, 
+                             const char *attrs[], int attrsonly,
+                             LDAPControl **sctrls, LDAPControl **cctrls, 
+                             int sizelimit, LDAPMessage **res)
 {
        int             rc = LDAP_SERVER_DOWN;
        int             attempts = 0;
        char           *utf8_filter;
        time_t          endtime = time(NULL)+lp_ldap_timeout();
+       struct          timeval timeout;
 
        SMB_ASSERT(ldap_state);
        
-       DEBUG(5,("smbldap_search: base => [%s], filter => [%s], scope => [%d]\n",
-               base, filter, scope));
+       DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
+                "scope => [%d]\n", base, filter, scope));
 
        if (ldap_state->last_rebind.tv_sec > 0) {
                struct timeval  tval;
@@ -1053,9 +1057,10 @@ int smbldap_search(struct smbldap_state *ldap_state,
 
                if (sleep_time > 0) {
                        /* we wait for the LDAP replication */
-                       DEBUG(5,("smbldap_search: waiting %d milliseconds for LDAP replication.\n",sleep_time));
+                       DEBUG(5,("smbldap_search_ext: waiting %d milliseconds "
+                                "for LDAP replication.\n",sleep_time));
                        smb_msleep(sleep_time);
-                       DEBUG(5,("smbldap_search: go on!\n"));
+                       DEBUG(5,("smbldap_search_ext: go on!\n"));
                }
                ZERO_STRUCT(ldap_state->last_rebind);
        }
@@ -1064,11 +1069,138 @@ int smbldap_search(struct smbldap_state *ldap_state,
                return LDAP_NO_MEMORY;
        }
 
+       /* Setup timeout for the ldap_search_ext_s call - local and remote. */
+       timeout.tv_sec = lp_ldap_timeout();
+       timeout.tv_usec = 0;
+
+       /* Setup alarm timeout.... Do we need both of these ? JRA.
+        * Yes, I think we do need both of these. The server timeout only
+        * covers the case where the server's operation takes too long. It
+        * does not cover the case where the request hangs on its way to the
+        * server. The server side timeout is not strictly necessary, it's
+        * just a bit more kind to the server. VL. */
+
+       got_alarm = 0;
+       CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+       alarm(lp_ldap_timeout());
+       /* End setup timeout. */
+
        while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
-               rc = ldap_search_s(ldap_state->ldap_struct, base, scope, 
-                                  utf8_filter, attrs, attrsonly, res);
-       
+               rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope, 
+                                      utf8_filter,
+                                      CONST_DISCARD(char **, attrs),
+                                      attrsonly, sctrls, cctrls, &timeout,
+                                      sizelimit, res);
+
        SAFE_FREE(utf8_filter);
+
+       /* Teardown timeout. */
+       CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+       alarm(0);
+
+       if (got_alarm != 0)
+               return LDAP_TIMELIMIT_EXCEEDED;
+
+       return rc;
+}
+
+int smbldap_search(struct smbldap_state *ldap_state, 
+                  const char *base, int scope, const char *filter, 
+                  const char *attrs[], int attrsonly, 
+                  LDAPMessage **res)
+{
+       return smbldap_search_ext(ldap_state, base, scope, filter, attrs,
+                                 attrsonly, NULL, NULL, LDAP_NO_LIMIT, res);
+}
+
+int smbldap_search_paged(struct smbldap_state *ldap_state, 
+                        const char *base, int scope, const char *filter, 
+                        const char **attrs, int attrsonly, int pagesize,
+                        LDAPMessage **res, void **cookie)
+{
+       LDAPControl     pr;
+       LDAPControl     **rcontrols;
+       LDAPControl     *controls[2] = { NULL, NULL};
+       BerElement      *cookie_be = NULL;
+       struct berval   *cookie_bv = NULL;
+       int             tmp = 0, i, rc;
+       BOOL            critical = True;
+
+       *res = NULL;
+
+       DEBUG(3,("smbldap_search_paged: base => [%s], filter => [%s],"
+                "scope => [%d], pagesize => [%d]\n",
+                base, filter, scope, pagesize));
+
+       cookie_be = ber_alloc_t(LBER_USE_DER);
+       if (cookie_be == NULL) {
+               DEBUG(0,("smbldap_create_page_control: ber_alloc_t returns "
+                        "NULL\n"));
+               return LDAP_NO_MEMORY;
+       }
+
+       /* construct cookie */
+       if (*cookie != NULL) {
+               ber_printf(cookie_be, "{iO}", (ber_int_t) pagesize, *cookie);
+               ber_bvfree(*cookie); /* don't need it from last time */
+               *cookie = NULL;
+       } else {
+               ber_printf(cookie_be, "{io}", (ber_int_t) pagesize, "", 0);
+       }
+       ber_flatten(cookie_be, &cookie_bv);
+
+       pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
+       pr.ldctl_iscritical = (char) critical;
+       pr.ldctl_value.bv_len = cookie_bv->bv_len;
+       pr.ldctl_value.bv_val = cookie_bv->bv_val;
+
+       controls[0] = &pr;
+       controls[1] = NULL;
+
+       rc = smbldap_search_ext(ldap_state, base, scope, filter, attrs, 
+                                0, controls, NULL, LDAP_NO_LIMIT, res);
+
+       ber_free(cookie_be, 1);
+       ber_bvfree(cookie_bv);
+
+       if (rc != 0) {
+               DEBUG(3,("smbldap_search_paged: smbldap_search_ext(%s) "
+                        "failed with [%s]\n", filter, ldap_err2string(rc)));
+               goto done;
+       }
+
+       DEBUG(3,("smbldap_search_paged: search was successfull\n"));
+
+       rc = ldap_parse_result(ldap_state->ldap_struct, *res, NULL, NULL, 
+                              NULL, NULL, &rcontrols,  0);
+       if (rc != 0) {
+               DEBUG(3,("smbldap_search_paged: ldap_parse_result failed " \
+                        "with [%s]\n", ldap_err2string(rc)));
+               goto done;
+       }
+
+       if (rcontrols == NULL)
+               goto done;
+
+       for (i=0; rcontrols[i]; i++) {
+
+               if (strcmp(ADS_PAGE_CTL_OID, rcontrols[i]->ldctl_oid) != 0)
+                       continue;
+
+               cookie_be = ber_init(&rcontrols[i]->ldctl_value);
+               ber_scanf(cookie_be,"{iO}", &tmp, &cookie_bv);
+               /* the berval is the cookie, but must be freed when it is all
+                  done */
+               if (cookie_bv->bv_len)
+                       *cookie=ber_bvdup(cookie_bv);
+               else
+                       *cookie=NULL;
+               ber_bvfree(cookie_bv);
+               ber_free(cookie_be, 1);
+               break;
+       }
+       ldap_controls_free(rcontrols);
+done:  
        return rc;
 }
 
@@ -1471,7 +1603,8 @@ static BOOL smbldap_check_root_dse(struct smbldap_state *ldap_state, const char
        }
 
        rc = ldap_search_s(ldap_state->ldap_struct, "", LDAP_SCOPE_BASE, 
-                          "(objectclass=*)", attrs, 0 , &msg);
+                          "(objectclass=*)", CONST_DISCARD(char **, attrs),
+                           0 , &msg);
 
        if (rc != LDAP_SUCCESS) {
                DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
index 615a8d73b0a36016381705b8a7fa99fdf026bb8a..af30e900ace87bba0e9f1b5730487f2128fb3b15 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 fstring local_machine="";
 fstring remote_arch="UNKNOWN";
 userdom_struct current_user_info;
@@ -800,7 +802,6 @@ char *alloc_sub_conn(connection_struct *conn, const char *str)
 
 void standard_sub_snum(int snum, char *str, size_t len)
 {
-       extern struct current_user current_user;
        static uid_t cached_uid = -1;
        static fstring cached_user;
        /* calling uidtoname() on every substitute would be too expensive, so
index 7434cbe35eea878021fa5bc3b7430b21629ebfc4..a2e5352aa5f802b8c02651e1cfdaeacd2ada286c 100644 (file)
@@ -1373,10 +1373,17 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
 {
 #if defined(HAVE_GETXATTR)
        return getxattr(path, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FILE)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_get_file(path, attrnamespace, attrname, value, size);
 #elif defined(HAVE_ATTR_GET)
        int retval, flags = 0;
        int valuelength = (int)size;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1393,10 +1400,17 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s
 {
 #if defined(HAVE_LGETXATTR)
        return lgetxattr(path, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_LINK)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_get_link(path, attrnamespace, attrname, value, size);
 #elif defined(HAVE_ATTR_GET)
        int retval, flags = ATTR_DONTFOLLOW;
        int valuelength = (int)size;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1413,10 +1427,17 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
 {
 #if defined(HAVE_FGETXATTR)
        return fgetxattr(filedes, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FD)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_get_fd(filedes, attrnamespace, attrname, value, size);
 #elif defined(HAVE_ATTR_GETF)
        int retval, flags = 0;
        int valuelength = (int)size;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1429,6 +1450,99 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
 #endif
 }
 
+#if defined(HAVE_EXTATTR_LIST_FILE)
+
+#define EXTATTR_PREFIX(s)      (s), (sizeof((s))-1)
+
+static struct {
+        int space;
+       const char *name;
+       size_t len;
+} 
+extattr[] = {
+       { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
+        { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
+};
+
+typedef union {
+       const char *path;
+       int filedes;
+} extattr_arg;
+
+static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
+{
+       ssize_t list_size, total_size = 0;
+       int i, t, len;
+       char *buf;
+       /* Iterate through extattr(2) namespaces */
+       for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
+               switch(type) {
+#if defined(HAVE_EXTATTR_LIST_FILE)
+                       case 0:
+                               list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
+                               break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_LINK)
+                       case 1:
+                               list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
+                               break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_FD)
+                       case 2:
+                               list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
+                               break;
+#endif
+                       default:
+                               errno = ENOSYS;
+                               return -1;
+               }
+               /* Some error happend. Errno should be set by the previous call */
+               if(list_size < 0)
+                       return -1;
+               /* No attributes */
+               if(list_size == 0)
+                       continue;
+               /* XXX: Call with an empty buffer may be used to calculate
+                  necessary buffer size. Unfortunately, we can't say, how
+                  many attributes were returned, so here is the potential
+                  problem with the emulation.
+               */
+               if(list == NULL) {
+                       /* Take the worse case of one char attribute names - 
+                          two bytes per name plus one more for sanity.
+                       */
+                       total_size += list_size + (list_size/2 + 1)*extattr[t].len;
+                       continue;
+               }
+               /* Count necessary offset to fit namespace prefixes */
+               len = 0;
+               for(i = 0; i < list_size; i += list[i] + 1)
+                       len += extattr[t].len;
+
+               total_size += list_size + len;
+               /* Buffer is too small to fit the results */
+               if(total_size > size) {
+                       errno = ERANGE;
+                       return -1;
+               }
+               /* Shift the results back, so we can prepend prefixes */
+               buf = memmove(list + len, list, list_size);
+
+               for(i = 0; i < list_size; i += len + 1) {
+                       len = buf[i];
+                       strncpy(list, extattr[t].name, extattr[t].len + 1);
+                       list += extattr[t].len;
+                       strncpy(list, buf + i + 1, len);
+                       list[len] = '\0';
+                       list += len + 1;
+               }
+               size -= total_size;
+       }
+       return total_size;
+}
+
+#endif
+
 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
 static char attr_buffer[ATTR_MAX_VALUELEN];
 
@@ -1501,6 +1615,10 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
 {
 #if defined(HAVE_LISTXATTR)
        return listxattr(path, list, size);
+#elif defined(HAVE_EXTATTR_LIST_FILE)
+       extattr_arg arg;
+       arg.path = path;
+       return bsd_attr_list(0, arg, list, size);
 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
        return irix_attr_list(path, 0, list, size, 0);
 #else
@@ -1513,6 +1631,10 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
 {
 #if defined(HAVE_LLISTXATTR)
        return llistxattr(path, list, size);
+#elif defined(HAVE_EXTATTR_LIST_LINK)
+       extattr_arg arg;
+       arg.path = path;
+       return bsd_attr_list(1, arg, list, size);
 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
        return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
 #else
@@ -1525,6 +1647,10 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size)
 {
 #if defined(HAVE_FLISTXATTR)
        return flistxattr(filedes, list, size);
+#elif defined(HAVE_EXTATTR_LIST_FD)
+       extattr_arg arg;
+       arg.filedes = filedes;
+       return bsd_attr_list(2, arg, list, size);
 #elif defined(HAVE_ATTR_LISTF)
        return irix_attr_list(NULL, filedes, list, size, 0);
 #else
@@ -1537,9 +1663,16 @@ int sys_removexattr (const char *path, const char *name)
 {
 #if defined(HAVE_REMOVEXATTR)
        return removexattr(path, name);
+#elif defined(HAVE_EXTATTR_DELETE_FILE)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_delete_file(path, attrnamespace, attrname);
 #elif defined(HAVE_ATTR_REMOVE)
        int flags = 0;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1554,9 +1687,16 @@ int sys_lremovexattr (const char *path, const char *name)
 {
 #if defined(HAVE_LREMOVEXATTR)
        return lremovexattr(path, name);
+#elif defined(HAVE_EXTATTR_DELETE_LINK)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_delete_link(path, attrnamespace, attrname);
 #elif defined(HAVE_ATTR_REMOVE)
        int flags = ATTR_DONTFOLLOW;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1571,9 +1711,16 @@ int sys_fremovexattr (int filedes, const char *name)
 {
 #if defined(HAVE_FREMOVEXATTR)
        return fremovexattr(filedes, name);
+#elif defined(HAVE_EXTATTR_DELETE_FD)
+       char *s;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       return extattr_delete_fd(filedes, attrnamespace, attrname);
 #elif defined(HAVE_ATTR_REMOVEF)
        int flags = 0;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
 
@@ -1593,9 +1740,18 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
 {
 #if defined(HAVE_SETXATTR)
        return setxattr(path, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_FILE)
+       char *s;
+       int retval = 0;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       retval = extattr_set_file(path, attrnamespace, attrname, value, size);
+       return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SET)
        int myflags = 0;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
        if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
@@ -1612,9 +1768,18 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
 {
 #if defined(HAVE_LSETXATTR)
        return lsetxattr(path, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_LINK)
+       char *s;
+       int retval = 0;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       retval = extattr_set_link(path, attrnamespace, attrname, value, size);
+       return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SET)
        int myflags = ATTR_DONTFOLLOW;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
        if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
@@ -1631,9 +1796,18 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
 {
 #if defined(HAVE_FSETXATTR)
        return fsetxattr(filedes, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_FD)
+       char *s;
+       int retval = 0;
+       int attrnamespace = (strncmp(name, "system", 6) == 0) ? 
+               EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+       const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+       retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
+       return (retval < 0) ? -1 : 0;
 #elif defined(HAVE_ATTR_SETF)
        int myflags = 0;
-       char *attrname = strchr(name,'.') +1;
+       char *attrname = strchr(name,'.') + 1;
        
        if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
        if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
index c83eecf17330eb767dae3bcc88811f09a2249f9c..f124983006d8a00bef66b548ed235c68a867a3c6 100644 (file)
@@ -178,10 +178,10 @@ BOOL getgroups_user(const char *user, gid_t primary_gid,
        groups = NULL;
 
        /* Add in primary group first */
-       add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+       add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
 
        for (i=0; i<max_grp; i++)
-               add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+               add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
 
        *ngroups = ngrp;
        *ret_groups = groups;
index cafe0654790b31abc2c3ab6744a2381576e78328..f5e21299b5a643b800e54706696d752a84f4ee17 100644 (file)
@@ -338,6 +338,19 @@ char *talloc_strdup(TALLOC_CTX *t, const char *p)
                return NULL;
 }
 
+/* strndup with a talloc */
+char *talloc_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t maxlen)
+{
+       size_t len = strnlen(str, maxlen);
+       void *ret = TALLOC(mem_ctx, len+1);
+
+       if (ret != NULL) {
+               memcpy(ret, str, len);
+               ((char *)ret)[len] = '\0';
+       }
+       return ret;
+}
+
 /** strdup_upper with a talloc */
 char *talloc_strdup_upper(TALLOC_CTX *t, const char *p)
 {
index 84004a099bebc2e561c1f0c7a994508386296918..9f94791b581dcd168042ea9017843f25d8d4fa53 100644 (file)
@@ -791,3 +791,25 @@ SMB_BIG_INT usec_time_diff(struct timeval *larget, struct timeval *smallt)
        SMB_BIG_INT sec_diff = larget->tv_sec - smallt->tv_sec;
        return (sec_diff * 1000000) + (SMB_BIG_INT)(larget->tv_usec - smallt->tv_usec);
 }
+
+
+/****************************************************************************
+ convert ASN.1 GeneralizedTime string to unix-time
+ returns 0 on failure; Currently ignores timezone. 
+****************************************************************************/
+time_t generalized_to_unix_time(const char *str)
+{ 
+       struct tm tm;
+
+       ZERO_STRUCT(tm);
+
+       if (sscanf(str, "%4d%2d%2d%2d%2d%2d", 
+                  &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 
+                  &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+               return 0;
+       }
+       tm.tm_year -= 1900;
+       tm.tm_mon -= 1;
+
+       return timegm(&tm);
+}
index 42ead313a9206c2046630f5b7836ad3bb2195133..52cf15da1e489052e9107ef1f97e43e683d74576 100644 (file)
 
 #include "includes.h"
 
+extern fstring local_machine;
+extern char *global_clobber_region_function;
+extern unsigned int global_clobber_region_line;
+extern fstring remote_arch;
+
 /* Max allowable allococation - 256mb - 0x10000000 */
 #define MAX_ALLOC_SIZE (1024*1024*256)
 
@@ -230,7 +235,6 @@ BOOL set_netbios_aliases(const char **str_array)
 
 BOOL init_names(void)
 {
-       extern fstring local_machine;
        char *p;
        int n;
 
@@ -273,29 +277,12 @@ const char *tmpdir(void)
        return "/tmp";
 }
 
-/****************************************************************************
- Determine whether we are in the specified group.
-****************************************************************************/
-
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
-{
-       int i;
-
-       if (group == current_gid)
-               return(True);
-
-       for (i=0;i<ngroups;i++)
-               if (group == groups[i])
-                       return(True);
-
-       return(False);
-}
-
 /****************************************************************************
  Add a gid to an array of gids if it's not already there.
 ****************************************************************************/
 
-void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num)
+void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+                            gid_t **gids, int *num)
 {
        int i;
 
@@ -303,8 +290,11 @@ void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num)
                if ((*gids)[i] == gid)
                        return;
        }
-       
-       *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num+1);
+
+       if (mem_ctx != NULL)
+               *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num+1);
+       else
+               *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num+1);
 
        if (*gids == NULL)
                return;
@@ -617,7 +607,7 @@ void unix_clean_name(char *s)
  Make a dir struct.
 ****************************************************************************/
 
-void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date)
+void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL uc)
 {  
        char *p;
        pstring mask2;
@@ -641,7 +631,9 @@ void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T si
        put_dos_date(buf,22,date);
        SSVAL(buf,26,size & 0xFFFF);
        SSVAL(buf,28,(size >> 16)&0xFFFF);
-       push_ascii(buf+30,fname,12,0);
+       /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf.
+          Strange, but verified on W2K3. Needed for OS/2. JRA. */
+       push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0);
        DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
 }
 
@@ -985,6 +977,56 @@ void *realloc_array(void *p,size_t el_size, unsigned int count)
        return Realloc(p,el_size*count);
 }
 
+/****************************************************************************
+ (Hopefully) efficient array append
+****************************************************************************/
+void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
+                       void *element, void **array, uint32 *num_elements,
+                       ssize_t *array_size)
+{
+       if (*array_size == -1)
+               return;
+
+       if (*array == NULL) {
+               if (*array_size == 0)
+                       *array_size = 128;
+
+               if (mem_ctx != NULL)
+                       *array = talloc_array(mem_ctx, element_size,
+                                             *array_size);
+               else
+                       *array = malloc_array(element_size, *array_size);
+
+               if (*array == NULL)
+                       goto error;
+       }
+
+       if (*num_elements == *array_size) {
+               *array_size *= 2;
+
+               if (mem_ctx != NULL)
+                       *array = talloc_realloc_array(mem_ctx, *array,
+                                                     element_size,
+                                                     *array_size);
+               else
+                       *array = realloc_array(*array, element_size,
+                                              *array_size);
+
+               if (*array == NULL)
+                       goto error;
+       }
+
+       memcpy((char *)(*array) + element_size*(*num_elements),
+              element, element_size);
+       *num_elements += 1;
+
+       return;
+
+ error:
+       *num_elements = 0;
+       *array_size = -1;
+}
+
 /****************************************************************************
  Free memory, checks for NULL.
  Use directly SAFE_FREE()
@@ -1465,8 +1507,6 @@ void smb_panic2(const char *why, BOOL decrement_pid_count )
 
 #ifdef DEVELOPER
        {
-               extern char *global_clobber_region_function;
-               extern unsigned int global_clobber_region_line;
 
                if (global_clobber_region_function) {
                        DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
@@ -1931,7 +1971,6 @@ void ra_lanman_string( const char *native_lanman )
 
 void set_remote_arch(enum remote_arch_types type)
 {
-       extern fstring remote_arch;
        ra_type = type;
        switch( type ) {
        case RA_WFWG:
@@ -2172,8 +2211,12 @@ BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
 
        if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
                (*reg_type) = HKEY_LOCAL_MACHINE;
+       else if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT"))
+               (*reg_type) = HKEY_CLASSES_ROOT;
        else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
                (*reg_type) = HKEY_USERS;
+       else if (strequal(tmp, "HKPD")||strequal(tmp, "HKEY_PERFORMANCE_DATA"))
+               (*reg_type) = HKEY_PERFORMANCE_DATA;
        else {
                DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
                return False;
@@ -2469,7 +2512,23 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
        if (strcmp(pattern,".") == 0)
                return False;
        
-       return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0;
+       return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
+}
+
+/*******************************************************************
+ A wrapper that handles case sensitivity and the special handling
+ of the ".." name. Varient that is only called by old search code which requires
+ pattern translation.
+*******************************************************************/
+
+BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
+{
+       if (strcmp(string,"..") == 0)
+               string = ".";
+       if (strcmp(pattern,".") == 0)
+               return False;
+       
+       return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
 }
 
 /*******************************************************************
index b5a9010b5c4e8e5eccfdaaa4484dfb23c0fe04cd..73fc45c844d432cb7af43bf5ef439c468de3b8e2 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "includes.h"
 
-extern DOM_SID global_sid_Builtin;
+extern NT_USER_TOKEN anonymous_token;
 
 /*********************************************************************************
  Check an ACE against a SID.  We return the remaining needed permission
@@ -214,7 +214,6 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
                     uint32 acc_desired, uint32 *acc_granted, 
                     NTSTATUS *status)
 {
-       extern NT_USER_TOKEN anonymous_token;
        size_t i;
        SEC_ACL *the_acl;
        fstring sid_str;
@@ -316,3 +315,41 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
        return False;
 }
 
+
+/*******************************************************************
+ samr_make_sam_obj_sd
+ ********************************************************************/
+
+NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+       DOM_SID adm_sid;
+       DOM_SID act_sid;
+
+       SEC_ACE ace[3];
+       SEC_ACCESS mask;
+
+       SEC_ACL *psa = NULL;
+
+       sid_copy(&adm_sid, &global_sid_Builtin);
+       sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+       sid_copy(&act_sid, &global_sid_Builtin);
+       sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+       /*basic access for every one*/
+       init_sec_access(&mask, GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ);
+       init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+       /*full access for builtin aliases Administrators and Account Operators*/
+       init_sec_access(&mask, GENERIC_RIGHTS_SAM_ALL_ACCESS);
+       init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+       init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+       if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       return NT_STATUS_OK;
+}
index 0ba774e184dc38a5f73b2bf2b89e949b1fcc512d..1838da1313d7a315788bc6bd1731e4232dfcccd3 100644 (file)
  * Some useful sids
  */
 
-DOM_SID global_sid_World_Domain;               /* Everyone domain */
-DOM_SID global_sid_World;                              /* Everyone */
-DOM_SID global_sid_Creator_Owner_Domain;    /* Creator Owner domain */
-DOM_SID global_sid_NT_Authority;               /* NT Authority */
-DOM_SID global_sid_System;             /* System */
-DOM_SID global_sid_NULL;                       /* NULL sid */
-DOM_SID global_sid_Authenticated_Users;                /* All authenticated rids */
-DOM_SID global_sid_Network;                    /* Network rids */
-
-DOM_SID global_sid_Creator_Owner;      /* Creator Owner */
-DOM_SID global_sid_Creator_Group;      /* Creator Group */
-DOM_SID global_sid_Anonymous;          /* Anonymous login */
-
-DOM_SID global_sid_Builtin;                    /* Local well-known domain */
-DOM_SID global_sid_Builtin_Administrators;     /* Builtin administrators */
-DOM_SID global_sid_Builtin_Users;              /* Builtin users */
-DOM_SID global_sid_Builtin_Guests;             /* Builtin guest users */
-DOM_SID global_sid_Builtin_Power_Users;                /* Builtin power users */
-DOM_SID global_sid_Builtin_Account_Operators;  /* Builtin account operators */
-DOM_SID global_sid_Builtin_Server_Operators;   /* Builtin server operators */
-DOM_SID global_sid_Builtin_Print_Operators;    /* Builtin print operators */
-DOM_SID global_sid_Builtin_Backup_Operators;   /* Builtin backup operators */
-DOM_SID global_sid_Builtin_Replicator;         /* Builtin replicator */
+
+const DOM_SID global_sid_World_Domain =               /* Everyone domain */
+{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_World =                      /* Everyone */
+{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Creator_Owner_Domain =       /* Creator Owner domain */
+{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_NT_Authority =                /* NT Authority */
+{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_System =                      /* System */
+{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_NULL =                        /* NULL sid */
+{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Authenticated_Users = /* All authenticated rids */
+{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Network =                     /* Network rids */
+{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+const DOM_SID global_sid_Creator_Owner =               /* Creator Owner */
+{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Creator_Group =               /* Creator Group */
+{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Anonymous =                   /* Anonymous login */
+{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+const DOM_SID global_sid_Builtin =                     /* Local well-known domain */
+{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Administrators =      /* Builtin administrators */
+{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Users =               /* Builtin users */
+{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Guests =              /* Builtin guest users */
+{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Power_Users = /* Builtin power users */
+{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Account_Operators =   /* Builtin account operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Server_Operators =    /* Builtin server operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Print_Operators =     /* Builtin print operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Backup_Operators =    /* Builtin backup operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Replicator =          /* Builtin replicator */
+{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
 
 #define SECURITY_NULL_SID_AUTHORITY    0
 #define SECURITY_WORLD_SID_AUTHORITY   1
@@ -62,18 +84,15 @@ DOM_SID global_sid_Builtin_Replicator;              /* Builtin replicator */
  * An NT compatible anonymous token.
  */
 
-static DOM_SID anon_sid_array[3];
-
-NT_USER_TOKEN anonymous_token = {
-       3,
-       anon_sid_array
-};
+static DOM_SID anon_sid_array[3] =
+{ { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
+  { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
+  { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
+NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
 
-static DOM_SID system_sid_array[4];
-NT_USER_TOKEN system_token = {
-       1,
-       system_sid_array
-};
+static DOM_SID system_sid_array[1] =
+{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
+NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
 
 /****************************************************************************
  Lookup string names for SID types.
@@ -111,66 +130,12 @@ const char *sid_type_lookup(uint32 sid_type)
        return "SID *TYPE* is INVALID";
 }
 
-/****************************************************************************
- Creates some useful well known sids
-****************************************************************************/
-
-void generate_wellknown_sids(void)
-{
-       static BOOL initialised = False;
-
-       if (initialised) 
-               return;
-
-       /* SECURITY_NULL_SID_AUTHORITY */
-       string_to_sid(&global_sid_NULL, "S-1-0-0");
-
-       /* SECURITY_WORLD_SID_AUTHORITY */
-       string_to_sid(&global_sid_World_Domain, "S-1-1");
-       string_to_sid(&global_sid_World, "S-1-1-0");
-
-       /* SECURITY_CREATOR_SID_AUTHORITY */
-       string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
-       string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
-       string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
-
-       /* SECURITY_NT_AUTHORITY */
-       string_to_sid(&global_sid_NT_Authority, "S-1-5");
-       string_to_sid(&global_sid_Network, "S-1-5-2");
-       string_to_sid(&global_sid_Anonymous, "S-1-5-7");
-       string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
-       string_to_sid(&global_sid_System, "S-1-5-18");
-
-       /* SECURITY_BUILTIN_DOMAIN_RID */
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
-       string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
-       string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
-       string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
-       string_to_sid(&global_sid_Builtin_Power_Users, "S-1-5-32-547");
-       string_to_sid(&global_sid_Builtin_Account_Operators, "S-1-5-32-548");
-       string_to_sid(&global_sid_Builtin_Server_Operators, "S-1-5-32-549");
-       string_to_sid(&global_sid_Builtin_Print_Operators, "S-1-5-32-550");
-       string_to_sid(&global_sid_Builtin_Backup_Operators, "S-1-5-32-551");
-       string_to_sid(&global_sid_Builtin_Replicator, "S-1-5-32-552");
-
-       /* Create the anon token. */
-       sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
-       sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
-       sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);
-
-       /* Create the system token. */
-       sid_copy( &system_token.user_sids[0], &global_sid_System);
-       
-       initialised = True;
-}
-
 /**************************************************************************
  Create the SYSTEM token.
 ***************************************************************************/
 
 NT_USER_TOKEN *get_system_token(void) 
 {
-       generate_wellknown_sids(); /* The token is initialised here */
        return &system_token;
 }
 
@@ -351,6 +316,19 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
        return True;
 }
 
+DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
+{
+       DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
+
+       if (result == NULL)
+               return NULL;
+
+       if (!string_to_sid(result, sidstr))
+               return NULL;
+
+       return result;
+}
+
 /*****************************************************************
  Add a rid to the end of a sid
 *****************************************************************/  
@@ -652,9 +630,14 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
  Add SID to an array SIDs
 ********************************************************************/
 
-void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
+void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+                     DOM_SID **sids, int *num)
 {
-       *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
+       if (mem_ctx != NULL)
+               *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
+                                            (*num)+1);
+       else
+               *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
 
        if (*sids == NULL)
                return;
@@ -670,7 +653,8 @@ void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
  Add SID to an array SIDs ensuring that it is not already there
 ********************************************************************/
 
-void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
+void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+                            DOM_SID **sids, int *num_sids)
 {
        int i;
 
@@ -679,7 +663,7 @@ void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
                        return;
        }
 
-       add_sid_to_array(sid, sids, num_sids);
+       add_sid_to_array(mem_ctx, sid, sids, num_sids);
 }
 
 /********************************************************************
index 586362c1e4cfe147fd46df2fc877548ba78f878b..c6f6bc0a32adde5fc82d2c0b635bc4b6a571deea 100644 (file)
@@ -73,10 +73,10 @@ BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int
        groups = NULL;
 
        /* Add in primary group first */
-       add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+       add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
 
        for (i=0; i<max_grp; i++)
-               add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+               add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
 
        *ngroups = ngrp;
        *ret_groups = groups;
index f99c2d1fb320a8150b8c2a0fadd607a45263c7dc..12ee3dc162ee5aa10f0ade416d4965b060c940b8 100644 (file)
@@ -45,7 +45,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
        if (!ptr)
                return(False);
 
-       s = (char *)*ptr;
+       s = CONST_DISCARD(char *, *ptr);
 
        /* default to simple separators */
        if (!sep)
@@ -109,7 +109,7 @@ void set_first_token(char *ptr)
 
 char **toktocliplist(int *ctok, const char *sep)
 {
-       char *s=(char *)last_ptr;
+        char *s = CONST_DISCARD(char *, last_ptr);
        int ictok=0;
        char **ret, **iret;
 
@@ -132,7 +132,7 @@ char **toktocliplist(int *ctok, const char *sep)
        } while(*s);
        
        *ctok=ictok;
-       s=(char *)last_ptr;
+       s = CONST_DISCARD(char *, last_ptr);
        
        if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
                return NULL;
@@ -363,16 +363,16 @@ BOOL strisnormal(const char *s, int case_default)
  NOTE: oldc and newc must be 7 bit characters
 **/
 
-void string_replace(pstring s,char oldc,char newc)
+void string_replace( pstring s, char oldc, char newc )
 {
-       unsigned char *p;
+       char *p;
 
        /* this is quite a common operation, so we want it to be
           fast. We optimise for the ascii case, knowing that all our
           supported multi-byte character sets are ascii-compatible
           (ie. they match for the first 128 chars) */
 
-       for (p = (unsigned char *)s; *p; p++) {
+       for (p = s; *p; p++) {
                if (*p & 0x80) /* mb string - slow path. */
                        break;
                if (*p == oldc)
@@ -799,7 +799,7 @@ DATA_BLOB strhex_to_data_blob(const char *strhex)
 {
        DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
 
-       ret_blob.length = strhex_to_str(ret_blob.data,  
+       ret_blob.length = strhex_to_str((char*)ret_blob.data,   
                                        strlen(strhex), 
                                        strhex);
 
@@ -826,7 +826,7 @@ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
  Check if a string is part of a list.
 **/
 
-BOOL in_list(char *s,char *list,BOOL casesensitive)
+BOOL in_list(const char *s, const char *list, BOOL casesensitive)
 {
        pstring tok;
        const char *p=list;
@@ -1221,7 +1221,7 @@ char *strchr_m(const char *src, char c)
 
        for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
                if (*s == c)
-                       return (char *)s;
+                       return CONST_DISCARD(char *, s);
        }
 
        if (!*s)
@@ -1238,7 +1238,7 @@ char *strchr_m(const char *src, char c)
                return NULL;
        *p = 0;
        pull_ucs2_pstring(s2, ws);
-       return (char *)(s+strlen(s2));
+       return CONST_DISCARD(char *, (s+strlen(s2)));
 }
 
 char *strrchr_m(const char *s, char c)
@@ -1275,7 +1275,7 @@ char *strrchr_m(const char *s, char c)
                                        break;
                                }
                                /* No - we have a match ! */
-                               return (char *)cp;
+                               return CONST_DISCARD(char *, cp);
                        }
                } while (cp-- != s);
                if (!got_mb)
@@ -1294,7 +1294,7 @@ char *strrchr_m(const char *s, char c)
                        return NULL;
                *p = 0;
                pull_ucs2_pstring(s2, ws);
-               return (char *)(s+strlen(s2));
+               return CONST_DISCARD(char *, (s+strlen(s2)));
        }
 }
 
@@ -1315,7 +1315,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
                return NULL;
        *p = 0;
        pull_ucs2_pstring(s2, ws);
-       return (char *)(s+strlen(s2));
+       return CONST_DISCARD(char *, (s+strlen(s2)));
 }
 
 /***********************************************************************
@@ -1334,7 +1334,7 @@ char *strstr_m(const char *src, const char *findstr)
 
        /* for correctness */
        if (!findstr[0]) {
-               return src;
+               return CONST_DISCARD(char *, src);
        }
 
        /* Samba does single character findstr calls a *lot*. */
@@ -1351,7 +1351,7 @@ char *strstr_m(const char *src, const char *findstr)
                                findstr_len = strlen(findstr);
 
                        if (strncmp(s, findstr, findstr_len) == 0) {
-                               return (char *)s;
+                               return CONST_DISCARD(char *, s);
                        }
                }
        }
@@ -1392,7 +1392,7 @@ char *strstr_m(const char *src, const char *findstr)
                DEBUG(0,("strstr_m: dest malloc fail\n"));
                return NULL;
        }
-       retp = (char *)(s+strlen(s2));
+       retp = CONST_DISCARD(char *, (s+strlen(s2)));
        SAFE_FREE(src_w);
        SAFE_FREE(find_w);
        SAFE_FREE(s2);
@@ -1694,6 +1694,20 @@ void str_list_free(char ***list)
        SAFE_FREE(*list);
 }
 
+/******************************************************************************
+ *****************************************************************************/
+
+int str_list_count( const char **list )
+{
+       int i = 0;
+
+       /* count the number of list members */
+       
+       for ( i=0; *list; i++, list++ );
+       
+       return i;
+}
+
 /******************************************************************************
  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
  for the work
index 55a21ebcbbcebf2bc22206e2ec8917493e8f7696..0b4552e1f5d918b0046cee8a534e0182a4f60384 100644 (file)
@@ -282,6 +282,19 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
        pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
 }
 
+/*******************************************************************
+ Convert a (little-endian) UNISTR3 structure to an ASCII string
+********************************************************************/
+void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen)
+{
+       if (str == NULL) {
+               *dest='\0';
+               return;
+       }
+       pull_ucs2(NULL, dest, str->str.buffer, maxlen, str->uni_str_len*2,
+                 STR_NOALIGN);
+}
+       
 /*******************************************************************
 give a static string for displaying a UNISTR2
 ********************************************************************/
@@ -310,18 +323,6 @@ char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
 }
 
 
-/*******************************************************************
-Return a number stored in a buffer
-********************************************************************/
-
-uint32 buffer2_to_uint32(BUFFER2 *str)
-{
-       if (str->buf_len == 4)
-               return IVAL(str->buffer, 0);
-       else
-               return 0;
-}
-
 /*******************************************************************
  Convert a wchar to upper case.
 ********************************************************************/
@@ -397,10 +398,10 @@ size_t strnlen_w(const smb_ucs2_t *src, size_t max)
 smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
 {
        while (*s != 0) {
-               if (c == *s) return (smb_ucs2_t *)s;
+                if (c == *s) return CONST_DISCARD(smb_ucs2_t *, s);
                s++;
        }
-       if (c == *s) return (smb_ucs2_t *)s;
+       if (c == *s) return CONST_DISCARD(smb_ucs2_t *, s);
 
        return NULL;
 }
@@ -421,7 +422,7 @@ smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
        if (len == 0) return NULL;
        p += (len - 1);
        do {
-               if (c == *p) return (smb_ucs2_t *)p;
+               if (c == *p) return CONST_DISCARD(smb_ucs2_t *, p);
        } while (p-- != s);
        return NULL;
 }
@@ -442,7 +443,7 @@ smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n)
                        n--;
 
                if (!n)
-                       return (smb_ucs2_t *)p;
+                       return CONST_DISCARD(smb_ucs2_t *, p);
        } while (p-- != s);
        return NULL;
 }
@@ -460,7 +461,7 @@ smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins)
                return NULL;
 
        inslen = strlen_w(ins);
-       r = (smb_ucs2_t *)s;
+       r = CONST_DISCARD(smb_ucs2_t *, s);
 
        while ((r = strchr_w(r, *ins))) {
                if (strncmp_w(r, ins, inslen) == 0) 
@@ -731,7 +732,7 @@ smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
                int i;
                for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++) 
                        ;
-               if (p[i]) return (smb_ucs2_t *)s;
+               if (p[i]) return CONST_DISCARD(smb_ucs2_t *, s);
                s++;
        }
        return NULL;
@@ -746,7 +747,7 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins)
                return NULL;
 
        inslen = strlen(ins);
-       r = (smb_ucs2_t *)s;
+       r = CONST_DISCARD(smb_ucs2_t *, s);
 
        while ((r = strchr_w(r, UCS2_CHAR(*ins)))) {
                if (strncmp_wa(r, ins, inslen) == 0) 
index df70740b33c1b7fb5db4cd64d1c777970a80e33c..8b8e70a36efb530e0fb550a1103f488626e5daea 100644 (file)
@@ -94,7 +94,7 @@ BOOL smb_string_to_uuid(const char *in, struct uuid* uu)
 {
        BOOL ret = False;
        const char *ptr = in;
-       char *end = (char *)in;
+       char *end = CONST_DISCARD(char *, in);
        int i;
        unsigned v1, v2;
 
index b82e04e13ccea6b6ea2f2c7b6e840cc147cd7d7e..c139f427ca89c8e3c6b572e923c4429e6032300d 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "includes.h"
 
+extern struct in_addr loopback_ip;
+
 /*
   This is pretty much a complete rewrite of the earlier code. The main
   aim of the rewrite is to add support for having multiple wins server
@@ -280,7 +282,6 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
 
        /* if we are a wins server then we always just talk to ourselves */
        if (lp_wins_support()) {
-               extern struct in_addr loopback_ip;
                return loopback_ip;
        }
 
index 4c9997e080ec9c2d334289169021d519f4271a35..18820d9e312317c51a9eb3986797c4ccba680693 100644 (file)
@@ -88,7 +88,8 @@ int kerberos_kinit_password(const char *principal,
                return code;
        }
        
-       if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, 
+       if ((code = krb5_get_init_creds_password(ctx, &my_creds, me,
+                                                 CONST_DISCARD(char *, password), 
                                                 kerb_prompter, 
                                                 NULL, 0, NULL, NULL))) {
                krb5_free_principal(ctx, me);
index 6e1b011c37c6b623bbe4a9dfab68f47ed8fb2c51..7a59da5a6d363f79971fbfdaeac470e47a0ec80b 100644 (file)
@@ -481,15 +481,15 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
                ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0);
        }
        ber_flatten(cookie_be, &cookie_bv);
-       PagedResults.ldctl_oid = ADS_PAGE_CTL_OID;
+       PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
        PagedResults.ldctl_iscritical = (char) 1;
        PagedResults.ldctl_value.bv_len = cookie_bv->bv_len;
        PagedResults.ldctl_value.bv_val = cookie_bv->bv_val;
 
-       NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID;
+       NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID);
        NoReferrals.ldctl_iscritical = (char) 0;
        NoReferrals.ldctl_value.bv_len = 0;
-       NoReferrals.ldctl_value.bv_val = "";
+       NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, "");
 
 
        controls[0] = &NoReferrals;
@@ -831,7 +831,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
                   need to reset it to NULL before doing ldap modify */
                mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
        
-       return mods;
+       return (ADS_MODLIST)mods;
 }
 
 
@@ -868,7 +868,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
                memset(&modlist[curmod], 0, 
                       ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *));
                modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
-               *mods = modlist;
+               *mods = (ADS_MODLIST)modlist;
        }
                
        if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod)))
@@ -962,7 +962,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
           non-existent attribute (but allowable for the object) to run
        */
        LDAPControl PermitModify = {
-               ADS_PERMIT_MODIFY_OID,
+                CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID),
                {0, NULL},
                (char) 1};
        LDAPControl *controls[2];
@@ -1006,7 +1006,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
        /* make sure the end of the list is NULL */
        mods[i] = NULL;
 
-       ret = ldap_add_s(ads->ld, utf8_dn, mods);
+       ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods);
        SAFE_FREE(utf8_dn);
        return ADS_ERROR(ret);
 }
@@ -1267,7 +1267,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
        ADS_STATUS ret;
        TALLOC_CTX *ctx;
        LDAPMessage *res = NULL;
-       char *host_spn, *host_upn, *psp1, *psp2, *psp3;
+       char *host_spn, *psp1, *psp2, *psp3;
        ADS_MODLIST mods;
        fstring my_fqdn;
        char *dn_string = NULL;
@@ -1297,11 +1297,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
                ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
        }
-       if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) {
-               talloc_destroy(ctx);
-               ads_msgfree(ads, res);
-               return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
-       }
 
        /* Add the extra principal */
        psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name);
index 68e6735891038a1de49a390e0cc6e8abb8189605..61275e40d11de997f7c71c1c83b8ef09e9a2725e 100644 (file)
@@ -61,8 +61,10 @@ ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
 
        /* For the moment only display all printers */
 
-       ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
-               "(objectCategory=printQueue))";
+       ldap_expr =
+                CONST_DISCARD(char *,
+                                "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
+                                "(objectCategory=printQueue))");
 
        return ads_search(ads, res, ldap_expr, attrs);
 }
index 97ba9c92862792cab182505a0e1a43cc650f14e6..e657f2114e67a7063cde0d06c9ce7780ca61ccea 100644 (file)
@@ -18,6 +18,8 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#define KRB5_PRIVATE    1       /* this file uses PRIVATE interfaces! */
+
 #include "includes.h"
 
 #ifdef HAVE_LDAP
@@ -173,7 +175,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
        DATA_BLOB blob;
        char *principal = NULL;
        char *OIDs[ASN1_MAX_OIDS];
+#ifdef HAVE_KRB5
        BOOL got_kerberos_mechanism = False;
+#endif
 
        rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
 
@@ -202,10 +206,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
        /* make sure the server understands kerberos */
        for (i=0;OIDs[i];i++) {
                DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i]));
+#ifdef HAVE_KRB5
                if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
                    strcmp(OIDs[i], OID_KERBEROS5) == 0) {
                        got_kerberos_mechanism = True;
                }
+#endif
                free(OIDs[i]);
        }
        DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal));
@@ -281,7 +287,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
                        ENCTYPE_DES_CBC_MD5,
                        ENCTYPE_NULL};
        gss_OID_desc nt_principal = 
-       {10, "\052\206\110\206\367\022\001\002\002\002"};
+                {10, CONST_DISCARD(char *,
+                                     "\052\206\110\206\367\022\001\002\002\002")};
 
        /* we need to fetch a service ticket as the ldap user in the
           servers realm, regardless of our realm */
index dce51a2c8bbbee9560e47574bfda3d9f88da3915..5a9992d4e0369a4d3b70832f0f410ba6e5930b16 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "includes.h"
 
+extern pstring user_socket_options;
 
 static const struct {
        int prot;
@@ -702,7 +703,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        char *principal;
        char *OIDs[ASN1_MAX_OIDS];
        int i;
+#ifdef HAVE_KRB5
        BOOL got_kerberos_mechanism = False;
+#endif
        DATA_BLOB blob;
 
        DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
@@ -731,10 +734,12 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        /* make sure the server understands kerberos */
        for (i=0;OIDs[i];i++) {
                DEBUG(3,("got OID=%s\n", OIDs[i]));
+#ifdef HAVE_KRB5
                if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
                    strcmp(OIDs[i], OID_KERBEROS5) == 0) {
                        got_kerberos_mechanism = True;
                }
+#endif
                free(OIDs[i]);
        }
        DEBUG(3,("got principal=%s\n", principal));
@@ -1196,7 +1201,6 @@ BOOL cli_session_request(struct cli_state *cli,
 {
        char *p;
        int len = 4;
-       extern pstring user_socket_options;
 
        memcpy(&(cli->calling), calling, sizeof(*calling));
        memcpy(&(cli->called ), called , sizeof(*called ));
@@ -1286,7 +1290,6 @@ BOOL cli_session_request(struct cli_state *cli,
 
 BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
 {
-       extern pstring user_socket_options;
        int name_type = 0x20;
        char *p;
 
index b7bc780a1a195ccd1f00fe579c9f72d329da77de..e787650c2f5388f35849348bc0874bef56d14bb5 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "includes.h"
 
+extern int smb_read_error;
+
 /****************************************************************************
  Change the timeout (in milliseconds).
 ****************************************************************************/
@@ -81,7 +83,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
 
 BOOL cli_receive_smb(struct cli_state *cli)
 {
-       extern int smb_read_error;
        BOOL ret;
 
        /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
index 9d20ed3adcd268ca01629982c13b7bf3562aba5e..93492ec08229654b38ca5502321e31689a61a3dd 100644 (file)
@@ -1071,7 +1071,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
 ****************************************************************************/
 
 BOOL cli_getattrE(struct cli_state *cli, int fd, 
-                 uint16 *attr, SMB_BIG_UINT *size, 
+                 uint16 *attr, SMB_OFF_T *size, 
                  time_t *c_time, time_t *a_time, time_t *m_time)
 {
        memset(cli->outbuf,'\0',smb_size);
@@ -1122,7 +1122,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
 ****************************************************************************/
 
 BOOL cli_getatr(struct cli_state *cli, const char *fname, 
-               uint16 *attr, size_t *size, time_t *t)
+               uint16 *attr, SMB_OFF_T *size, time_t *t)
 {
        char *p;
 
index 22c8bff3ba02bd526bb2cbd699b8d4eaf4ad329f..2874ee6ca1cba99dfd0e7a60fcf24612f7d308d6 100644 (file)
@@ -132,3 +132,118 @@ cleanup:
 
        return ret;     
 }
+
+BOOL cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number)
+{
+       BOOL ret = False;
+       uint16 setup;
+       char param[2];
+       char *rparam=NULL, *rdata=NULL;
+       unsigned int rparam_count=0, rdata_count=0;
+       unsigned char nlen;
+
+       setup = TRANSACT2_QFSINFO;
+       
+       SSVAL(param,0,SMB_INFO_VOLUME);
+
+       if (!cli_send_trans(cli, SMBtrans2, 
+                   NULL, 
+                   0, 0,
+                   &setup, 1, 0,
+                   param, 2, 0,
+                   NULL, 0, 560)) {
+               goto cleanup;
+       }
+       
+       if (!cli_receive_trans(cli, SMBtrans2,
+                              &rparam, &rparam_count,
+                              &rdata, &rdata_count)) {
+               goto cleanup;
+       }
+
+       if (cli_is_error(cli)) {
+               ret = False;
+               goto cleanup;
+       } else {
+               ret = True;
+       }
+
+       if (rdata_count < 5) {
+               goto cleanup;
+       }
+
+       if (pserial_number) {
+               *pserial_number = IVAL(rdata,0);
+       }
+       nlen = CVAL(rdata,l2_vol_cch);
+       clistr_pull(cli, volume_name, rdata + l2_vol_szVolLabel, sizeof(fstring), nlen, STR_NOALIGN);
+
+       /* todo: but not yet needed 
+        *       return the other stuff
+        */
+
+cleanup:
+       SAFE_FREE(rparam);
+       SAFE_FREE(rdata);
+
+       return ret;     
+}
+
+BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate)
+{
+       BOOL ret = False;
+       uint16 setup;
+       char param[2];
+       char *rparam=NULL, *rdata=NULL;
+       unsigned int rparam_count=0, rdata_count=0;
+       unsigned int nlen;
+
+       setup = TRANSACT2_QFSINFO;
+       
+       SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO);
+
+       if (!cli_send_trans(cli, SMBtrans2, 
+                   NULL, 
+                   0, 0,
+                   &setup, 1, 0,
+                   param, 2, 0,
+                   NULL, 0, 560)) {
+               goto cleanup;
+       }
+       
+       if (!cli_receive_trans(cli, SMBtrans2,
+                              &rparam, &rparam_count,
+                              &rdata, &rdata_count)) {
+               goto cleanup;
+       }
+
+       if (cli_is_error(cli)) {
+               ret = False;
+               goto cleanup;
+       } else {
+               ret = True;
+       }
+
+       if (rdata_count < 19) {
+               goto cleanup;
+       }
+
+       if (pdate) {
+               *pdate = interpret_long_date(rdata);
+       }
+       if (pserial_number) {
+               *pserial_number = IVAL(rdata,8);
+       }
+       nlen = IVAL(rdata,12);
+       clistr_pull(cli, volume_name, rdata + 18, sizeof(fstring), nlen, STR_UNICODE);
+
+       /* todo: but not yet needed 
+        *       return the other stuff
+        */
+
+cleanup:
+       SAFE_FREE(rparam);
+       SAFE_FREE(rdata);
+
+       return ret;     
+}
index 66c16b69aef4c4b882eae2f0122e46d0dd58e497..c35b53a9dd8563474042065de5364a11b5ab337b 100644 (file)
@@ -19,6 +19,9 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#define KRB5_PRIVATE    1       /* this file uses PRIVATE interfaces! */
+#define KRB5_DEPRECATED 1       /* this file uses DEPRECATED interfaces! */
+
 #include "includes.h"
 
 #ifdef HAVE_KRB5
index 0f1b9efed0e80f55c67f63cd38b1d67c53ebbac6..79c2ef66a19ac72320711bae55f96a8f6b4df2b3 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "includes.h"
 
+extern file_info def_finfo;
+
 /****************************************************************************
  Interpret a long filename structure - this is mostly guesses at the moment.
  The length of the structure is returned
@@ -32,7 +34,6 @@
 static size_t interpret_long_filename(struct cli_state *cli,
                                   int level,char *p,file_info *finfo)
 {
-       extern file_info def_finfo;
        file_info finfo2;
        int len;
        char *base = p;
@@ -332,7 +333,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
 
 static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo)
 {
-       extern file_info def_finfo;
 
        *finfo = def_finfo;
 
index 8e6742d438077cb608c5740812211b2b0ed33711..06b683b0385df18811808059ec8acb9dc6a797d8 100644 (file)
@@ -382,7 +382,7 @@ send a qpathinfo call
 ****************************************************************************/
 BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, 
                   time_t *c_time, time_t *a_time, time_t *m_time, 
-                  size_t *size, uint16 *mode)
+                  SMB_OFF_T *size, uint16 *mode)
 {
        unsigned int data_len = 0;
        unsigned int param_len = 0;
@@ -462,7 +462,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
 ****************************************************************************/
 BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, 
                    time_t *c_time, time_t *a_time, time_t *m_time, 
-                   time_t *w_time, size_t *size, uint16 *mode,
+                   time_t *w_time, SMB_OFF_T *size, uint16 *mode,
                    SMB_INO_T *ino)
 {
        unsigned int data_len = 0;
@@ -501,22 +501,22 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
        }
 
        if (c_time) {
-               *c_time = interpret_long_date(rdata+0) - cli->serverzone;
+                *c_time = interpret_long_date(rdata+0);
        }
        if (a_time) {
-               *a_time = interpret_long_date(rdata+8) - cli->serverzone;
+               *a_time = interpret_long_date(rdata+8);
        }
        if (m_time) {
-               *m_time = interpret_long_date(rdata+16) - cli->serverzone;
+               *m_time = interpret_long_date(rdata+16);
        }
        if (w_time) {
-               *w_time = interpret_long_date(rdata+24) - cli->serverzone;
+               *w_time = interpret_long_date(rdata+24);
        }
        if (mode) {
                *mode = SVAL(rdata, 32);
        }
        if (size) {
-               *size = IVAL(rdata, 48);
+                *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
        }
        if (ino) {
                *ino = IVAL(rdata, 64);
@@ -546,11 +546,11 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum,
        SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO);
 
        if (!cli_send_trans(cli, SMBtrans2, 
-                            NULL,                           /* name */
-                            -1, 0,                          /* fid, flags */
-                            &setup, 1, 0,                   /* setup, length, max */
-                            param, param_len, 2,            /* param, length, max */
-                            NULL, data_len, cli->max_xmit   /* data, length, max */
+                            NULL,                         /* name */
+                            -1, 0,                        /* fid, flags */
+                            &setup, 1, 0,                 /* setup, length, max */
+                            param, param_len, 2,          /* param, length, max */
+                            NULL, data_len, cli->max_xmit /* data, length, max */
                            )) {
                return False;
        }
@@ -575,7 +575,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum,
 send a qfileinfo call
 ****************************************************************************/
 BOOL cli_qfileinfo(struct cli_state *cli, int fnum, 
-                  uint16 *mode, size_t *size,
+                  uint16 *mode, SMB_OFF_T *size,
                   time_t *c_time, time_t *a_time, time_t *m_time, 
                   time_t *w_time, SMB_INO_T *ino)
 {
@@ -596,11 +596,11 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
        SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
 
        if (!cli_send_trans(cli, SMBtrans2, 
-                            NULL,                           /* name */
-                            -1, 0,                          /* fid, flags */
-                            &setup, 1, 0,                   /* setup, length, max */
-                            param, param_len, 2,            /* param, length, max */
-                            NULL, data_len, cli->max_xmit   /* data, length, max */
+                            NULL,                         /* name */
+                            -1, 0,                        /* fid, flags */
+                            &setup, 1, 0,                 /* setup, length, max */
+                            param, param_len, 2,          /* param, length, max */
+                            NULL, data_len, cli->max_xmit /* data, length, max */
                            )) {
                return False;
        }
@@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
                *mode = SVAL(rdata, 32);
        }
        if (size) {
-               *size = IVAL(rdata, 48);
+                *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
        }
        if (ino) {
                *ino = IVAL(rdata, 64);
index 12a3d63aff35542b1e81fe621e9434509cda9836..d8a85195502862b3ff70b2a89f56981f26d8cd30 100644 (file)
@@ -329,6 +329,70 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char
   return res;
 }
 
+int cli_RNetGroupEnum0(struct cli_state *cli,
+                      void (*fn)(const char *, void *),
+                      void *state)
+{
+  char param[WORDSIZE                     /* api number    */
+           +sizeof(RAP_NetGroupEnum_REQ) /* parm string   */
+           +sizeof(RAP_GROUP_INFO_L0)    /* return string */
+           +WORDSIZE                     /* info level    */
+           +WORDSIZE];                   /* buffer size   */
+  char *p;
+  char *rparam = NULL;
+  char *rdata = NULL; 
+  unsigned int rprcnt, rdrcnt;
+  int res = -1;
+  
+  
+  memset(param, '\0', sizeof(param));
+  p = make_header(param, RAP_WGroupEnum,
+                 RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0);
+  PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this
+                                     is the resume count, at least
+                                     that's what smbd believes... */
+  PUTWORD(p,0xFFE0); /* Return buffer size */
+
+  if (cli_api(cli,
+             param, PTR_DIFF(p,param),8,
+             NULL, 0, 0xFFE0 /* data area size */,
+             &rparam, &rprcnt,
+             &rdata, &rdrcnt)) {
+    res = GETRES(rparam);
+    cli->rap_error = res;
+    if(cli->rap_error == 234) 
+        DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
+    else if (cli->rap_error != 0) {
+      DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
+    }
+  }
+
+  if (rdata) {
+    if (res == 0 || res == ERRmoredata) {
+      int i, converter, count;
+
+      p = rparam + WORDSIZE; /* skip result */
+      GETWORD(p, converter);
+      GETWORD(p, count);
+
+      for (i=0,p=rdata;i<count;i++) {
+           char groupname[RAP_GROUPNAME_LEN];
+           GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
+           fn(groupname, cli);
+      }        
+    } else {
+      DEBUG(4,("NetGroupEnum res=%d\n", res));
+    }
+  } else {
+    DEBUG(4,("NetGroupEnum no data returned\n"));
+  }
+    
+  SAFE_FREE(rparam);
+  SAFE_FREE(rdata);
+
+  return res;
+}
+
 int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
 {
   char *rparam = NULL;
@@ -768,6 +832,66 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char
   return res;
 }
 
+int cli_RNetUserEnum0(struct cli_state *cli,
+                     void (*fn)(const char *, void *),
+                     void *state)
+{
+  char param[WORDSIZE                 /* api number    */
+           +sizeof(RAP_NetUserEnum_REQ) /* parm string   */
+           +sizeof(RAP_USER_INFO_L0)    /* return string */
+           +WORDSIZE                 /* info level    */
+           +WORDSIZE];               /* buffer size   */
+  char *p;
+  char *rparam = NULL;
+  char *rdata = NULL; 
+  unsigned int rprcnt, rdrcnt;
+  int res = -1;
+  
+
+  memset(param, '\0', sizeof(param));
+  p = make_header(param, RAP_WUserEnum,
+                 RAP_NetUserEnum_REQ, RAP_USER_INFO_L0);
+  PUTWORD(p,0); /* Info level 1 */
+  PUTWORD(p,0xFF00); /* Return buffer size */
+
+/* BB Fix handling of large numbers of users to be returned */
+  if (cli_api(cli,
+             param, PTR_DIFF(p,param),8,
+             NULL, 0, CLI_BUFFER_SIZE,
+             &rparam, &rprcnt,
+             &rdata, &rdrcnt)) {
+    res = GETRES(rparam);
+    cli->rap_error = res;
+    if (cli->rap_error != 0) {
+      DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
+    }
+  }
+  if (rdata) {
+    if (res == 0 || res == ERRmoredata) {
+      int i, converter, count;
+      char username[RAP_USERNAME_LEN];
+
+      p = rparam + WORDSIZE; /* skip result */
+      GETWORD(p, converter);
+      GETWORD(p, count);
+
+      for (i=0,p=rdata;i<count;i++) {
+        GETSTRINGF(p, username, RAP_USERNAME_LEN);
+        fn(username, cli);
+      }
+    } else {
+      DEBUG(4,("NetUserEnum res=%d\n", res));
+    }
+  } else {
+    DEBUG(4,("NetUserEnum no data returned\n"));
+  }
+    
+  SAFE_FREE(rparam);
+  SAFE_FREE(rdata);
+
+  return res;
+}
+
 /****************************************************************************
  call a NetFileClose2 - close open file on another session to server
 ****************************************************************************/
index 85b7bd9e1eec1f3cee0d87cf33bcbd2d43c01d71..5d07999bc3a6b847a5f208c6065c4356e9677f4c 100644 (file)
@@ -338,7 +338,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset,
                return retval;
 
        /* wrap that up in a nice GSS-API wrapping */
-       tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
+       tkt_wrapped = spnego_gen_krb5_wrap(
+            tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ));
 
        /* and wrap that in a shiny SPNEGO wrapper */
        *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
index 96c052c7c56d25b43c6227816818a0ca34545c7a..0dca2653483a44f1b53c209d3812cb6ae3ac9a53 100644 (file)
@@ -31,6 +31,7 @@ typedef const struct
 werror_code_struct dos_errs[] =
 {
        { "WERR_OK", WERR_OK },
+       { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE },
        { "WERR_BADFILE", WERR_BADFILE },
        { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED },
        { "WERR_BADFID", WERR_BADFID },
@@ -69,6 +70,7 @@ werror_code_struct dos_errs[] =
        { "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
        { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
        { "WERR_IO_PENDING", WERR_IO_PENDING },
+       { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL },
        { NULL, W_ERROR(0) }
 };
 
index 3761074e04fac2c5f91ff6fa58f265d593063bcc..3e8e604ab11488380f78c07e12aa8e66e7bd970e 100644 (file)
@@ -80,6 +80,9 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
        return False;
 }
 
+static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file);
+static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence);
+
 extern BOOL in_client;
 
 /*
@@ -555,6 +558,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
        int tried_reverse = 0;
         int port_try_first;
         int port_try_next;
+        const char *username_used;
   
        zero_ip(&ip);
        ZERO_STRUCT(c);
@@ -709,16 +713,26 @@ SMBCSRV *smbc_server(SMBCCTX *context,
                return NULL;
        }
 
-       if (!cli_session_setup(&c, username, 
+        username_used = username;
+
+       if (!cli_session_setup(&c, username_used, 
                               password, strlen(password),
                               password, strlen(password),
-                              workgroup) &&
-                       /* Try an anonymous login if it failed and this was allowed by flags. */
-                       ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
-                       !cli_session_setup(&c, "", "", 1,"", 0, workgroup))) {
-               cli_shutdown(&c);
-               errno = EPERM;
-               return NULL;
+                              workgroup)) {
+                
+                /* Failed.  Try an anonymous login, if allowed by flags. */
+                username_used = "";
+
+                if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
+                     !cli_session_setup(&c, username_used,
+                                        password, 1,
+                                        password, 0,
+                                        workgroup)) {
+
+                        cli_shutdown(&c);
+                        errno = EPERM;
+                        return NULL;
+                }
        }
 
        DEBUG(4,(" session setup ok\n"));
@@ -750,7 +764,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
        /* now add it to the cache (internal or external)  */
        /* Let the cache function set errno if it wants to */
        errno = 0;
-       if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
+       if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) {
                int saved_errno = errno;
                DEBUG(3, (" Failed to add server to cache\n"));
                errno = saved_errno;
@@ -968,6 +982,37 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m
                file->file    = True;
 
                DLIST_ADD(context->internal->_files, file);
+
+                /*
+                 * If the file was opened in O_APPEND mode, all write
+                 * operations should be appended to the file.  To do that,
+                 * though, using this protocol, would require a getattrE()
+                 * call for each and every write, to determine where the end
+                 * of the file is. (There does not appear to be an append flag
+                 * in the protocol.)  Rather than add all of that overhead of
+                 * retrieving the current end-of-file offset prior to each
+                 * write operation, we'll assume that most append operations
+                 * will continuously write, so we'll just set the offset to
+                 * the end of the file now and hope that's adequate.
+                 *
+                 * Note to self: If this proves inadequate, and O_APPEND
+                 * should, in some cases, be forced for each write, add a
+                 * field in the context options structure, for
+                 * "strict_append_mode" which would select between the current
+                 * behavior (if FALSE) or issuing a getattrE() prior to each
+                 * write and forcing the write to the end of the file (if
+                 * TRUE).  Adding that capability will likely require adding
+                 * an "append" flag into the _SMBCFILE structure to track
+                 * whether a file was opened in O_APPEND mode.  -- djl
+                 */
+                if (flags & O_APPEND) {
+                        if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) {
+                                (void) smbc_close_ctx(context, file);
+                                errno = ENXIO;
+                                return NULL;
+                        }
+                }
+
                return file;
 
        }
@@ -1017,6 +1062,17 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
 {
        int ret;
 
+        /*
+         * offset:
+         *
+         * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) --
+         * appears to pass file->offset (which is type off_t) differently than
+         * a local variable of type off_t.  Using local variable "offset" in
+         * the call to cli_read() instead of file->offset fixes a problem
+         * retrieving data at an offset greater than 4GB.
+         */
+        off_t offset = file->offset;
+
        if (!context || !context->internal ||
            !context->internal->_initialized) {
 
@@ -1043,7 +1099,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
 
        }
 
-       ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count);
+       ret = cli_read(&file->srv->cli, file->cli_fd, buf, offset, count);
 
        if (ret < 0) {
 
@@ -1067,6 +1123,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
 static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
 {
        int ret;
+        off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
@@ -1092,7 +1149,7 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_
 
        }
 
-       ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count);
+       ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, offset, count);
 
        if (ret <= 0) {
 
@@ -1165,7 +1222,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file)
  * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
  */
 static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, 
-                uint16 *mode, size_t *size, 
+                uint16 *mode, SMB_OFF_T *size, 
                 time_t *c_time, time_t *a_time, time_t *m_time,
                 SMB_INO_T *ino)
 {
@@ -1272,7 +1329,7 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
                if (errno == EACCES) { /* Check if the file is a directory */
 
                        int saverr = errno;
-                       size_t size = 0;
+                       SMB_OFF_T size = 0;
                        uint16 mode = 0;
                        time_t m_time = 0, a_time = 0, c_time = 0;
                        SMB_INO_T ino = 0;
@@ -1396,7 +1453,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
 
 static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence)
 {
-       size_t size;
+       SMB_OFF_T size;
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
@@ -1482,7 +1539,8 @@ ino_t smbc_inode(SMBCCTX *context, const char *name)
  */
 
 static
-int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode)
+int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname,
+                    SMB_OFF_T size, int mode)
 {
        
        st->st_mode = 0;
@@ -1532,7 +1590,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
        fstring server, share, user, password, workgroup;
        pstring path;
        time_t m_time = 0, a_time = 0, c_time = 0;
-       size_t size = 0;
+       SMB_OFF_T size = 0;
        uint16 mode = 0;
        SMB_INO_T ino = 0;
 
@@ -1602,7 +1660,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
 static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
 {
        time_t c_time, a_time, m_time;
-       size_t size;
+       SMB_OFF_T size;
        uint16 mode;
        SMB_INO_T ino = 0;
 
@@ -1629,15 +1687,12 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
 
        if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
                           &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) {
-           SMB_BIG_UINT b_size = size;
            if (!cli_getattrE(&file->srv->cli, file->cli_fd,
-                         &mode, &b_size, &c_time, &a_time, &m_time)) {
+                         &mode, &size, &c_time, &a_time, &m_time)) {
 
                errno = EINVAL;
                return -1;
-           } else
-               size = b_size;
-
+           }
        }
 
        st->st_ino = ino;
@@ -1960,7 +2015,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                 }
 
                 for (i = 0; i < count && i < max_lmb_count; i++) {
-                        DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
+                        DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip)));
                         
                         cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info);
                        /* cli == NULL is the master browser refused to talk or 
@@ -1983,12 +2038,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                         srv = smbc_server(context, server,
                                           "IPC$", workgroup, user, password);
                         if (!srv) {
-                                
-                                if (dir) {
-                                        SAFE_FREE(dir->fname);
-                                        SAFE_FREE(dir);
-                                }
-                                return NULL;
+                                continue;
                         }
                 
                         dir->srv = srv;
@@ -1999,13 +2049,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                         if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
                                                (void *)dir)) {
                                 
-                                if (dir) {
-                                        SAFE_FREE(dir->fname);
-                                        SAFE_FREE(dir);
-                                }
-                                
-                                return NULL;
-                                
+                                continue;
                         }
                 }
         } else { 
@@ -3233,7 +3277,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
                                      SMBCSRV *srv)
 {
         time_t m_time = 0, a_time = 0, c_time = 0;
-        size_t size = 0;
+        SMB_OFF_T size = 0;
         uint16 mode = 0;
        SMB_INO_T inode = 0;
         DOS_ATTR_DESC *ret;
@@ -3245,7 +3289,8 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
         }
 
         /* Obtain the DOS attributes */
-        if (!smbc_getatr(context, srv, filename, &mode, &size, 
+        if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
+                         &mode, &size, 
                          &c_time, &a_time, &m_time, &inode)) {
         
                 errno = smbc_errno(context, &srv->cli);
@@ -3314,42 +3359,124 @@ retrieve the acls for a file
 *******************************************************/
 static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
                     struct cli_state *ipc_cli, POLICY_HND *pol,
-                    char *filename, char *name, char *buf, int bufsize)
+                    char *filename, char *attr_name, char *buf, int bufsize)
 {
        uint32 i;
         int n = 0;
         int n_used;
         BOOL all;
         BOOL all_nt;
+        BOOL all_nt_acls;
         BOOL all_dos;
         BOOL some_nt;
         BOOL some_dos;
+        BOOL exclude_nt_revision = False;
+        BOOL exclude_nt_owner = False;
+        BOOL exclude_nt_group = False;
+        BOOL exclude_nt_acl = False;
+        BOOL exclude_dos_mode = False;
+        BOOL exclude_dos_size = False;
+        BOOL exclude_dos_ctime = False;
+        BOOL exclude_dos_atime = False;
+        BOOL exclude_dos_mtime = False;
+        BOOL exclude_dos_inode = False;
         BOOL numeric = True;
         BOOL determine_size = (bufsize == 0);
        int fnum = -1;
        SEC_DESC *sd;
        fstring sidstr;
+        fstring name_sandbox;
+        char *name;
+        char *pExclude;
         char *p;
        time_t m_time = 0, a_time = 0, c_time = 0;
-       size_t size = 0;
+       SMB_OFF_T size = 0;
        uint16 mode = 0;
        SMB_INO_T ino = 0;
         struct cli_state *cli = &srv->cli;
 
+        /* Copy name so we can strip off exclusions (if any are specified) */
+        strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1);
+
+        /* Ensure name is null terminated */
+        name_sandbox[sizeof(name_sandbox) - 1] = '\0';
+
+        /* Play in the sandbox */
+        name = name_sandbox;
+
+        /* If there are any exclusions, point to them and mask them from name */
+        if ((pExclude = strchr(name, '!')) != NULL)
+        {
+                *pExclude++ = '\0';
+        }
+
         all = (StrnCaseCmp(name, "system.*", 8) == 0);
         all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0);
+        all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0);
         all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0);
         some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0);
         some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0);
         numeric = (* (name + strlen(name) - 1) != '+');
 
+        /* Look for exclusions from "all" requests */
+        if (all || all_nt || all_dos) {
+
+                /* Exclusions are delimited by '!' */
+                for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) {
+
+                /* Find end of this exclusion name */
+                if ((p = strchr(pExclude, '!')) != NULL)
+                {
+                    *p = '\0';
+                }
+
+                /* Which exclusion name is this? */
+                if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) {
+                    exclude_nt_revision = True;
+                }
+                else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) {
+                    exclude_nt_owner = True;
+                }
+                else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) {
+                    exclude_nt_group = True;
+                }
+                else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) {
+                    exclude_nt_acl = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) {
+                    exclude_dos_mode = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) {
+                    exclude_dos_size = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.c_time") == 0) {
+                    exclude_dos_ctime = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.a_time") == 0) {
+                    exclude_dos_atime = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.m_time") == 0) {
+                    exclude_dos_mtime = True;
+                }
+                else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) {
+                    exclude_dos_inode = True;
+                }
+                else {
+                    DEBUG(5, ("cacl_get received unknown exclusion: %s\n",
+                              pExclude));
+                    errno = ENOATTR;
+                    return -1;
+                }
+            }
+        }
+
         n_used = 0;
 
         /*
          * If we are (possibly) talking to an NT or new system and some NT
          * attributes have been requested...
          */
-        if (ipc_cli && (all || some_nt)) {
+        if (ipc_cli && (all || some_nt || all_nt_acls)) {
                 /* Point to the portion after "system.nt_sec_desc." */
                 name += 19;     /* if (all) this will be invalid but unused */
 
@@ -3374,139 +3501,105 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
 
                 cli_close(cli, fnum);
 
-                if (all || all_nt) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    "REVISION:%d",
-                                                    sd->revision);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                if (! exclude_nt_revision) {
+                        if (all || all_nt) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx,
+                                                            "REVISION:%d",
+                                                            sd->revision);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     "REVISION:%d", sd->revision);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             "REVISION:%d", sd->revision);
-                        }
-                } else if (StrCaseCmp(name, "revision") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%d", sd->revision);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "revision") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "%d",
+                                                            sd->revision);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "%d",
+                                                     sd->revision);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "%d", sd->revision);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
-                }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                /* Get owner and group sid */
-
-                if (sd->owner_sid) {
-                        convert_sid_to_string(ipc_cli, pol,
-                                              sidstr, numeric, sd->owner_sid);
-                } else {
-                        fstrcpy(sidstr, "");
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
 
-                if (all || all_nt) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
-                                }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",OWNER:%s", sidstr);
-                        }
-                } else if (StrnCaseCmp(name, "owner", 5) == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%s", sidstr);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
-                                }
-                                n = strlen(p);
+                if (! exclude_nt_owner) {
+                        /* Get owner and group sid */
+                        if (sd->owner_sid) {
+                                convert_sid_to_string(ipc_cli, pol,
+                                                      sidstr,
+                                                      numeric,
+                                                      sd->owner_sid);
                         } else {
-                                n = snprintf(buf, bufsize, "%s", sidstr);
+                                fstrcpy(sidstr, "");
                         }
-                }
-
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
-                }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
 
-                if (sd->grp_sid) {
-                        convert_sid_to_string(ipc_cli, pol,
-                                              sidstr, numeric, sd->grp_sid);
-                } else {
-                        fstrcpy(sidstr, "");
-                }
-
-                if (all || all_nt) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        if (all || all_nt) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, ",OWNER:%s",
+                                                            sidstr);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",OWNER:%s", sidstr);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",GROUP:%s", sidstr);
-                        }
-                } else if (StrnCaseCmp(name, "group", 5) == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%s", sidstr);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrnCaseCmp(name, "owner", 5) == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "%s", sidstr);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "%s",
+                                                     sidstr);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "%s", sidstr);
                         }
-                }
 
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                /* Add aces to value buffer  */
-                for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
 
-                        SEC_ACE *ace = &sd->dacl->ace[i];
-                        convert_sid_to_string(ipc_cli, pol,
-                                              sidstr, numeric, &ace->trustee);
+                if (! exclude_nt_group) {
+                        if (sd->grp_sid) {
+                                convert_sid_to_string(ipc_cli, pol,
+                                                      sidstr, numeric,
+                                                      sd->grp_sid);
+                        } else {
+                                fstrcpy(sidstr, "");
+                        }
 
                         if (all || all_nt) {
                                 if (determine_size) {
-                                        p = talloc_asprintf(ctx, 
-                                                            ",ACL:"
-                                                            "%s:%d/%d/0x%08x", 
-                                                            sidstr,
-                                                            ace->type,
-                                                            ace->flags,
-                                                            ace->info.mask);
+                                        p = talloc_asprintf(ctx, ",GROUP:%s",
+                                                            sidstr);
                                         if (!p) {
                                                 errno = ENOMEM;
                                                 return -1;
@@ -3514,36 +3607,22 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
                                         n = strlen(p);
                                 } else {
                                         n = snprintf(buf, bufsize,
-                                                     ",ACL:%s:%d/%d/0x%08x", 
-                                                     sidstr,
-                                                     ace->type,
-                                                     ace->flags,
-                                                     ace->info.mask);
+                                                     ",GROUP:%s", sidstr);
                                 }
-                        } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
-                                    StrCaseCmp(name + 3, sidstr) == 0) ||
-                                   (StrnCaseCmp(name, "acl+", 4) == 0 &&
-                                    StrCaseCmp(name + 4, sidstr) == 0)) {
+                        } else if (StrnCaseCmp(name, "group", 5) == 0) {
                                 if (determine_size) {
-                                        p = talloc_asprintf(ctx, 
-                                                            "%d/%d/0x%08x", 
-                                                            ace->type,
-                                                            ace->flags,
-                                                            ace->info.mask);
+                                        p = talloc_asprintf(ctx, "%s", sidstr);
                                         if (!p) {
                                                 errno = ENOMEM;
                                                 return -1;
                                         }
                                         n = strlen(p);
                                 } else {
-                                        n = snprintf(buf, bufsize,
-                                                     "%d/%d/0x%08x", 
-                                                     ace->type,
-                                                     ace->flags,
-                                                     ace->info.mask);
+                                        n = snprintf(buf, bufsize, "%s", sidstr);
                                 }
                         }
-                        if (n > bufsize) {
+
+                        if (!determine_size && n > bufsize) {
                                 errno = ERANGE;
                                 return -1;
                         }
@@ -3552,6 +3631,97 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
                         bufsize -= n;
                 }
 
+                if (! exclude_nt_acl) {
+                        /* Add aces to value buffer  */
+                        for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+
+                                SEC_ACE *ace = &sd->dacl->ace[i];
+                                convert_sid_to_string(ipc_cli, pol,
+                                                      sidstr, numeric,
+                                                      &ace->trustee);
+
+                                if (all || all_nt) {
+                                        if (determine_size) {
+                                                p = talloc_asprintf(
+                                                        ctx, 
+                                                        ",ACL:"
+                                                        "%s:%d/%d/0x%08x", 
+                                                        sidstr,
+                                                        ace->type,
+                                                        ace->flags,
+                                                        ace->info.mask);
+                                                if (!p) {
+                                                        errno = ENOMEM;
+                                                        return -1;
+                                                }
+                                                n = strlen(p);
+                                        } else {
+                                                n = snprintf(
+                                                        buf, bufsize,
+                                                        ",ACL:%s:%d/%d/0x%08x", 
+                                                        sidstr,
+                                                        ace->type,
+                                                        ace->flags,
+                                                        ace->info.mask);
+                                        }
+                                } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
+                                            StrCaseCmp(name + 3, sidstr) == 0) ||
+                                           (StrnCaseCmp(name, "acl+", 4) == 0 &&
+                                            StrCaseCmp(name + 4, sidstr) == 0)) {
+                                        if (determine_size) {
+                                                p = talloc_asprintf(
+                                                        ctx, 
+                                                        "%d/%d/0x%08x", 
+                                                        ace->type,
+                                                        ace->flags,
+                                                        ace->info.mask);
+                                                if (!p) {
+                                                        errno = ENOMEM;
+                                                        return -1;
+                                                }
+                                                n = strlen(p);
+                                        } else {
+                                                n = snprintf(buf, bufsize,
+                                                             "%d/%d/0x%08x", 
+                                                             ace->type,
+                                                             ace->flags,
+                                                             ace->info.mask);
+                                        }
+                                } else if (all_nt_acls) {
+                                        if (determine_size) {
+                                                p = talloc_asprintf(
+                                                        ctx, 
+                                                        "%s%s:%d/%d/0x%08x",
+                                                        i ? "," : "",
+                                                        sidstr,
+                                                        ace->type,
+                                                        ace->flags,
+                                                        ace->info.mask);
+                                                if (!p) {
+                                                        errno = ENOMEM;
+                                                        return -1;
+                                                }
+                                                n = strlen(p);
+                                        } else {
+                                                n = snprintf(buf, bufsize,
+                                                             "%s%s:%d/%d/0x%08x",
+                                                             i ? "," : "",
+                                                             sidstr,
+                                                             ace->type,
+                                                             ace->flags,
+                                                             ace->info.mask);
+                                        }
+                                }
+                                if (n > bufsize) {
+                                        errno = ERANGE;
+                                        return -1;
+                                }
+                                buf += n;
+                                n_used += n;
+                                bufsize -= n;
+                        }
+                }
+
                 /* Restore name pointer to its original value */
                 name -= 19;
         }
@@ -3569,231 +3739,250 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
                         
                 }
                 
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    "%sMODE:0x%x",
-                                                    (ipc_cli &&
-                                                     (all || some_nt)
-                                                     ? ","
-                                                     : ""),
-                                                    mode);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                if (! exclude_dos_mode) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx,
+                                                            "%sMODE:0x%x",
+                                                            (ipc_cli &&
+                                                             (all || some_nt)
+                                                             ? ","
+                                                             : ""),
+                                                            mode);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     "%sMODE:0x%x",
+                                                     (ipc_cli &&
+                                                      (all || some_nt)
+                                                      ? ","
+                                                      : ""),
+                                                     mode);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             "%sMODE:0x%x",
-                                             (ipc_cli &&
-                                              (all || some_nt)
-                                              ? ","
-                                              : ""),
-                                             mode);
-                        }
-                } else if (StrCaseCmp(name, "mode") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "0x%x", mode);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "mode") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "0x%x", mode);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "0x%x", mode);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "0x%x", mode);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    ",SIZE:%llu",
-                                                    (unsigned long long) size);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+
+                if (! exclude_dos_size) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(
+                                                ctx,
+                                                ",SIZE:%llu",
+                                                (unsigned long long) size);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",SIZE:%llu",
+                                                     (unsigned long long) size);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",SIZE:%llu",
-                                             (unsigned long long) size);
-                        }
-                } else if (StrCaseCmp(name, "size") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    "%llu",
-                                                    (unsigned long long) size);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "size") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(
+                                                ctx,
+                                                "%llu",
+                                                (unsigned long long) size);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     "%llu",
+                                                     (unsigned long long) size);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             "%llu",
-                                             (unsigned long long) size);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    ",C_TIME:%lu", c_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+
+                if (! exclude_dos_ctime) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx,
+                                                            ",C_TIME:%lu",
+                                                            c_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",C_TIME:%lu", c_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",C_TIME:%lu", c_time);
-                        }
-                } else if (StrCaseCmp(name, "c_time") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%lu", c_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "c_time") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "%lu", c_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "%lu", c_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "%lu", c_time);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    ",A_TIME:%lu", a_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+
+                if (! exclude_dos_atime) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx,
+                                                            ",A_TIME:%lu",
+                                                            a_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",A_TIME:%lu", a_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",A_TIME:%lu", a_time);
-                        }
-                } else if (StrCaseCmp(name, "a_time") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%lu", a_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "a_time") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "%lu", a_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "%lu", a_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "%lu", a_time);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    ",M_TIME:%lu", m_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+
+                if (! exclude_dos_mtime) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx,
+                                                            ",M_TIME:%lu",
+                                                            m_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",M_TIME:%lu", m_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",M_TIME:%lu", m_time);
-                        }
-                } else if (StrCaseCmp(name, "m_time") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx, "%lu", m_time);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "m_time") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, "%lu", m_time);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize, "%lu", m_time);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize, "%lu", m_time);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
-
-                if (all || all_dos) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    ",INODE:%llu",
-                                                    (unsigned long long) ino);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+
+                if (! exclude_dos_inode) {
+                        if (all || all_dos) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(
+                                                ctx,
+                                                ",INODE:%llu",
+                                                (unsigned long long) ino);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",INODE:%llu",
+                                                     (unsigned long long) ino);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             ",INODE:%llu",
-                                             (unsigned long long) ino);
-                        }
-                } else if (StrCaseCmp(name, "inode") == 0) {
-                        if (determine_size) {
-                                p = talloc_asprintf(ctx,
-                                                    "%llu",
-                                                    (unsigned long long) ino);
-                                if (!p) {
-                                        errno = ENOMEM;
-                                        return -1;
+                        } else if (StrCaseCmp(name, "inode") == 0) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(
+                                                ctx,
+                                                "%llu",
+                                                (unsigned long long) ino);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     "%llu",
+                                                     (unsigned long long) ino);
                                 }
-                                n = strlen(p);
-                        } else {
-                                n = snprintf(buf, bufsize,
-                                             "%llu",
-                                             (unsigned long long) ino);
                         }
-                }
         
-                if (!determine_size && n > bufsize) {
-                        errno = ERANGE;
-                        return -1;
+                        if (!determine_size && n > bufsize) {
+                                errno = ERANGE;
+                                return -1;
+                        }
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-                buf += n;
-                n_used += n;
-                bufsize -= n;
 
                 /* Restore name pointer to its original value */
                 name -= 16;
@@ -3840,7 +4029,8 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
                         the_acl = p + 1;
                 }
 
-                sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl);
+                sd = sec_desc_parse(ctx, ipc_cli, pol, numeric,
+                                    CONST_DISCARD(char *, the_acl));
 
                 if (!sd) {
                         errno = EINVAL;
@@ -4347,9 +4537,13 @@ int smbc_getxattr_ctx(SMBCCTX *context,
 
         /* Are they requesting a supported attribute? */
         if (StrCaseCmp(name, "system.*") == 0 ||
+            StrnCaseCmp(name, "system.*!", 9) == 0 ||
             StrCaseCmp(name, "system.*+") == 0 ||
+            StrnCaseCmp(name, "system.*+!", 10) == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+            StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
+            StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
@@ -4358,6 +4552,7 @@ int smbc_getxattr_ctx(SMBCCTX *context,
             StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
             StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 ||
             StrCaseCmp(name, "system.dos_attr.*") == 0 ||
+            StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 ||
             StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
             StrCaseCmp(name, "system.dos_attr.size") == 0 ||
             StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
@@ -4368,7 +4563,9 @@ int smbc_getxattr_ctx(SMBCCTX *context,
                 /* Yup. */
                 ret = cacl_get(context, ctx, srv,
                                ipc_srv == NULL ? NULL : &ipc_srv->cli, 
-                               &pol, path, name, (const char *) value, size);
+                               &pol, path,
+                               CONST_DISCARD(char *, name),
+                               CONST_DISCARD(char *, value), size);
                 if (ret < 0 && errno == 0) {
                         errno = smbc_errno(context, &srv->cli);
                 }
@@ -4507,6 +4704,7 @@ int smbc_listxattr_ctx(SMBCCTX *context,
                 "system.nt_sec_desc.owner+\0"
                 "system.nt_sec_desc.group\0"
                 "system.nt_sec_desc.group+\0"
+                "system.nt_sec_desc.acl.*\0"
                 "system.nt_sec_desc.acl\0"
                 "system.nt_sec_desc.acl+\0"
                 "system.nt_sec_desc.*\0"
@@ -4982,10 +5180,25 @@ SMBCCTX * smbc_init_context(SMBCCTX * context)
                          * defaults ...
                          */
 
-                   if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
-                      DEBUG(5, ("Could not load either config file: %s or %s\n",
-                             conf, dyn_CONFIGFILE));
-                   }
+                        if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
+                                DEBUG(5, ("Could not load either config file: "
+                                          "%s or %s\n",
+                                          conf, dyn_CONFIGFILE));
+                        } else {
+                                /*
+                                 * We loaded the global config file.  Now lets
+                                 * load user-specific modifications to the
+                                 * global config.
+                                 */
+                                slprintf(conf, sizeof(conf),
+                                         "%s/.smb/smb.conf.append", home);
+                                if (!lp_load(conf, True, False, False)) {
+                                        DEBUG(10,
+                                              ("Could not append config file: "
+                                               "%s\n",
+                                               conf));
+                                }
+                        }
                 }
 
                 reopen_logs();  /* Get logging working ... */
index 1c93f7b1e2bd15b36e236b4a46f926cfdabacefe..164f85be7bf13146242d9f1c1abeff504edbf61b 100644 (file)
@@ -21,6 +21,9 @@
 
 #include "includes.h"
 
+extern struct in_addr lastip;
+extern int lastport;
+
 int num_good_sends = 0;
 int num_good_receives = 0;
 
@@ -692,8 +695,6 @@ void free_packet(struct packet_struct *packet)
 struct packet_struct *parse_packet(char *buf,int length,
                                   enum packet_type packet_type)
 {
-       extern struct in_addr lastip;
-       extern int lastport;
        struct packet_struct *p;
        BOOL ok=False;
 
index 500ff7cc6e2113e7d43e97a0f432132044711d3a..f0f2024e7b9ff9f0ac477e36ddfb160d23c92732 100644 (file)
@@ -255,7 +255,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
        const size_t offset_end_of_sig = (smb_ss_field + 8);
        unsigned char sequence_buf[8];
        struct MD5Context md5_ctx;
+#if 0
+        /* JRA - apparently this is incorrect. */
        unsigned char key_buf[16];
+#endif
 
        /*
         * Firstly put the sequence number into the first 4 bytes.
index d4b05574118a1337285e9c9eadbc2333c8c33890..55e06ffe9720335213ac401d71132a6e637b394f 100644 (file)
@@ -513,7 +513,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
  *new_pw_len is the length in bytes of the possibly mulitbyte
  returned password including termination.
 ************************************************************/
-BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
+BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
                      int new_pwrd_size, uint32 *new_pw_len,
                      int string_flags)
 {
index a0f5565d4f3f9fbdff12a7e74dcbb1cf2aa95cbd..0387e8f67d84c35ad9c8c40fb949c32b69ea5d6e 100644 (file)
@@ -42,12 +42,14 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
                        asn1_start_tag(asn1, ASN1_CONTEXT(0));
                        asn1_start_tag(asn1, ASN1_SEQUENCE(0));
 
-                       token->mechTypes = SMB_MALLOC_P(char *);
+                       token->mechTypes = SMB_MALLOC_P(const char *);
                        for (i = 0; !asn1->has_error &&
                                     0 < asn1_tag_remaining(asn1); i++) {
                                token->mechTypes = 
-                                       SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2);
-                               asn1_read_OID(asn1, token->mechTypes + i);
+                                       SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2);
+                               asn1_read_OID(asn1,
+                                              CONST_DISCARD(char **,
+                                                              (token->mechTypes + i)));
                        }
                        token->mechTypes[i] = NULL;
                        
@@ -182,7 +184,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
                        break;
                case ASN1_CONTEXT(1):
                        asn1_start_tag(asn1, ASN1_CONTEXT(1));
-                       asn1_read_OID(asn1, &token->supportedMech);
+                       asn1_read_OID(asn1, CONST_DISCARD(char **, &token->supportedMech));
                        asn1_end_tag(asn1);
                        break;
                case ASN1_CONTEXT(2):
@@ -317,7 +319,8 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego)
                if (spnego->negTokenInit.mechTypes) {
                        int i;
                        for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) {
-                               free(spnego->negTokenInit.mechTypes[i]);
+                               free(CONST_DISCARD(void *,
+                                                     spnego->negTokenInit.mechTypes[i]));
                        }
                        free(spnego->negTokenInit.mechTypes);
                }
@@ -326,7 +329,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego)
                break;
        case SPNEGO_NEG_TOKEN_TARG:
                if (spnego->negTokenTarg.supportedMech) {
-                       free(spnego->negTokenTarg.supportedMech);
+                       free(CONST_DISCARD(void *, spnego->negTokenTarg.supportedMech));
                }
                data_blob_free(&spnego->negTokenTarg.responseToken);
                data_blob_free(&spnego->negTokenTarg.mechListMIC);
index 491c51294e9ca0e68704250b126865671c7229e8..2ce07f898caff989d6cc0ee2d4bdec112199d083 100644 (file)
    the right thing about local DST.  Unlike previous versions, this
    version is reentrant.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-#  include <alloca.h>
-# endif
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
 #endif
 
 /* Since the code of getdate.y is not included in the Emacs executable
index aab37f4d23554163fcab0c5de345af340d58c9ee..ecae7311ac8628dec99a78a62d83ae7297a501b0 100644 (file)
    the right thing about local DST.  Unlike previous versions, this
    version is reentrant.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-#  include <alloca.h>
-# endif
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
 #endif
 
 /* Since the code of getdate.y is not included in the Emacs executable
diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c
new file mode 100644 (file)
index 0000000..f77739b
--- /dev/null
@@ -0,0 +1,317 @@
+/* 
+ * Catia VFS module
+ *
+ * Implement a fixed mapping of forbidden NT characters in filenames that are
+ * used a lot by the CAD package Catia.
+ *
+ * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
+ * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
+ * under Windows...
+ *
+ * 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 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+static void catia_string_replace(char *s, unsigned char oldc, unsigned 
+                                char newc)
+{
+        static smb_ucs2_t tmpbuf[sizeof(pstring)];
+        smb_ucs2_t *ptr = tmpbuf;
+        smb_ucs2_t old = oldc;
+
+        push_ucs2(NULL, tmpbuf, s, sizeof(tmpbuf), STR_TERMINATE);
+
+        for (;*ptr;ptr++)
+                if (*ptr==old) *ptr=newc;
+
+        pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+}
+
+static void from_unix(char *s)
+{
+        catia_string_replace(s, '\x22', '\xa8');
+        catia_string_replace(s, '\x2a', '\xa4');
+        catia_string_replace(s, '\x2f', '\xf8');
+        catia_string_replace(s, '\x3a', '\xf7');
+        catia_string_replace(s, '\x3c', '\xab');
+        catia_string_replace(s, '\x3e', '\xbb');
+        catia_string_replace(s, '\x3f', '\xbf');
+        catia_string_replace(s, '\x5c', '\xff');
+        catia_string_replace(s, '\x7c', '\xa6');
+        catia_string_replace(s, ' ', '\xb1');
+}
+
+static void to_unix(char *s)
+{
+        catia_string_replace(s, '\xa8', '\x22');
+        catia_string_replace(s, '\xa4', '\x2a');
+        catia_string_replace(s, '\xf8', '\x2f');
+        catia_string_replace(s, '\xf7', '\x3a');
+        catia_string_replace(s, '\xab', '\x3c');
+        catia_string_replace(s, '\xbb', '\x3e');
+        catia_string_replace(s, '\xbf', '\x3f');
+        catia_string_replace(s, '\xff', '\x5c');
+        catia_string_replace(s, '\xa6', '\x7c');
+        catia_string_replace(s, '\xb1', ' ');
+}
+
+static DIR *catia_opendir(vfs_handle_struct *handle, connection_struct 
+                         *conn, const char *fname)
+{
+        pstring name;
+        pstrcpy(name, fname);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_OPENDIR(handle, conn, name);
+}
+
+static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle, 
+                                       connection_struct *conn, DIR *dirp)
+{
+        SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
+
+        if (result == NULL)
+                return result;
+
+        from_unix(result->d_name);
+        return result;
+}
+
+static int catia_open(vfs_handle_struct *handle, connection_struct *conn, 
+                     const char *fname, int flags, mode_t mode)
+{
+        pstring name;
+
+        pstrcpy(name, fname);
+        to_unix(name);
+        return SMB_VFS_NEXT_OPEN(handle, conn, name, flags, mode);
+}
+
+static int catia_rename(vfs_handle_struct *handle, connection_struct *conn,
+                       const char *old, const char *new)
+{
+        pstring oname, nname;
+
+        pstrcpy(oname, old);
+        to_unix(oname);
+        pstrcpy(nname, new);
+        to_unix(nname);
+
+        DEBUG(10, ("converted old name: %s\n", oname));
+        DEBUG(10, ("converted new name: %s\n", nname));
+        return SMB_VFS_NEXT_RENAME(handle, conn, oname, nname);
+}
+
+static int catia_stat(vfs_handle_struct *handle, connection_struct *conn, 
+                     const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+        pstring name;
+        pstrcpy(name, fname);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_STAT(handle, conn, name, sbuf);
+}
+
+static int catia_lstat(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path, SMB_STRUCT_STAT *sbuf)
+{
+        pstring name;
+        pstrcpy(name, path);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_LSTAT(handle, conn, name, sbuf);
+}
+
+static int catia_unlink(vfs_handle_struct *handle, connection_struct *conn,
+                       const char *path)
+{
+        pstring name;
+        pstrcpy(name, path);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_UNLINK(handle, conn, name);
+}
+
+static int catia_chmod(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path, mode_t mode)
+{
+        pstring name;
+        pstrcpy(name, path);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_CHMOD(handle, conn, name, mode);
+}
+
+static int catia_chown(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path, uid_t uid, gid_t gid)
+{
+        pstring name;
+        pstrcpy(name, path);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_CHOWN(handle, conn, name, uid, gid);
+}
+
+static int catia_chdir(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path)
+{
+        pstring name;
+        pstrcpy(name, path);
+        to_unix(name);
+
+        return SMB_VFS_NEXT_CHDIR(handle, conn, name);
+}
+
+static char *catia_getwd(vfs_handle_struct *handle, connection_struct *conn,
+                        char *buf)
+{
+        return SMB_VFS_NEXT_GETWD(handle, conn, buf);
+}
+
+static int catia_utime(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path, struct utimbuf *times)
+{
+        return SMB_VFS_NEXT_UTIME(handle, conn, path, times);
+}
+
+static BOOL catia_symlink(vfs_handle_struct *handle, connection_struct *conn,
+                         const char *oldpath, const char *newpath)
+{
+        return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
+}
+
+static BOOL catia_readlink(vfs_handle_struct *handle, connection_struct *conn,
+                          const char *path, char *buf, size_t bufsiz)
+{
+        return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
+}
+
+static int catia_link(vfs_handle_struct *handle, connection_struct *conn, 
+                     const char *oldpath, const char *newpath)
+{
+        return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
+}
+
+static int catia_mknod(vfs_handle_struct *handle, connection_struct *conn, 
+                      const char *path, mode_t mode, SMB_DEV_T dev)
+{
+        return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev);
+}
+
+static char *catia_realpath(vfs_handle_struct *handle, connection_struct *conn,
+                           const char *path, char *resolved_path)
+{
+        return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
+}
+
+static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+                              const char *name, uint32 security_info,
+                              struct  security_descriptor_info **ppdesc)
+{
+        return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info,
+                                      ppdesc);
+}
+
+static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, 
+                            const char *name, uint32 security_info_sent,
+                            struct security_descriptor_info *psd)
+{
+        return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent,
+                                      psd);
+}
+
+static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
+                          const char *name, mode_t mode)
+{
+        /* If the underlying VFS doesn't have ACL support... */
+        if (!handle->vfs_next.ops.chmod_acl) {
+                errno = ENOSYS;
+                return -1;
+        }
+        return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode);
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple catia_op_tuples[] = {
+
+        /* Directory operations */
+
+        {SMB_VFS_OP(catia_opendir), SMB_VFS_OP_OPENDIR, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_readdir), SMB_VFS_OP_READDIR, 
+SMB_VFS_LAYER_TRANSPARENT},
+
+        /* File operations */
+
+        {SMB_VFS_OP(catia_open), SMB_VFS_OP_OPEN, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_rename),                      SMB_VFS_OP_RENAME, 
+        SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_stat), SMB_VFS_OP_STAT, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_lstat),                       SMB_VFS_OP_LSTAT,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_unlink),                      SMB_VFS_OP_UNLINK, 
+        SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_chmod),                       SMB_VFS_OP_CHMOD,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_chown),                       SMB_VFS_OP_CHOWN,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_chdir),                       SMB_VFS_OP_CHDIR,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_getwd),                       SMB_VFS_OP_GETWD,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_utime),                       SMB_VFS_OP_UTIME,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_symlink), SMB_VFS_OP_SYMLINK, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_readlink), SMB_VFS_OP_READLINK, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_link), SMB_VFS_OP_LINK, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_mknod),                       SMB_VFS_OP_MKNOD,  
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_realpath), SMB_VFS_OP_REALPATH, 
+SMB_VFS_LAYER_TRANSPARENT},
+
+        /* NT File ACL operations */
+
+        {SMB_VFS_OP(catia_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, 
+SMB_VFS_LAYER_TRANSPARENT},
+        {SMB_VFS_OP(catia_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, 
+SMB_VFS_LAYER_TRANSPARENT},
+
+        /* POSIX ACL operations */
+
+        {SMB_VFS_OP(catia_chmod_acl), SMB_VFS_OP_CHMOD_ACL, 
+SMB_VFS_LAYER_TRANSPARENT},
+
+
+        {NULL,                                          SMB_VFS_OP_NOOP,   
+SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS init_module(void)
+{
+        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia", 
+catia_op_tuples);
+}
index 740218dcd4192864cb1b2985b496d22c1a46b07a..4d10ea5f3378bd7a86ea874c9462137b5230b76f 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
@@ -33,8 +35,6 @@ static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, c
 
        ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
        if (ret == 0) {
-               extern struct current_user current_user;
-               
                if (S_ISDIR(sbuf->st_mode)) {
                        sbuf->st_mode = S_IFDIR | S_IRWXU;
                } else {
@@ -53,8 +53,6 @@ static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd
 
        ret = SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf);
        if (ret == 0) {
-               extern struct current_user current_user;
-               
                if (S_ISDIR(sbuf->st_mode)) {
                        sbuf->st_mode = S_IFDIR | S_IRWXU;
                } else {
index 3c59fd9d61f18b35115df84d0cb64b468524fd05..e4809a64c4271c7a97bb195ac62105271aeeda65 100644 (file)
@@ -26,8 +26,8 @@ static struct {
        char *to;
        int len;
 } weird_table[] = {
-       {'q', "^q^", 3},
-       {'Q', "^Q^", 3},
+       {'q', CONST_DISCARD(char *, "^q^"), 3},
+       {'Q', CONST_DISCARD(char *, "^Q^"), 3},
        {0, NULL}
 };
 
index f8006a22a9edcbb6952f7752c4a0f7d5e77756d5..532b578f3c79b8937775c49a6da42394f643d8a3 100644 (file)
@@ -27,6 +27,8 @@ int ClientNMB       = -1;
 int ClientDGRAM     = -1;
 int global_nmb_port = -1;
 
+extern BOOL rescan_listen_set;
+extern struct in_addr loopback_ip;
 extern BOOL global_in_nmbd;
 
 extern BOOL override_logfile;
@@ -196,8 +198,6 @@ static BOOL reload_interfaces(time_t t)
        static time_t lastt;
        int n;
        struct subnet_record *subrec;
-       extern BOOL rescan_listen_set;
-       extern struct in_addr loopback_ip;
 
        if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
        lastt = t;
index ecfd92719bf8eb25267a76e9ee893a206b24960f..b53a6d7328fd037206c41032c34abe62e2e6271d 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "includes.h"
 
+extern struct in_addr loopback_ip;
 extern int ClientNMB;
 extern int ClientDGRAM;
 extern int global_nmb_port;
@@ -211,7 +212,6 @@ BOOL create_subnets(void)
        int num_interfaces = iface_count();
        int i;
        struct in_addr unicast_ip, ipzero;
-       extern struct in_addr loopback_ip;
 
        if(num_interfaces == 0) {
                DEBUG(0,("create_subnets: No local interfaces !\n"));
index c6bcb3e574284b862f2688530489344cf6b46657..33690133bf88de614e6aa94eb17da3f805d0d970 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "includes.h"
 
+extern fstring local_machine;
+
 struct sync_record {
        struct sync_record *next, *prev;
        unstring workgroup;
@@ -65,7 +67,6 @@ static void sync_child(char *name, int nm_type,
                       struct in_addr ip, BOOL local, BOOL servers,
                       char *fname)
 {
-       extern fstring local_machine;
        fstring unix_workgroup;
        static struct cli_state cli;
        uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
index 3a920c1134b3cb3310c62d5f0575c5f2db960c41..5e08c0853e1e3ead2677178f25f98ed9b37353a8 100644 (file)
@@ -28,8 +28,6 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-extern DOM_SID global_sid_NULL;                        /* NULL sid */
-
 NSS_STATUS winbindd_request(int req_type,
                                  struct winbindd_request *request,
                                  struct winbindd_response *response);
index 9caf7affc3934a2e517e1bf4be20c46ae17f63fc..6ba0cbbf4287cd1fc4d039a48c281621d117552d 100644 (file)
@@ -26,6 +26,9 @@
 
 #include "winbind_client.h"
 
+#define CONST_DISCARD(type, ptr)      ((type) ((void *) (ptr)))
+#define CONST_ADD(type, ptr)          ((type) ((const void *) (ptr)))
+
 /* Global variables.  These are effectively the client state information */
 
 int winbindd_fd = -1;           /* fd for winbindd socket */
@@ -606,14 +609,14 @@ NSS_STATUS winbindd_request(int req_type,
 
 BOOL winbind_off( void )
 {
-       static char *s = WINBINDD_DONT_ENV "=1";
+        static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=1");
 
        return putenv(s) != -1;
 }
 
 BOOL winbind_on( void )
 {
-       static char *s = WINBINDD_DONT_ENV "=0";
+       static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=0");
 
        return putenv(s) != -1;
 }
index 6f4a0a275335d089266fa54f29922748af908a59..6840dd91871bdcd9dd8625c4ee16274360bec75a 100644 (file)
@@ -898,8 +898,6 @@ int main(int argc, char **argv)
                idmap_proxyonly();
        }
 
-       generate_wellknown_sids();
-
        /* Unblock all signals we are interested in as they may have been
           blocked by the parent process. */
 
index cd1d16e34411349ac7aa6a26518fb0b38ea575ac..863ae35fed4a999102ed0e25f03ba75a5e65fe98 100644 (file)
@@ -245,7 +245,6 @@ struct winbindd_idmap_methods {
 #include "nsswitch/winbindd_proto.h"
 
 #include "rpc_parse.h"
-#include "rpc_client.h"
 
 #define WINBINDD_ESTABLISH_LOOP 30
 #define WINBINDD_RESCAN_FREQ 300
index 2c8b7cae28755e43aef73e0dc087b3bee587920c..cd0b5b7e0669b513d14792865d4a83fad891f0ac 100644 (file)
@@ -222,7 +222,7 @@ static WINBINDD_GR* string2group( char *string )
                        gr_members = SMB_XMALLOC_ARRAY(char*, num_gr_members+1);
                        
                        i = 0;
-                       while ( next_token(&str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
+                       while ( next_token((const char **) &str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
                                gr_members[i++] = smb_xstrdup(buffer);
                        }
 
index 88a7d3ed3b1c2186abd2b7eabf08e06afcc1a5ff..4daf4ba989085ed8ed31fad0d098711148fe01d9 100644 (file)
@@ -27,6 +27,8 @@
 
 #ifdef HAVE_ADS
 
+extern struct winbindd_methods msrpc_methods, cache_methods;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
@@ -76,7 +78,6 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 
        status = ads_connect(ads);
        if (!ADS_ERR_OK(status) || !ads->config.realm) {
-               extern struct winbindd_methods msrpc_methods, cache_methods;
                DEBUG(1,("ads_connect for domain %s failed: %s\n", 
                         domain->name, ads_errstr(status)));
                ads_destroy(&ads);
index 3fc62df005f27d67527185fa0342f03c83bc51ee..cc385a1dd72d56cbd0be86398a2d7be6369c8d3a 100644 (file)
 #include "includes.h"
 #include "winbindd.h"
 
+extern BOOL opt_nocache;
+extern struct winbindd_methods msrpc_methods;
+extern struct winbindd_methods ads_methods;
+extern BOOL opt_dual_daemon;
+extern BOOL background_process;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
@@ -47,8 +53,6 @@ static struct winbind_cache *wcache;
 /* flush the cache */
 void wcache_flush_cache(void)
 {
-       extern BOOL opt_nocache;
-
        if (!wcache)
                return;
        if (wcache->tdb) {
@@ -102,11 +106,9 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
        struct winbind_cache *ret = wcache;
 
        if (!domain->backend) {
-               extern struct winbindd_methods msrpc_methods;
                switch (lp_security()) {
 #ifdef HAVE_ADS
                case SEC_ADS: {
-                       extern struct winbindd_methods ads_methods;
                        /* always obey the lp_security parameter for our domain */
                        if (domain->primary) {
                                domain->backend = &ads_methods;
@@ -469,13 +471,11 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
        centry->sequence_number = centry_uint32(centry);
 
        if (centry_expired(domain, kstr, centry)) {
-               extern BOOL opt_dual_daemon;
 
                DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
                         kstr, domain->name ));
 
                if (opt_dual_daemon) {
-                       extern BOOL background_process;
                        background_process = True;
                        DEBUG(10,("wcache_fetch: background processing expired entry %s for domain %s\n",
                                 kstr, domain->name ));
index 51618bd00fdef98c1920051f1ec93e7d12660381..f0d3bc43ea6867ad065f9ca3ea4c34a20e102b1b 100644 (file)
@@ -920,6 +920,52 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
        return WINBINDD_OK;
 }
 
+static BOOL enum_alias_memberships(const DOM_SID *member_sid,
+                                  DOM_SID **aliases, int *num_aliases)
+{
+       TALLOC_CTX *mem_ctx = talloc_init("enum_alias_memberships");
+
+       uint32 *rids = NULL;
+       int i, num_rids = 0;
+
+       BOOL result = False;
+
+       if (mem_ctx == NULL)
+               return False;
+       
+       *aliases = NULL;
+       *num_aliases = 0;
+
+       if (!pdb_enum_alias_memberships(mem_ctx, get_global_sam_sid(),
+                                       member_sid, 1, &rids, &num_rids))
+               goto done;
+
+       for (i=0; i<num_rids; i++) {
+               DOM_SID alias_sid;
+               sid_copy(&alias_sid, get_global_sam_sid());
+               sid_append_rid(&alias_sid, rids[i]);
+               add_sid_to_array(NULL, &alias_sid, aliases, num_aliases);
+       }
+
+       if (!pdb_enum_alias_memberships(mem_ctx, &global_sid_Builtin,
+                                       member_sid, 1, &rids, &num_rids))
+               goto done;
+
+       for (i=0; i<num_rids; i++) {
+               DOM_SID alias_sid;
+               sid_copy(&alias_sid, &global_sid_Builtin);
+               sid_append_rid(&alias_sid, rids[i]);
+               add_sid_to_array(NULL, &alias_sid, aliases, num_aliases);
+       }
+
+       result = True;
+ done:
+       if (mem_ctx != NULL)
+               talloc_destroy(mem_ctx);
+
+       return result;
+}
+
 static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
 {
        gid_t gid;
@@ -937,7 +983,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
 
        /* Add nested group memberships */
 
-       if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
+       if (!enum_alias_memberships(sid, &aliases, &num_aliases))
                return;
 
        for (j=0; j<num_aliases; j++) {
@@ -953,7 +999,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
                        continue;
                }
 
-               add_gid_to_array_unique(gid, gids, num);
+               add_gid_to_array_unique(NULL, gid, gids, num);
        }
        SAFE_FREE(aliases);
 }
@@ -974,7 +1020,7 @@ static void add_gids_from_group_sid(DOM_SID *sid, gid_t **gids, int *num)
                   sid_string_static(sid)));
 
        if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0)))
-               add_gid_to_array_unique(gid, gids, num);
+               add_gid_to_array_unique(NULL, gid, gids, num);
 
        add_local_gids_from_sid(sid, gids, num);
 }
@@ -1178,7 +1224,7 @@ static void add_local_sids_from_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
        DOM_SID *aliases = NULL;
        int i, num_aliases = 0;
 
-       if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
+       if (!enum_alias_memberships(sid, &aliases, &num_aliases))
                return;
 
        if (num_aliases == 0)
index 88e3254d24a8fe989a8783e19c29ee8887122e30..06ebd68f8f80ae0d8fd9f14bff43306fdeb2c21a 100644 (file)
@@ -11,7 +11,7 @@
 */
 
 #ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
+#define SAFE_FREE(x) do { if(x) {free(CONST_DISCARD(void *, (x))); x=NULL;} } while(0)
 #endif
 
 #ifndef _WINBINDD_NTDOM_H
index bd15777bd311041cc01b37d4e74e87b3c42382d7..23a56e4ea637a2c8b1451acb6f5ca26854b87081 100644 (file)
@@ -207,23 +207,33 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                                uint32 *num_entries, 
                                struct acct_info **info)
 {
-       struct acct_info *talloced_info;
+       struct pdb_search *search;
+       struct samr_displayentry *aliases;
+       int i;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
-       /* Hmm. One billion aliases should be enough for a start */
+       search = pdb_search_aliases(&domain->sid);
+       if (search == NULL) goto done;
 
-       if (!pdb_enum_aliases(&domain->sid, 0, 1000000000,
-                             num_entries, info)) {
-               /* Nothing to report, just exit. */
-               return NT_STATUS_OK;
-       }
+       *num_entries = pdb_search_entries(search, 0, 0xffffffff, &aliases);
+       if (*num_entries == 0) goto done;
 
-       talloced_info = (struct acct_info *)TALLOC_MEMDUP(mem_ctx, *info,
-                             *num_entries * sizeof(struct acct_info));
+       *info = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);
+       if (*info == NULL) {
+               result = NT_STATUS_NO_MEMORY;
+               goto done;
+       }
 
-       SAFE_FREE(*info);
-       *info = talloced_info;
+       for (i=0; i<*num_entries; i++) {
+               fstrcpy((*info)[i].acct_name, aliases[i].account_name);
+               fstrcpy((*info)[i].acct_desc, aliases[i].description);
+               (*info)[i].rid = aliases[i].rid;
+       }
 
-       return NT_STATUS_OK;
+       result = NT_STATUS_OK;
+ done:
+       pdb_search_destroy(search);
+       return result;
 }
 
 /* convert a single name to a sid in a domain */
index 99d12563c6cab3602aed54317b78f9ee7ec6d4b4..1dfa810a8d3869e1f30718761ef8ee6e3d16310a 100644 (file)
@@ -788,7 +788,8 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
        to.tv_sec = 10;
        to.tv_usec = 0;
 
-       if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
+       if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
+                           CONST_DISCARD(char **, &attrs[0]), 0, &to, &res))
                goto done;
 
        if (ldap_count_entries(ldp, res) != 1)
index 11da05ac3b45e481b48f151bea24389c5eaadb48..68560c040e4aed3b8c1952ec171eaf387ef53787 100644 (file)
@@ -24,6 +24,9 @@
 #include "includes.h"
 #include "winbindd.h"
 
+extern struct winbindd_methods cache_methods;
+extern struct winbindd_methods passdb_methods;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
@@ -85,25 +88,17 @@ void free_domain_list(void)
 
 static BOOL is_internal_domain(const DOM_SID *sid)
 {
-       extern DOM_SID global_sid_Builtin;
-
        if (sid == NULL)
                return False;
 
-       if (sid_compare_domain(sid, get_global_sam_sid()) == 0)
-               return True;
-
-       if (sid_compare_domain(sid, &global_sid_Builtin) == 0)
-               return True;
-
-       return False;
+       return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
 }
 
 
 /* Add a trusted domain to our list of domains */
 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
                                                  struct winbindd_methods *methods,
-                                                 DOM_SID *sid)
+                                                 const DOM_SID *sid)
 {
        struct winbindd_domain *domain;
        const char *alternative_name = NULL;
@@ -183,7 +178,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
 
 static void add_trusted_domains( struct winbindd_domain *domain )
 {
-       extern struct winbindd_methods cache_methods;
        TALLOC_CTX *mem_ctx;
        NTSTATUS result;
        time_t t;
@@ -284,9 +278,6 @@ void rescan_trusted_domains( void )
 /* Look up global info for the winbind daemon */
 BOOL init_domain_list(void)
 {
-       extern DOM_SID global_sid_Builtin;
-       extern struct winbindd_methods cache_methods;
-       extern struct winbindd_methods passdb_methods;
        struct winbindd_domain *domain;
 
        /* Free existing list */
@@ -636,7 +627,7 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
 */
 void fill_domain_username(fstring name, const char *domain, const char *user)
 {
-       strlower_m( user );
+        strlower_m(CONST_DISCARD(char *, user));
 
        if (assume_domain(domain)) {
                strlcpy(name, user, sizeof(fstring));
index 493f1142daa03bbeeb5879a4011e9b7a291b3d25..06070b07003533eb0fbb8a4e95804d40f18c21ae 100644 (file)
@@ -58,6 +58,7 @@ BOOL bLoaded = False;
 
 extern userdom_struct current_user_info;
 extern pstring user_socket_options;
+extern enum protocol_types Protocol;
 
 #ifndef GLOBAL_NAME
 #define GLOBAL_NAME "global"
@@ -73,7 +74,7 @@ extern pstring user_socket_options;
 
 /* some helpful bits */
 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
-#define VALID(i) ServicePtrs[i]->valid
+#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
 
 int keepalive = DEFAULT_KEEPALIVE;
 BOOL use_getwd_cache = True;
@@ -183,8 +184,16 @@ typedef struct
        char *szAddShareCommand;
        char *szChangeShareCommand;
        char *szDeleteShareCommand;
+        char *szEventLogOpenCommand;
+        char *szEventLogReadCommand;
+        char *szEventLogClearCommand;
+        char *szEventLogNumRecordsCommand;
+        char *szEventLogOldestRecordCommand;
+       char *szEventLogCloseCommand;
+        char **szEventLogs;
        char *szGuestaccount;
        char *szManglingMethod;
+       char **szServicesList;
        int mangle_prefix;
        int max_log_size;
        char *szLogLevel;
@@ -237,6 +246,7 @@ typedef struct
        int ldap_passwd_sync; 
        int ldap_replication_sleep;
        int ldap_timeout; /* This is initialised in init_globals */
+       int ldap_page_size;
        BOOL ldap_delete_dn;
        BOOL bMsAddPrinterWizard;
        BOOL bDNSproxy;
@@ -272,6 +282,7 @@ typedef struct
        BOOL bNTPipeSupport;
        BOOL bNTStatusSupport;
        BOOL bStatCache;
+       int iMaxStatCacheSize;
        BOOL bKernelOplocks;
        BOOL bAllowTrustedDomains;
        BOOL bLanmanAuth;
@@ -413,6 +424,7 @@ typedef struct
        BOOL bBlockingLocks;
        BOOL bInheritPerms;
        BOOL bInheritACLS;
+       BOOL bInheritOwner;
        BOOL bMSDfsRoot;
        BOOL bUseClientDriver;
        BOOL bDefaultDevmode;
@@ -539,6 +551,7 @@ static service sDefault = {
        True,                   /* bBlockingLocks */
        False,                  /* bInheritPerms */
        False,                  /* bInheritACLS */
+       False,                  /* bInheritOwner */
        False,                  /* bMSDfsRoot */
        False,                  /* bUseClientDriver */
        False,                  /* bDefaultDevmode */
@@ -581,6 +594,7 @@ static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr
 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
 static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
+static BOOL handle_eventlog( int snum, const char *pszParmValue, char **ptr);
 
 static void set_server_role(void);
 static void set_default_server_announce_type(void);
@@ -864,6 +878,7 @@ static struct parm_struct parm_table[] = {
        {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
        {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
+       {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, 
 
@@ -932,6 +947,8 @@ static struct parm_struct parm_table[] = {
        {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
        {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
 
+       {"enable svcctl", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
+
        {N_("Tuning Options"), P_SEP, P_SEPARATOR}, 
 
        {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
@@ -975,6 +992,7 @@ static struct parm_struct parm_table[] = {
        {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
        {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
        {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
+       {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE}, 
        {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
        {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
        {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
@@ -1017,6 +1035,7 @@ static struct parm_struct parm_table[] = {
        {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
        {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
        {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, 
+       {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, 
        {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, 
        {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
 
@@ -1103,6 +1122,7 @@ static struct parm_struct parm_table[] = {
        {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, 
        {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, 
        {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
+       {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
        {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, 
 
        {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, 
@@ -1110,6 +1130,14 @@ static struct parm_struct parm_table[] = {
        {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED}, 
        {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, 
 
+       {N_("EventLog Options"), P_SEP, P_SEPARATOR}, 
+       {"eventlog open command", P_STRING, P_GLOBAL, &Globals.szEventLogOpenCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+       {"eventlog read command", P_STRING, P_GLOBAL, &Globals.szEventLogReadCommand, handle_eventlog, NULL, FLAG_ADVANCED}, 
+       {"eventlog clear command", P_STRING, P_GLOBAL, &Globals.szEventLogClearCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+       {"eventlog num records command", P_STRING, P_GLOBAL, &Globals.szEventLogNumRecordsCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+       {"eventlog oldest record command", P_STRING, P_GLOBAL, &Globals.szEventLogOldestRecordCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+       {"eventlog list",  P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
+       
        {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 
        {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
        {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
@@ -1378,7 +1406,7 @@ static void init_globals(void)
        Globals.AlgorithmicRidBase = BASE_RID;
 
        Globals.bLoadPrinters = True;
-       Globals.PrintcapCacheTime = 0;
+       Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
        /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
        /* Discovered by 2 days of pain by Don McCall @ HP :-). */
        Globals.max_xmit = 0x4104;
@@ -1438,6 +1466,7 @@ static void init_globals(void)
        Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
        Globals.bNTStatusSupport = True; /* Use NT status by default. */
        Globals.bStatCache = True;      /* use stat cache by default */
+       Globals.iMaxStatCacheSize = 0;  /* unlimited size in kb by default. */
        Globals.restrict_anonymous = 0;
        Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
        Globals.bClientPlaintextAuth = True;    /* Do use a plaintext password if is requested by the server */
@@ -1485,6 +1514,7 @@ static void init_globals(void)
        Globals.ldap_delete_dn = False;
        Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
        Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
+       Globals.ldap_page_size = LDAP_PAGE_SIZE;
 
        /* This is what we tell the afs client. in reality we set the token 
         * to never expire, though, when this runs out the afs client will 
@@ -1527,6 +1557,12 @@ static void init_globals(void)
        string_set(&Globals.szAclCompat, "");
        string_set(&Globals.szCupsServer, "");
 
+       string_set(&Globals.szEventLogOpenCommand, "");
+       string_set(&Globals.szEventLogReadCommand, "");
+       string_set(&Globals.szEventLogClearCommand, "");
+       string_set(&Globals.szEventLogNumRecordsCommand, "");
+       string_set(&Globals.szEventLogOldestRecordCommand, "");
+
        Globals.winbind_cache_time = 300;       /* 5 minutes */
        Globals.bWinbindEnableLocalAccounts = False;
        Globals.bWinbindEnumUsers = True;
@@ -1553,6 +1589,8 @@ static void init_globals(void)
           operations as root */
 
        Globals.bEnablePrivileges = False;
+       
+       Globals.szServicesList = str_list_make( "Spooler NETLOGON", NULL );
 }
 
 static TALLOC_CTX *lp_talloc;
@@ -1719,6 +1757,7 @@ FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
 
+
 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
 FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
 
@@ -1734,10 +1773,19 @@ FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
+FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
 
+FN_GLOBAL_STRING(lp_eventlog_open_cmd, &Globals.szEventLogOpenCommand)
+FN_GLOBAL_STRING(lp_eventlog_read_cmd, &Globals.szEventLogReadCommand)
+FN_GLOBAL_STRING(lp_eventlog_clear_cmd, &Globals.szEventLogClearCommand)
+FN_GLOBAL_STRING(lp_eventlog_num_records_cmd, &Globals.szEventLogNumRecordsCommand)
+FN_GLOBAL_STRING(lp_eventlog_oldest_record_cmd, &Globals.szEventLogOldestRecordCommand)
+FN_GLOBAL_STRING(lp_eventlog_close_cmd, &Globals.szEventLogCloseCommand)
+FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
+
 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
@@ -1773,6 +1821,7 @@ FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
+FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
@@ -1835,6 +1884,7 @@ FN_LOCAL_STRING(lp_username, szUsername)
 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
+FN_GLOBAL_LIST(lp_enable_svcctl, &Globals.szServicesList)
 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
@@ -1907,6 +1957,7 @@ FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
+FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
@@ -2765,6 +2816,12 @@ static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
        return True;
 }
 
+static BOOL handle_eventlog(int snum, const char *pszParmValue, char **ptr)
+{
+       string_set(ptr, pszParmValue);
+       return True;
+}
+
 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
 {
        BOOL ret;
@@ -4311,7 +4368,6 @@ const char *lp_printcapname(void)
 
 BOOL lp_use_sendfile(int snum)
 {
-       extern enum protocol_types Protocol;
        /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
        if (Protocol < PROTOCOL_NT1) {
                return False;
index 9d21d25a240dd7ac91640355c3e70cfb2f3723c7..3b736113befc7bcf383210819ed642fcc1feb7e3 100644 (file)
@@ -81,6 +81,8 @@
 
 #include "includes.h"
 
+extern BOOL in_client;
+
 /* -------------------------------------------------------------------------- **
  * Constants...
  */
@@ -523,7 +525,6 @@ static BOOL Parse( myFILE *InFile,
 static myFILE *OpenConfFile( const char *FileName )
 {
        const char *func = "params.c:OpenConfFile() -";
-       extern BOOL in_client;
        int lvl = in_client?1:0;
        myFILE *ret;
 
index ae0b16273f207ad7dd8d6beced8fa0f619a91e47..ecc7d291f6dfe2f0f3a320a883ad44b7f1007cf5 100644 (file)
@@ -86,8 +86,6 @@ static DOM_SID *pdb_generate_sam_sid(void)
        if(!(sam_sid=SMB_MALLOC_P(DOM_SID)))
                return NULL;
                        
-       generate_wellknown_sids();
-
        switch (lp_server_role()) {
        case ROLE_DOMAIN_PDC:
        case ROLE_DOMAIN_BDC:
index deac2bbd6e3e20797160a0321d74d1abd7e3a7fa..203fa2bf21e8b46f5ffac21978ef24a83a31a22a 100644 (file)
@@ -1894,7 +1894,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
        /* Change from V1 is addition of password history field. */
        account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
        if (pwHistLen) {
-               char *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
+               uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
                if (!pw_hist) {
                        ret = False;
                        goto done;
index 4b59b5fdf95a171a055ed064f1cc3c8b6c8832e7..99afac133acbc3a729a97908284a9ce0d4133863 100644 (file)
@@ -1195,7 +1195,7 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
                        /* We need to make sure we don't have a race condition here - the
                           account policy history length can change between when the pw_history
                           was first loaded into the SAM_ACCOUNT struct and now.... JRA. */
-                       pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
+                       pwhistory = CONST_DISCARD(uchar *, pdb_get_pw_history(sampass, &current_history_len));
 
                        if (current_history_len != pwHistLen) {
                                /* After closing and reopening SAM_ACCOUNT the history
index 84d398ccd64ed1634f57e2e714e2018005fd69f5..edcd1c92223ecc116bca1ccff3e67b38dc24bf85 100644 (file)
@@ -48,7 +48,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
 
 static void pdb_force_pw_initialization(SAM_ACCOUNT *pass) 
 {
-       const char *lm_pwd, *nt_pwd;
+       const uint8 *lm_pwd, *nt_pwd;
        
        /* only reset a password if the last set time has been 
           explicitly been set to zero.  A default last set time 
@@ -233,7 +233,7 @@ static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sa
 static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
 {
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       const char *lm_pw, *nt_pw;
+       const uint8 *lm_pw, *nt_pw;
        uint16 acb_flags;
 
        if ((!context) || (!context->pdb_methods)) {
@@ -262,7 +262,7 @@ static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT
 static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
 {
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-       const char *lm_pw, *nt_pw;
+       const uint8 *lm_pw, *nt_pw;
        uint16 acb_flags;
 
        if (!context) {
@@ -549,24 +549,6 @@ static NTSTATUS context_delete_alias(struct pdb_context *context,
        return context->pdb_methods->delete_alias(context->pdb_methods, sid);
 }
 
-static NTSTATUS context_enum_aliases(struct pdb_context *context,
-                                    const DOM_SID *sid,
-                                    uint32 start_idx, uint32 max_entries,
-                                    uint32 *num_aliases,
-                                    struct acct_info **info)
-{
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
-       if ((!context) || (!context->pdb_methods)) {
-               DEBUG(0, ("invalid pdb_context specified!\n"));
-               return ret;
-       }
-
-       return context->pdb_methods->enum_aliases(context->pdb_methods,
-                                                 sid, start_idx, max_entries,
-                                                 num_aliases, info);
-}
-
 static NTSTATUS context_get_aliasinfo(struct pdb_context *context,
                                      const DOM_SID *sid,
                                      struct acct_info *info)
@@ -643,9 +625,12 @@ static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
 }
        
 static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
+                                              TALLOC_CTX *mem_ctx,
+                                              const DOM_SID *domain_sid,
                                               const DOM_SID *members,
                                               int num_members,
-                                              DOM_SID **aliases, int *num)
+                                              uint32 **alias_rids,
+                                              int *num_alias_rids)
 {
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 
@@ -655,8 +640,91 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
        }
 
        return context->pdb_methods->
-               enum_alias_memberships(context->pdb_methods, members,
-                                      num_members, aliases, num);
+               enum_alias_memberships(context->pdb_methods, mem_ctx,
+                                      domain_sid, members, num_members,
+                                      alias_rids, num_alias_rids);
+}
+
+static NTSTATUS context_lookup_rids(struct pdb_context *context,
+                                   TALLOC_CTX *mem_ctx,
+                                   const DOM_SID *domain_sid,
+                                   int num_rids,
+                                   uint32 *rids,
+                                   const char ***names,
+                                   uint32 **attrs)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return ret;
+       }
+
+       return context->pdb_methods->lookup_rids(context->pdb_methods,
+                                                mem_ctx, domain_sid, num_rids,
+                                                rids, names, attrs);
+}
+
+static BOOL context_search_users(struct pdb_context *context,
+                                struct pdb_search *search, uint16 acct_flags)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_users(context->pdb_methods,
+                                                 search, acct_flags);
+}
+
+static BOOL context_search_groups(struct pdb_context *context,
+                                 struct pdb_search *search)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_groups(context->pdb_methods,
+                                                  search);
+}
+
+static BOOL context_search_aliases(struct pdb_context *context,
+                                  struct pdb_search *search,
+                                  const DOM_SID *sid)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_aliases(context->pdb_methods,
+                                                   search, sid);
+}
+
+static BOOL context_search_next_entry(struct pdb_context *context,
+                                     struct pdb_search *search,
+                                     struct samr_displayentry *entry)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_next_entry(context->pdb_methods,
+                                                      search, entry);
+}
+
+static void context_search_end(struct pdb_context *context,
+                              struct pdb_search *search)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return;
+       }
+
+       context->pdb_methods->search_end(context->pdb_methods, search);
+       return;
 }
 
 /******************************************************************
@@ -781,13 +849,19 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_find_alias = context_find_alias;
        (*context)->pdb_create_alias = context_create_alias;
        (*context)->pdb_delete_alias = context_delete_alias;
-       (*context)->pdb_enum_aliases = context_enum_aliases;
        (*context)->pdb_get_aliasinfo = context_get_aliasinfo;
        (*context)->pdb_set_aliasinfo = context_set_aliasinfo;
        (*context)->pdb_add_aliasmem = context_add_aliasmem;
        (*context)->pdb_del_aliasmem = context_del_aliasmem;
        (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
        (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
+       (*context)->pdb_lookup_rids = context_lookup_rids;
+
+       (*context)->pdb_search_users = context_search_users;
+       (*context)->pdb_search_groups = context_search_groups;
+       (*context)->pdb_search_aliases = context_search_aliases;
+       (*context)->pdb_search_next_entry = context_search_next_entry;
+       (*context)->pdb_search_end = context_search_end;
 
        (*context)->free_fn = free_pdb_context;
 
@@ -1174,22 +1248,6 @@ BOOL pdb_delete_alias(const DOM_SID *sid)
                                                            
 }
 
-BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries,
-                     uint32 *num_aliases, struct acct_info **info)
-{
-       struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-       if (!pdb_context) {
-               return False;
-       }
-
-       return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid,
-                                                            start_idx,
-                                                            max_entries,
-                                                            num_aliases,
-                                                            info));
-}
-
 BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1252,8 +1310,9 @@ BOOL pdb_enum_aliasmem(const DOM_SID *alias,
                                                 members, num_members));
 }
 
-BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
-                               DOM_SID **aliases, int *num)
+BOOL pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
+                               const DOM_SID *members, int num_members,
+                               uint32 **alias_rids, int *num_alias_rids)
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
 
@@ -1262,9 +1321,28 @@ BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
        }
 
        return NT_STATUS_IS_OK(pdb_context->
-                              pdb_enum_alias_memberships(pdb_context, members,
-                                                         num_members,
-                                                         aliases, num));
+                              pdb_enum_alias_memberships(pdb_context, mem_ctx,
+                                                         domain_sid,
+                                                         members, num_members,
+                                                         alias_rids,
+                                                         num_alias_rids));
+}
+
+NTSTATUS pdb_lookup_rids(TALLOC_CTX *mem_ctx,
+                        const DOM_SID *domain_sid,
+                        int num_rids,
+                        uint32 *rids,
+                        const char ***names,
+                        uint32 **attrs)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       return pdb_context->pdb_lookup_rids(pdb_context, mem_ctx, domain_sid,
+                                           num_rids, rids, names, attrs);
 }
 
 /***************************************************************
@@ -1439,6 +1517,481 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
        return NT_STATUS_OK;
 }
 
+NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
+                                TALLOC_CTX *mem_ctx,
+                                const DOM_SID *domain_sid,
+                                int num_rids,
+                                uint32 *rids,
+                                const char ***names,
+                                uint32 **attrs)
+{
+       int i;
+       NTSTATUS result;
+       BOOL have_mapped = False;
+       BOOL have_unmapped = False;
+
+       (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
+       (*attrs) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_rids);
+
+       if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
+               return NT_STATUS_NO_MEMORY;
+
+       if (!sid_equal(domain_sid, get_global_sam_sid())) {
+               /* TODO: Sooner or later we need to look up BUILTIN rids as
+                * well. -- vl */
+               goto done;
+       }
+
+       for (i = 0; i < num_rids; i++) {
+               fstring tmpname;
+               fstring domname;
+               DOM_SID sid;
+               enum SID_NAME_USE type;
+
+               (*attrs)[i] = SID_NAME_UNKNOWN;
+
+               sid_copy(&sid, domain_sid);
+               sid_append_rid(&sid, rids[i]);
+
+               if (lookup_sid(&sid, domname, tmpname, &type)) {
+                       (*attrs)[i] = (uint32)type;
+                       (*names)[i] = talloc_strdup(mem_ctx, tmpname);
+                       if ((*names)[i] == NULL)
+                               return NT_STATUS_NO_MEMORY;
+                       DEBUG(5,("lookup_rids: %s:%d\n", (*names)[i],
+                                (*attrs)[i]));
+                       have_mapped = True;
+               } else {
+                       have_unmapped = True;
+               }
+       }
+
+ done:
+
+       result = NT_STATUS_NONE_MAPPED;
+
+       if (have_mapped)
+               result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
+
+       return result;
+}
+
+static struct pdb_search *pdb_search_init(enum pdb_search_type type)
+{
+       TALLOC_CTX *mem_ctx;
+       struct pdb_search *result;
+
+       mem_ctx = talloc_init("pdb_search");
+       if (mem_ctx == NULL) {
+               DEBUG(0, ("talloc_init failed\n"));
+               return NULL;
+       }
+
+       result = TALLOC_P(mem_ctx, struct pdb_search);
+       if (result == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return NULL;
+       }
+
+       result->mem_ctx = mem_ctx;
+       result->type = type;
+       result->cache = NULL;
+       result->num_entries = 0;
+       result->cache_size = 0;
+       result->search_ended = False;
+
+       return result;
+}
+
+static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
+                             uint16 acct_flags,
+                             const char *account_name,
+                             const char *fullname,
+                             const char *description,
+                             struct samr_displayentry *entry)
+{
+       entry->rid = rid;
+       entry->acct_flags = acct_flags;
+
+       if (account_name != NULL)
+               entry->account_name = talloc_strdup(mem_ctx, account_name);
+       else
+               entry->account_name = "";
+
+       if (fullname != NULL)
+               entry->fullname = talloc_strdup(mem_ctx, fullname);
+       else
+               entry->fullname = "";
+
+       if (description != NULL)
+               entry->description = talloc_strdup(mem_ctx, description);
+       else
+               entry->description = "";
+}
+
+static BOOL user_search_in_progress = False;
+struct user_search {
+       uint16 acct_flags;
+};
+
+static BOOL pdb_default_search_users(struct pdb_methods *methods,
+                                    struct pdb_search *search,
+                                    uint16 acct_flags)
+{
+       struct user_search *state;
+
+       if (user_search_in_progress) {
+               DEBUG(1, ("user search in progress\n"));
+               return False;
+       }
+
+       if (!pdb_setsampwent(False, acct_flags)) {
+               DEBUG(5, ("Could not start search\n"));
+               return False;
+       }
+
+       user_search_in_progress = True;
+
+       state = TALLOC_P(search->mem_ctx, struct user_search);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       state->acct_flags = acct_flags;
+
+       search->private = state;
+       return True;
+}
+
+static BOOL pdb_search_next_entry_users(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
+{
+       struct user_search *state = s->private;
+       SAM_ACCOUNT *user = NULL;
+       NTSTATUS status;
+
+ next:
+       status = pdb_init_sam(&user);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("Could not pdb_init_sam\n"));
+               return False;
+       }
+
+       if (!pdb_getsampwent(user)) {
+               pdb_free_sam(&user);
+               return False;
+       }
+
+       if ((state->acct_flags != 0) &&
+           ((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
+               pdb_free_sam(&user);
+               goto next;
+       }
+
+       fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
+                         pdb_get_acct_ctrl(user), pdb_get_username(user),
+                         pdb_get_fullname(user), pdb_get_acct_desc(user),
+                         entry);
+
+       pdb_free_sam(&user);
+       return True;
+}
+
+static void pdb_search_end_users(struct pdb_search *search)
+{
+       pdb_endsampwent();
+       user_search_in_progress = False;
+}
+
+struct group_search {
+       GROUP_MAP *groups;
+       int num_groups, current_group;
+};
+
+static BOOL pdb_default_search_groups(struct pdb_methods *methods,
+                                     struct pdb_search *search)
+{
+       struct group_search *state;
+
+       state = TALLOC_P(search->mem_ctx, struct group_search);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &state->groups,
+                                   &state->num_groups, True)) {
+               DEBUG(0, ("Could not enum groups\n"));
+               return False;
+       }
+
+       state->current_group = 0;
+       search->private = state;
+       return True;
+}
+
+static BOOL pdb_search_next_entry_group(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
+{
+       struct group_search *state = s->private;
+       uint32 rid;
+       GROUP_MAP *map = &state->groups[state->current_group];
+
+       if (state->current_group == state->num_groups)
+               return False;
+
+       sid_peek_rid(&map->sid, &rid);
+
+       fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+                         entry);
+
+       state->current_group += 1;
+       return True;
+}
+
+static void pdb_search_end_groups(struct pdb_search *search)
+{
+       struct group_search *state = search->private;
+       SAFE_FREE(state->groups);
+}
+
+struct alias_search {
+       GROUP_MAP *aliases;
+       int num_aliases, current_alias;
+};
+
+static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
+                                      struct pdb_search *search,
+                                      const DOM_SID *sid)
+{
+       struct alias_search *state;
+       enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+
+       if (sid_equal(sid, get_global_sam_sid()))
+               type = SID_NAME_ALIAS;
+
+       if (sid_equal(sid, &global_sid_Builtin))
+               type = SID_NAME_WKN_GRP;
+
+       if (type == SID_NAME_UNKNOWN) {
+               DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
+               return False;
+       }
+
+       state = TALLOC_P(search->mem_ctx, struct alias_search);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       if (!pdb_enum_group_mapping(type, &state->aliases,
+                                   &state->num_aliases, False)) {
+               DEBUG(0, ("Could not enum aliases\n"));
+               return False;
+       }
+
+       state->current_alias = 0;
+       search->private = state;
+       return True;
+}
+
+static BOOL pdb_search_next_entry_alias(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
+{
+       struct alias_search *state = s->private;
+       uint32 rid;
+       GROUP_MAP *map = &state->aliases[state->current_alias];
+
+       if (state->current_alias == state->num_aliases)
+               return False;
+
+       sid_peek_rid(&map->sid, &rid);
+
+       fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+                         entry);
+
+       state->current_alias += 1;
+       return True;
+}
+
+static void pdb_search_end_aliases(struct pdb_search *search)
+{
+       struct alias_search *state = search->private;
+       SAFE_FREE(state->aliases);
+}
+
+static BOOL pdb_default_search_next_entry(struct pdb_methods *pdb_methods,
+                                         struct pdb_search *search,
+                                         struct samr_displayentry *entry)
+{
+       BOOL result = False;
+       switch (search->type) {
+       case PDB_USER_SEARCH:
+               result = pdb_search_next_entry_users(search, entry);
+               break;
+       case PDB_GROUP_SEARCH:
+               result = pdb_search_next_entry_group(search, entry);
+               break;
+       case PDB_ALIAS_SEARCH:
+               result = pdb_search_next_entry_alias(search, entry);
+               break;
+       default:
+               DEBUG(0, ("unknown search type: %d\n", search->type));
+               break;
+       }
+       return result;
+}
+
+static BOOL pdb_search_next_entry(struct pdb_search *search,
+                                 struct samr_displayentry *entry)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (pdb_context == NULL) return False;
+
+       return pdb_context->pdb_search_next_entry(pdb_context, search, entry);
+}
+
+static void pdb_default_search_end(struct pdb_methods *pdb_methods,
+                                  struct pdb_search *search)
+{
+       switch (search->type) {
+       case PDB_USER_SEARCH:
+               pdb_search_end_users(search);
+               break;
+       case PDB_GROUP_SEARCH:
+               pdb_search_end_groups(search);
+               break;
+       case PDB_ALIAS_SEARCH:
+               pdb_search_end_aliases(search);
+               break;
+       default:
+               DEBUG(0, ("unknown search type: %d\n", search->type));
+               break;
+       }
+}
+
+static void pdb_search_end(struct pdb_search *search)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (pdb_context == NULL) return;
+
+       pdb_context->pdb_search_end(pdb_context, search);
+}
+
+static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
+                                                    uint32 idx)
+{
+       if (idx < search->num_entries)
+               return &search->cache[idx];
+
+       if (search->search_ended)
+               return NULL;
+
+       while (idx >= search->num_entries) {
+               struct samr_displayentry entry;
+
+               if (!pdb_search_next_entry(search, &entry)) {
+                       pdb_search_end(search);
+                       search->search_ended = True;
+                       break;
+               }
+
+               ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
+                                  entry, &search->cache, &search->num_entries,
+                                  &search->cache_size);
+       }
+
+       return (search->num_entries > idx) ? &search->cache[idx] : NULL;
+}
+
+struct pdb_search *pdb_search_users(uint16 acct_flags)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
+
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_USER_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_users(pdb_context, result, acct_flags)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
+       }
+       return result;
+}
+
+struct pdb_search *pdb_search_groups(void)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
+
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_GROUP_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_groups(pdb_context, result)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
+       }
+       return result;
+}
+
+struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
+
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_ALIAS_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_aliases(pdb_context, result, sid)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
+       }
+       return result;
+}
+
+uint32 pdb_search_entries(struct pdb_search *search,
+                         uint32 start_idx, uint32 max_entries,
+                         struct samr_displayentry **result)
+{
+       struct samr_displayentry *end_entry;
+       uint32 end_idx = start_idx+max_entries-1;
+
+       /* The first entry needs to be searched after the last. Otherwise the
+        * first entry might have moved due to a realloc during the search for
+        * the last entry. */
+
+       end_entry = pdb_search_getentry(search, end_idx);
+       *result = pdb_search_getentry(search, start_idx);
+
+       if (end_entry != NULL)
+               return max_entries;
+
+       if (start_idx >= search->num_entries)
+               return 0;
+
+       return search->num_entries - start_idx;
+}
+
+void pdb_search_destroy(struct pdb_search *search)
+{
+       if (search == NULL)
+               return;
+
+       if (!search->search_ended)
+               pdb_search_end(search);
+
+       talloc_destroy(search->mem_ctx);
+}
+
 NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 
 {
        *methods = TALLOC_P(mem_ctx, struct pdb_methods);
@@ -1471,13 +2024,18 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
        (*methods)->find_alias = pdb_default_find_alias;
        (*methods)->create_alias = pdb_default_create_alias;
        (*methods)->delete_alias = pdb_default_delete_alias;
-       (*methods)->enum_aliases = pdb_default_enum_aliases;
        (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
        (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
        (*methods)->add_aliasmem = pdb_default_add_aliasmem;
        (*methods)->del_aliasmem = pdb_default_del_aliasmem;
        (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
        (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
+       (*methods)->lookup_rids = pdb_default_lookup_rids;
+       (*methods)->search_users = pdb_default_search_users;
+       (*methods)->search_groups = pdb_default_search_groups;
+       (*methods)->search_aliases = pdb_default_search_aliases;
+       (*methods)->search_next_entry = pdb_default_search_next_entry;
+       (*methods)->search_end = pdb_default_search_end;
 
        return NT_STATUS_OK;
 }
index 3dab919cb4698fa2333e5ec7d4a3748ce49a584b..752eb878b190b10f690d88e1ec8f148f7b5c94a8 100644 (file)
@@ -462,7 +462,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
        uint8           hours[MAX_HOURS_LEN];
        pstring temp;
        LOGIN_CACHE     *cache_entry = NULL;
-       int pwHistLen;
+       uint32          pwHistLen;
        pstring         tmpstring;
 
        /*
@@ -694,8 +694,8 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
        if (ldap_state->is_nds_ldap) {
                char *user_dn;
-               size_t pwd_len;
-               uchar clear_text_pw[512];
+               int pwd_len;
+               char clear_text_pw[512];
 
                /* Make call to Novell eDirectory ldap extension to get clear text password.
                        NOTE: This will only work if we have an SSL connection to eDirectory. */
@@ -1086,14 +1086,15 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                }
 
                if (need_update(sampass, PDB_PWHISTORY)) {
-                       int pwHistLen = 0;
+                       uint32 pwHistLen = 0;
                        account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
                        if (pwHistLen == 0) {
                                /* Remove any password history from the LDAP store. */
                                memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
                                temp[64] = '\0';
                        } else {
-                               int i, currHistLen = 0;
+                               int i; 
+                               uint32 currHistLen = 0;
                                const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
                                if (pwhist != NULL) {
                                        /* We can only store (sizeof(pstring)-1)/64 password history entries. */
@@ -1122,7 +1123,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
        }
 
        if (need_update(sampass, PDB_HOURS)) {
-               const char *hours = pdb_get_hours(sampass);
+               const uint8 *hours = pdb_get_hours(sampass);
                if (hours) {
                        pdb_sethexhours(temp, hours);
                        smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
@@ -2207,6 +2208,39 @@ static void add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
        *num += 1;
 }
 
+static BOOL ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
+                                          LDAPMessage *entry,
+                                          const DOM_SID *domain_sid,
+                                          uint32 *rid)
+{
+       fstring str;
+       DOM_SID sid;
+
+       if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
+                                         str, sizeof(str)-1)) {
+               DEBUG(10, ("Could not find sambaSID attribute\n"));
+               return False;
+       }
+
+       if (!string_to_sid(&sid, str)) {
+               DEBUG(10, ("Could not convert string %s to sid\n", str));
+               return False;
+       }
+
+       if (sid_compare_domain(&sid, domain_sid) != 0) {
+               DEBUG(10, ("SID %s is not in expected domain %s\n",
+                          str, sid_string_static(domain_sid)));
+               return False;
+       }
+
+       if (!sid_peek_rid(&sid, rid)) {
+               DEBUG(10, ("Could not peek into RID\n"));
+               return False;
+       }
+
+       return True;
+}
+
 static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
                                           TALLOC_CTX *mem_ctx,
                                           const DOM_SID *group,
@@ -2253,26 +2287,16 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
             entry != NULL;
             entry = ldap_next_entry(conn->ldap_struct, entry))
        {
-               fstring str;
-               DOM_SID sid;
                uint32 rid;
 
-               if (!smbldap_get_single_attribute(conn->ldap_struct,
-                                                 entry, "sambaSID",
-                                                 str, sizeof(str)-1))
-                       continue;
-
-               if (!string_to_sid(&sid, str))
-                       goto done;
-
-               if (!sid_check_is_in_our_domain(&sid)) {
-                       DEBUG(1, ("Inconsistent SAM -- group member uid not "
-                                 "in our domain\n"));
+               if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
+                                                   entry,
+                                                   get_global_sam_sid(),
+                                                   &rid)) {
+                       DEBUG(2, ("Could not find sid from ldap entry\n"));
                        continue;
                }
 
-               sid_peek_rid(&sid, &rid);
-
                add_rid_to_array_unique(mem_ctx, rid, member_rids,
                                        num_members);
        }
@@ -2412,7 +2436,6 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
        LDAPMessage *entry;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        int num_sids, num_gids;
-       extern DOM_SID global_sid_NULL;
 
        if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
                return pdb_default_enum_group_memberships(methods, username,
@@ -2445,11 +2468,11 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
 
        /* We need to add the primary group as the first gid/sid */
 
-       add_gid_to_array_unique(primary_gid, gids, &num_gids);
+       add_gid_to_array_unique(NULL, primary_gid, gids, &num_gids);
 
        /* This sid will be replaced later */
 
-       add_sid_to_array_unique(&global_sid_NULL, sids, &num_sids);
+       add_sid_to_array_unique(NULL, &global_sid_NULL, sids, &num_sids);
 
        for (entry = ldap_first_entry(conn->ldap_struct, msg);
             entry != NULL;
@@ -2481,8 +2504,8 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
                if (gid == primary_gid) {
                        sid_copy(&(*sids)[0], &sid);
                } else {
-                       add_gid_to_array_unique(gid, gids, &num_gids);
-                       add_sid_to_array_unique(&sid, sids, &num_sids);
+                       add_gid_to_array_unique(NULL, gid, gids, &num_gids);
+                       add_sid_to_array_unique(NULL, &sid, sids, &num_sids);
                }
        }
 
@@ -3028,7 +3051,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
                if (!string_to_sid(&member, values[i]))
                        continue;
 
-               add_sid_to_array(&member, members, num_members);
+               add_sid_to_array(NULL, &member, members, num_members);
        }
 
        ldap_value_free(values);
@@ -3038,9 +3061,12 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
 }
 
 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
+                                         TALLOC_CTX *mem_ctx,
+                                         const DOM_SID *domain_sid,
                                          const DOM_SID *members,
                                          int num_members,
-                                         DOM_SID **aliases, int *num_aliases)
+                                         uint32 **alias_rids,
+                                         int *num_alias_rids)
 {
        struct ldapsam_privates *ldap_state =
                (struct ldapsam_privates *)methods->private_data;
@@ -3053,12 +3079,6 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        int i;
        int rc;
        char *filter;
-       TALLOC_CTX *mem_ctx;
-
-       mem_ctx = talloc_init("ldapsam_alias_memberships");
-
-       if (mem_ctx == NULL)
-               return NT_STATUS_NO_MEMORY;
 
        /* This query could be further optimized by adding a
           (&(sambaSID=<domain-sid>*)) so that only those aliases that are
@@ -3083,9 +3103,6 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        if (rc != LDAP_SUCCESS)
                return NT_STATUS_UNSUCCESSFUL;
 
-       *aliases = NULL;
-       *num_aliases = 0;
-
        ldap_struct = ldap_state->smbldap_state->ldap_struct;
 
        for (entry = ldap_first_entry(ldap_struct, result);
@@ -3094,6 +3111,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
        {
                fstring sid_str;
                DOM_SID sid;
+               uint32 rid;
 
                if (!smbldap_get_single_attribute(ldap_struct, entry,
                                                  LDAP_ATTRIBUTE_SID,
@@ -3104,13 +3122,671 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
                if (!string_to_sid(&sid, sid_str))
                        continue;
 
-               add_sid_to_array_unique(&sid, aliases, num_aliases);
+               if (!sid_peek_check_rid(domain_sid, &sid, &rid))
+                       continue;
+
+               add_rid_to_array_unique(mem_ctx, rid, alias_rids,
+                                       num_alias_rids);
        }
 
        ldap_msgfree(result);
        return NT_STATUS_OK;
 }
 
+static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
+                                   TALLOC_CTX *mem_ctx,
+                                   const DOM_SID *domain_sid,
+                                   int num_rids,
+                                   uint32 *rids,
+                                   const char ***names,
+                                   uint32 **attrs)
+{
+       struct ldapsam_privates *ldap_state =
+               (struct ldapsam_privates *)methods->private_data;
+       LDAP *ldap_struct = ldap_state->smbldap_state->ldap_struct;
+       LDAPMessage *msg = NULL;
+       LDAPMessage *entry;
+       char *allsids = NULL;
+       char *tmp;
+       int i, rc, num_mapped;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
+               return pdb_default_lookup_rids(methods, mem_ctx, domain_sid,
+                                              num_rids, rids, names, attrs);
+
+       if (!sid_equal(domain_sid, get_global_sam_sid())) {
+               /* TODO: Sooner or later we need to look up BUILTIN rids as
+                * well. -- vl */
+               goto done;
+       }
+
+       (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
+       (*attrs) = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
+
+       if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
+               return NT_STATUS_NO_MEMORY;
+
+       for (i=0; i<num_rids; i++)
+               (*attrs)[i] = SID_NAME_UNKNOWN;
+
+       allsids = strdup("");
+       if (allsids == NULL) return NT_STATUS_NO_MEMORY;
+
+       for (i=0; i<num_rids; i++) {
+               DOM_SID sid;
+               sid_copy(&sid, domain_sid);
+               sid_append_rid(&sid, rids[i]);
+               tmp = allsids;
+               asprintf(&allsids, "%s(sambaSid=%s)", allsids,
+                        sid_string_static(&sid));
+               if (allsids == NULL) return NT_STATUS_NO_MEMORY;
+               free(tmp);
+       }
+
+       /* First look for users */
+
+       {
+               char *filter;
+               const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
+
+               asprintf(&filter, ("(&(objectClass=sambaSamAccount)(|%s))"),
+                        allsids);
+               if (filter == NULL) return NT_STATUS_NO_MEMORY;
+
+               rc = smbldap_search(ldap_state->smbldap_state,
+                                   lp_ldap_user_suffix(),
+                                   LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
+                                   &msg);
+
+               SAFE_FREE(filter);
+       }
+
+       if (rc != LDAP_SUCCESS)
+               goto done;
+
+       num_mapped = 0;
+
+       for (entry = ldap_first_entry(ldap_struct, msg);
+            entry != NULL;
+            entry = ldap_next_entry(ldap_struct, entry))
+       {
+               uint32 rid;
+               int rid_index;
+               fstring str;
+
+               if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
+                                                   get_global_sam_sid(),
+                                                   &rid)) {
+                       DEBUG(2, ("Could not find sid from ldap entry\n"));
+                       continue;
+               }
+
+               if (!smbldap_get_single_attribute(ldap_struct, entry,
+                                                 "uid", str, sizeof(str)-1)) {
+                       DEBUG(2, ("Could not retrieve uid attribute\n"));
+                       continue;
+               }
+
+               for (rid_index = 0; rid_index < num_rids; rid_index++) {
+                       if (rid == rids[rid_index])
+                               break;
+               }
+
+               if (rid_index == num_rids) {
+                       DEBUG(2, ("Got a RID not asked for: %d\n", rid));
+                       continue;
+               }
+
+               (*attrs)[rid_index] = SID_NAME_USER;
+               (*names)[rid_index] = talloc_strdup(mem_ctx, str);
+               if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+
+               num_mapped += 1;
+       }
+
+       if (num_mapped == num_rids) {
+               /* No need to look for groups anymore -- we're done */
+               result = NT_STATUS_OK;
+               goto done;
+       }
+
+       /* Same game for groups */
+
+       {
+               char *filter;
+               const char *ldap_attrs[] = { "cn", "sambaSid", NULL };
+
+               asprintf(&filter, ("(&(objectClass=sambaGroupMapping)(|%s))"),
+                        allsids);
+               if (filter == NULL) return NT_STATUS_NO_MEMORY;
+
+               rc = smbldap_search(ldap_state->smbldap_state,
+                                   lp_ldap_group_suffix(),
+                                   LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
+                                   &msg);
+
+               SAFE_FREE(filter);
+       }
+
+       if (rc != LDAP_SUCCESS)
+               goto done;
+
+       for (entry = ldap_first_entry(ldap_struct, msg);
+            entry != NULL;
+            entry = ldap_next_entry(ldap_struct, entry))
+       {
+               uint32 rid;
+               int rid_index;
+               fstring str;
+
+               if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
+                                                   get_global_sam_sid(),
+                                                   &rid)) {
+                       DEBUG(2, ("Could not find sid from ldap entry\n"));
+                       continue;
+               }
+
+               if (!smbldap_get_single_attribute(ldap_struct, entry,
+                                                 "cn", str, sizeof(str)-1)) {
+                       DEBUG(2, ("Could not retrieve cn attribute\n"));
+                       continue;
+               }
+
+               for (rid_index = 0; rid_index < num_rids; rid_index++) {
+                       if (rid == rids[rid_index])
+                               break;
+               }
+
+               if (rid_index == num_rids) {
+                       DEBUG(2, ("Got a RID not asked for: %d\n", rid));
+                       continue;
+               }
+
+               (*attrs)[rid_index] = SID_NAME_DOM_GRP;
+               (*names)[rid_index] = talloc_strdup(mem_ctx, str);
+               if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+               num_mapped += 1;
+       }
+
+       result = NT_STATUS_NONE_MAPPED;
+
+       if (num_mapped > 0)
+               result = (num_mapped == num_rids) ?
+                       NT_STATUS_OK : STATUS_SOME_UNMAPPED;
+ done:
+       SAFE_FREE(allsids);
+
+       if (msg != NULL)
+               ldap_msgfree(msg);
+
+       return result;
+}
+
+char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
+{
+       char *filter = NULL;
+       char *escaped = NULL;
+       char *result = NULL;
+
+       asprintf(&filter, "(&%s(objectclass=sambaSamAccount))",
+                lp_ldap_filter());
+       if (filter == NULL) goto done;
+
+       escaped = escape_ldap_string_alloc(username);
+       if (escaped == NULL) goto done;
+
+       filter = realloc_string_sub(filter, "%u", username);
+       result = talloc_strdup(mem_ctx, filter);
+
+ done:
+       SAFE_FREE(filter);
+       SAFE_FREE(escaped);
+
+       return result;
+}
+
+const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
+{
+       int i, num = 0;
+       va_list ap;
+       const char **result;
+
+       va_start(ap, mem_ctx);
+       while (va_arg(ap, const char *) != NULL)
+               num += 1;
+       va_end(ap);
+
+       result = TALLOC_ARRAY(mem_ctx, const char *, num+1);
+
+       va_start(ap, mem_ctx);
+       for (i=0; i<num; i++)
+               result[i] = talloc_strdup(mem_ctx, va_arg(ap, const char*));
+       va_end(ap);
+
+       result[num] = NULL;
+       return result;
+}
+
+struct ldap_search_state {
+       struct smbldap_state *connection;
+
+       uint16 acct_flags;
+
+       const char *base;
+       int scope;
+       const char *filter;
+       const char **attrs;
+       int attrsonly;
+       void *pagedresults_cookie;
+
+       LDAPMessage *entries, *current_entry;
+       BOOL (*ldap2displayentry)(struct ldap_search_state *state,
+                                 TALLOC_CTX *mem_ctx,
+                                 LDAP *ld, LDAPMessage *entry,
+                                 struct samr_displayentry *result);
+};
+
+static BOOL ldapsam_search_firstpage(struct pdb_search *search)
+{
+       struct ldap_search_state *state = search->private;
+       LDAP *ld = state->connection->ldap_struct;
+       int rc = LDAP_OPERATIONS_ERROR;
+
+       state->entries = NULL;
+
+       if (state->connection->paged_results) {
+               rc = smbldap_search_paged(state->connection, state->base,
+                                         state->scope, state->filter,
+                                         state->attrs, state->attrsonly,
+                                         lp_ldap_page_size(), &state->entries,
+                                         &state->pagedresults_cookie);
+       }
+
+       if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
+
+               if (state->entries != NULL) {
+                       /* Left over from unsuccessful paged attempt */
+                       ldap_msgfree(state->entries);
+                       state->entries = NULL;
+               }
+
+               rc = smbldap_search(state->connection, state->base,
+                                   state->scope, state->filter, state->attrs,
+                                   state->attrsonly, &state->entries);
+
+               if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
+                       return False;
+
+               /* Ok, the server was lying. It told us it could do paged
+                * searches when it could not. */
+               state->connection->paged_results = False;
+       }
+
+       state->current_entry = ldap_first_entry(ld, state->entries);
+
+       if (state->current_entry == NULL) {
+               ldap_msgfree(state->entries);
+               state->entries = NULL;
+       }
+
+       return True;
+}
+
+static BOOL ldapsam_search_nextpage(struct pdb_search *search)
+{
+       struct ldap_search_state *state = search->private;
+       LDAP *ld = state->connection->ldap_struct;
+       int rc;
+
+       if (!state->connection->paged_results) {
+               /* There is no next page when there are no paged results */
+               return False;
+       }
+
+       rc = smbldap_search_paged(state->connection, state->base,
+                                 state->scope, state->filter, state->attrs,
+                                 state->attrsonly, lp_ldap_page_size(),
+                                 &state->entries,
+                                 &state->pagedresults_cookie);
+
+       if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
+               return False;
+
+       state->current_entry = ldap_first_entry(ld, state->entries);
+
+       if (state->current_entry == NULL) {
+               ldap_msgfree(state->entries);
+               state->entries = NULL;
+       }
+
+       return True;
+}
+
+static BOOL ldapsam_search_next_entry(struct pdb_methods *methods,
+                                     struct pdb_search *search,
+                                     struct samr_displayentry *entry)
+{
+       struct ldap_search_state *state = search->private;
+       LDAP *ld = state->connection->ldap_struct;
+       BOOL result;
+
+ retry:
+       if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
+               return False;
+
+       if ((state->entries == NULL) &&
+           !ldapsam_search_nextpage(search))
+                   return False;
+
+       result = state->ldap2displayentry(state, search->mem_ctx, ld,
+                                         state->current_entry, entry);
+
+       if (!result) {
+               char *dn;
+               dn = ldap_get_dn(ld, state->current_entry);
+               DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
+               if (dn != NULL) ldap_memfree(dn);
+       }
+
+       state->current_entry = ldap_next_entry(ld, state->current_entry);
+
+       if (state->current_entry == NULL) {
+               ldap_msgfree(state->entries);
+               state->entries = NULL;
+       }
+
+       if (!result) goto retry;
+
+       return True;
+}
+
+static void ldapsam_search_end(struct pdb_methods *methods,
+                              struct pdb_search *search)
+{
+       struct ldap_search_state *state = search->private;
+       int rc;
+
+       if (state->pagedresults_cookie == NULL)
+               return;
+
+       if (state->entries != NULL)
+               ldap_msgfree(state->entries);
+
+       state->entries = NULL;
+       state->current_entry = NULL;
+
+       if (!state->connection->paged_results)
+               return;
+
+       /* Tell the LDAP server we're not interested in the rest anymore. */
+
+       rc = smbldap_search_paged(state->connection, state->base, state->scope,
+                                 state->filter, state->attrs,
+                                 state->attrsonly, 0, &state->entries,
+                                 &state->pagedresults_cookie);
+
+       if (rc != LDAP_SUCCESS)
+               DEBUG(5, ("Could not end search properly\n"));
+
+       return;
+}
+
+static BOOL ldapuser2displayentry(struct ldap_search_state *state,
+                                 TALLOC_CTX *mem_ctx,
+                                 LDAP *ld, LDAPMessage *entry,
+                                 struct samr_displayentry *result)
+{
+       char **vals;
+       DOM_SID sid;
+       uint16 acct_flags;
+
+       vals = ldap_get_values(ld, entry, "sambaAcctFlags");
+       if ((vals == NULL) || (vals[0] == NULL)) {
+               DEBUG(5, ("\"sambaAcctFlags\" not found\n"));
+               return False;
+       }
+       acct_flags = pdb_decode_acct_ctrl(vals[0]);
+       ldap_value_free(vals);
+
+       if ((state->acct_flags != 0) &&
+           ((state->acct_flags & acct_flags) == 0))
+               return False;           
+
+       result->acct_flags = acct_flags;
+       result->account_name = "";
+       result->fullname = "";
+       result->description = "";
+
+       vals = ldap_get_values(ld, entry, "uid");
+       if ((vals == NULL) || (vals[0] == NULL)) {
+               DEBUG(5, ("\"uid\" not found\n"));
+               return False;
+       }
+       pull_utf8_talloc(mem_ctx,
+                        CONST_DISCARD(char **, &result->account_name),
+                        vals[0]);
+       ldap_value_free(vals);
+
+       vals = ldap_get_values(ld, entry, "displayName");
+       if ((vals == NULL) || (vals[0] == NULL))
+               DEBUG(8, ("\"displayName\" not found\n"));
+       else
+               pull_utf8_talloc(mem_ctx,
+                                CONST_DISCARD(char **, &result->fullname),
+                                vals[0]);
+       ldap_value_free(vals);
+
+       vals = ldap_get_values(ld, entry, "description");
+       if ((vals == NULL) || (vals[0] == NULL))
+               DEBUG(8, ("\"description\" not found\n"));
+       else
+               pull_utf8_talloc(mem_ctx,
+                                CONST_DISCARD(char **, &result->description),
+                                vals[0]);
+       ldap_value_free(vals);
+
+       if ((result->account_name == NULL) ||
+           (result->fullname == NULL) ||
+           (result->description == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+       
+       vals = ldap_get_values(ld, entry, "sambaSid");
+       if ((vals == NULL) || (vals[0] == NULL)) {
+               DEBUG(0, ("\"objectSid\" not found\n"));
+               return False;
+       }
+
+       if (!string_to_sid(&sid, vals[0])) {
+               DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
+               ldap_value_free(vals);
+               return False;
+       }
+       ldap_value_free(vals);
+
+       if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
+               DEBUG(0, ("%s is not our domain\n", vals[0]));
+               return False;
+       }
+
+       return True;
+}
+
+
+static BOOL ldapsam_search_users(struct pdb_methods *methods,
+                                struct pdb_search *search,
+                                uint16 acct_flags)
+{
+       struct ldapsam_privates *ldap_state = methods->private_data;
+       struct ldap_search_state *state;
+
+       state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       state->connection = ldap_state->smbldap_state;
+
+       if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
+               state->base = lp_ldap_user_suffix();
+       else if ((acct_flags != 0) &&
+                ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) != 0))
+               state->base = lp_ldap_machine_suffix();
+       else
+               state->base = lp_ldap_suffix();
+
+       state->acct_flags = acct_flags;
+       state->base = talloc_strdup(search->mem_ctx, state->base);
+       state->scope = LDAP_SCOPE_SUBTREE;
+       state->filter = get_ldap_filter(search->mem_ctx, "*");
+       state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
+                                   "displayName", "description",
+                                   "sambaAcctFlags", NULL);
+       state->attrsonly = 0;
+       state->pagedresults_cookie = NULL;
+       state->entries = NULL;
+       state->ldap2displayentry = ldapuser2displayentry;
+
+       if ((state->filter == NULL) || (state->attrs == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       search->private = state;
+
+       return ldapsam_search_firstpage(search);
+}
+
+static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
+                                  TALLOC_CTX *mem_ctx,
+                                  LDAP *ld, LDAPMessage *entry,
+                                  struct samr_displayentry *result)
+{
+       char **vals;
+       DOM_SID sid;
+
+       result->account_name = "";
+       result->fullname = "";
+       result->description = "";
+
+       vals = ldap_get_values(ld, entry, "cn");
+       if ((vals == NULL) || (vals[0] == NULL)) {
+               DEBUG(5, ("\"cn\" not found\n"));
+               return False;
+       }
+       pull_utf8_talloc(mem_ctx,
+                        CONST_DISCARD(char **, &result->account_name),
+                        vals[0]);
+       ldap_value_free(vals);
+
+       vals = ldap_get_values(ld, entry, "displayName");
+       if ((vals == NULL) || (vals[0] == NULL))
+               DEBUG(8, ("\"displayName\" not found\n"));
+       else
+               pull_utf8_talloc(mem_ctx,
+                                CONST_DISCARD(char **, &result->fullname),
+                                vals[0]);
+       ldap_value_free(vals);
+
+       vals = ldap_get_values(ld, entry, "description");
+       if ((vals == NULL) || (vals[0] == NULL))
+               DEBUG(8, ("\"description\" not found\n"));
+       else
+               pull_utf8_talloc(mem_ctx,
+                                CONST_DISCARD(char **, &result->description),
+                                vals[0]);
+       ldap_value_free(vals);
+
+       if ((result->account_name == NULL) ||
+           (result->fullname == NULL) ||
+           (result->description == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+       
+       vals = ldap_get_values(ld, entry, "sambaSid");
+       if ((vals == NULL) || (vals[0] == NULL)) {
+               DEBUG(0, ("\"objectSid\" not found\n"));
+               return False;
+       }
+
+       if (!string_to_sid(&sid, vals[0])) {
+               DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
+               return False;
+       }
+
+       if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
+               DEBUG(0, ("%s is not our domain\n", vals[0]));
+               return False;
+       }
+       ldap_value_free(vals);
+
+       return True;
+}
+
+static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
+                                    struct pdb_search *search,
+                                    enum SID_NAME_USE type)
+{
+       struct ldapsam_privates *ldap_state = methods->private_data;
+       struct ldap_search_state *state;
+
+       state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
+       if (state == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       state->connection = ldap_state->smbldap_state;
+
+       state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
+       state->connection = ldap_state->smbldap_state;
+       state->scope = LDAP_SCOPE_SUBTREE;
+       state->filter = talloc_asprintf(search->mem_ctx,
+                                       "(&(objectclass=sambaGroupMapping)"
+                                       "(sambaGroupType=%d))", type);
+       state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
+                                   "displayName", "description", NULL);
+       state->attrsonly = 0;
+       state->pagedresults_cookie = NULL;
+       state->entries = NULL;
+       state->ldap2displayentry = ldapgroup2displayentry;
+
+       if ((state->filter == NULL) || (state->attrs == NULL)) {
+               DEBUG(0, ("talloc failed\n"));
+               return False;
+       }
+
+       search->private = state;
+
+       return ldapsam_search_firstpage(search);
+}
+
+static BOOL ldapsam_search_groups(struct pdb_methods *methods,
+                                 struct pdb_search *search)
+{
+       return ldapsam_search_grouptype(methods, search, SID_NAME_DOM_GRP);
+}
+
+static BOOL ldapsam_search_aliases(struct pdb_methods *methods,
+                                  struct pdb_search *search,
+                                  const DOM_SID *sid)
+{
+       if (sid_check_is_domain(sid))
+               return ldapsam_search_grouptype(methods, search,
+                                               SID_NAME_ALIAS);
+
+       if (sid_check_is_builtin(sid))
+               return ldapsam_search_grouptype(methods, search,
+                                               SID_NAME_WKN_GRP);
+
+       DEBUG(5, ("Don't know SID %s\n", sid_string_static(sid)));
+       return False;
+}
+
 /**********************************************************************
  Housekeeping
  *********************************************************************/
@@ -3168,6 +3844,12 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
        (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
        (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
        (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
+       (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
+       (*pdb_method)->search_users = ldapsam_search_users;
+       (*pdb_method)->search_groups = ldapsam_search_groups;
+       (*pdb_method)->search_aliases = ldapsam_search_aliases;
+       (*pdb_method)->search_next_entry = ldapsam_search_next_entry;
+       (*pdb_method)->search_end = ldapsam_search_end;
 
        /* TODO: Setup private data and free */
 
index 6be63e4f9d6f7301697d9cf5b12d2c81744556dc..c7ff2f80b00e656026e70f755699bf5e1efdffcd 100644 (file)
@@ -84,13 +84,11 @@ BOOL secrets_init(void)
  */
 void *secrets_fetch(const char *key, size_t *size)
 {
-       TDB_DATA kbuf, dbuf;
+       TDB_DATA dbuf;
        secrets_init();
        if (!tdb)
                return NULL;
-       kbuf.dptr = (char *)key;
-       kbuf.dsize = strlen(key);
-       dbuf = tdb_fetch(tdb, kbuf);
+       dbuf = tdb_fetch(tdb, string_tdb_data(key));
        if (size)
                *size = dbuf.dsize;
        return dbuf.dptr;
@@ -100,15 +98,11 @@ void *secrets_fetch(const char *key, size_t *size)
  */
 BOOL secrets_store(const char *key, const void *data, size_t size)
 {
-       TDB_DATA kbuf, dbuf;
        secrets_init();
        if (!tdb)
                return False;
-       kbuf.dptr = (char *)key;
-       kbuf.dsize = strlen(key);
-       dbuf.dptr = (char *)data;
-       dbuf.dsize = size;
-       return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
+       return tdb_store(tdb, string_tdb_data(key), make_tdb_data(data, size),
+                        TDB_REPLACE) == 0;
 }
 
 
@@ -116,13 +110,10 @@ BOOL secrets_store(const char *key, const void *data, size_t size)
  */
 BOOL secrets_delete(const char *key)
 {
-       TDB_DATA kbuf;
        secrets_init();
        if (!tdb)
                return False;
-       kbuf.dptr = (char *)key;
-       kbuf.dsize = strlen(key);
-       return tdb_delete(tdb, kbuf) == 0;
+       return tdb_delete(tdb, string_tdb_data(key)) == 0;
 }
 
 BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
index 1fddfc7925534dcd754dc73ed246cb9839bd5ca8..a9e1921e0d01757a0964f29ffad3f1744a732d77 100644 (file)
@@ -32,17 +32,11 @@ typedef struct _known_sid_users {
 
 static struct sid_name_map_info
 {
-       DOM_SID *sid;
+       const DOM_SID *sid;
        const char *name;
        const known_sid_users *known_users;
 } sid_name_map[MAX_SID_NAMES];
 
-extern DOM_SID global_sid_Builtin;                             /* Local well-known domain */
-extern DOM_SID global_sid_World_Domain;                /* Everyone domain */
-extern DOM_SID global_sid_Creator_Owner_Domain;    /* Creator Owner domain */
-extern DOM_SID global_sid_NT_Authority;                /* NT Authority */
-
-
 static BOOL sid_name_map_initialized = False;
 /* static known_sid_users no_users[] = {{0, 0, NULL}}; */
 
@@ -99,8 +93,6 @@ static void init_sid_name_map (void)
        
        if (sid_name_map_initialized) return;
 
-       generate_wellknown_sids();
-
        if ((lp_security() == SEC_USER) && lp_domain_logons()) {
                sid_name_map[i].sid = get_global_sam_sid();
                /* This is not lp_workgroup() for good reason:
index ad911c3b05b05a506bfdeb077abd227f097777c8..40d815cead1dd7c14c63ed271076aa449e45858b 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "includes.h"
 
-extern DOM_SID global_sid_World;
+extern struct current_user current_user;
 
 static TDB_CONTEXT *tdb_forms; /* used for forms files */
 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
@@ -1494,7 +1494,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        DEBUG(5,("Creating first directory\n"));
        slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
        driver_unix_convert(new_dir, conn, NULL, &bad_path, &st);
-       mkdir_internal(conn, new_dir);
+       mkdir_internal(conn, new_dir, bad_path);
 
        /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
         * listed for this driver which has already been moved, skip it (note:
@@ -5115,7 +5115,6 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
        BOOL result;
        const char *pname;
        TALLOC_CTX *mem_ctx = NULL;
-       extern struct current_user current_user;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        
        /* If user is NULL then use the current_user structure */
index 7c5de468701ce217b44fca62421c908adfa241d1..25f4d9bd464165b1bfb1f4be36ceddd87cc5e919 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 /***************************************************************************
 open a print file and setup a fsp for it. This is a wrapper around
 print_job_start().
@@ -30,7 +32,6 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
 {
        int jobid;
        SMB_STRUCT_STAT sbuf;
-       extern struct current_user current_user;
        files_struct *fsp = file_new(conn);
        fstring name;
 
index 5483005e1bd9099473e9fc1b271231ef9a7b2652..572ecb373a8c75c9885cd1051b41dd320bee53e5 100644 (file)
@@ -45,7 +45,7 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
 
 struct print_queue_update_context {
        char* sharename;
-       enum printing_types printing_type;
+       int printing_type;
        char* lpqcommand;
 };
 
@@ -235,7 +235,7 @@ void printing_end(void)
  when asked for (and only when supported)
 ****************************************************************************/
 
-static struct printif *get_printer_fns_from_type( enum printing_types type )
+static struct printif *get_printer_fns_from_type( int type )
 {
        struct printif *printer_fns = &generic_printif;
 
@@ -907,7 +907,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
 
 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
 {
-       TDB_DATA data, key;
+       TDB_DATA data;
        int max_reported_jobs = lp_max_reported_jobs(pts->snum);
        print_queue_struct *queue = pts->queue;
        size_t len;
@@ -951,22 +951,19 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
                                queue[i].fs_file);
        }
 
-       key.dptr = "INFO/linear_queue_array";
-       key.dsize = strlen(key.dptr);
-       tdb_store(pdb->tdb, key, data, TDB_REPLACE);
+       tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
+                 TDB_REPLACE);
        SAFE_FREE(data.dptr);
        return;
 }
 
 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
 {
-       TDB_DATA data, key;
+       TDB_DATA data;
 
-       key.dptr = "INFO/jobs_changed";
-       key.dsize = strlen(key.dptr);
        ZERO_STRUCT(data);
 
-       data = tdb_fetch(pdb->tdb, key);
+       data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
        if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
                SAFE_FREE(data.dptr);
                ZERO_STRUCT(data);
@@ -1035,7 +1032,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
                snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
 
                if ( check_pending 
-                       && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time ) 
+                       && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time ) 
                        && msg_pending_time > 0
                        && msg_pending_time <= time_now 
                        && (time_now - msg_pending_time) < 60 ) 
@@ -1382,7 +1379,7 @@ static void print_queue_update(int snum, BOOL force)
        size_t len = 0;
        size_t newlen;
        struct tdb_print_db *pdb;
-       enum printing_types type;
+       int type;
        struct printif *current_printif;
 
        fstrcpy( sharename, lp_const_servicename(snum));
@@ -1736,10 +1733,10 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
        BOOL ret = False;
        BOOL gotlock = False;
 
-       key.dptr = "INFO/jobs_changed";
-       key.dsize = strlen(key.dptr);
        ZERO_STRUCT(data);
 
+       key = string_tdb_data("INFO/jobs_changed");
+
        if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
                goto out;
 
@@ -2057,7 +2054,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
 static int get_queue_status(const char* sharename, print_status_struct *status)
 {
        fstring keystr;
-       TDB_DATA data, key;
+       TDB_DATA data;
        struct tdb_print_db *pdb = get_print_db_byname(sharename);
        int len;
 
@@ -2066,10 +2063,8 @@ static int get_queue_status(const char* sharename, print_status_struct *status)
 
        if (status) {
                ZERO_STRUCTP(status);
-               slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
-               key.dptr = keystr;
-               key.dsize = strlen(keystr);
-               data = tdb_fetch(pdb->tdb, key);
+               fstr_sprintf(keystr, "STATUS/%s", sharename);
+               data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
                if (data.dptr) {
                        if (data.dsize == sizeof(print_status_struct))
                                /* this memcpy is ok since the status struct was 
@@ -2179,18 +2174,17 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char
 
 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
 {
-       TDB_DATA data, key;
+       TDB_DATA data;
        uint32 store_jobid;
 
-       key.dptr = "INFO/jobs_changed";
-       key.dsize = strlen(key.dptr);
        SIVAL(&store_jobid, 0, jobid);
        data.dptr = (char *)&store_jobid;
        data.dsize = 4;
 
        DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
 
-       return (tdb_append(pdb->tdb, key, data) == 0);
+       return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
+                          data) == 0);
 }
 
 /***************************************************************************
@@ -2429,7 +2423,7 @@ fail:
 
 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
 {
-       TDB_DATA data, key, cgdata;
+       TDB_DATA data, cgdata;
        print_queue_struct *queue = NULL;
        uint32 qcount = 0;
        uint32 extra_count = 0;
@@ -2449,20 +2443,15 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
 
        ZERO_STRUCT(data);
        ZERO_STRUCT(cgdata);
-       key.dptr = "INFO/linear_queue_array";
-       key.dsize = strlen(key.dptr);
 
        /* Get the stored queue data. */
-       data = tdb_fetch(pdb->tdb, key);
+       data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
        
        if (data.dptr && data.dsize >= sizeof(qcount))
                len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
                
        /* Get the changed jobs list. */
-       key.dptr = "INFO/jobs_changed";
-       key.dsize = strlen(key.dptr);
-
-       cgdata = tdb_fetch(pdb->tdb, key);
+       cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
        if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
                extra_count = cgdata.dsize/4;
 
index c3d59d4fb8c064c662e95797559685ba08048007..ad83e469b24a8b9acc6d0a0ed79c6de4e50cf599 100644 (file)
@@ -212,7 +212,7 @@ static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw)
        static char *kwlist[] = { "fnum", "offset", "size", NULL };
        int fnum, offset=0, size=0;
        ssize_t result;
-       size_t fsize;
+       SMB_OFF_T fsize;
        char *data;
        PyObject *ret;
 
index 5ac8329309046cdb27f4ebf3a2afbecaa7d46901..f93b7e1ffba74b8a4f03ea2be46c8992dd0034fc 100644 (file)
@@ -65,6 +65,13 @@ static BOOL init_registry_data( void )
                return False;
        regsubkey_ctr_destroy( &subkeys );
 
+#ifdef REG_TEST_CODE
+       pstrcpy( keyname, KEY_HKLM );
+       pstrcat( keyname, "/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" );
+       if ( !regdb_store_reg_keys( keyname, &subkeys ))
+               return False;
+#endif
+
        regsubkey_ctr_init( &subkeys );
        pstrcpy( keyname, KEY_HKLM );
        pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
diff --git a/source/registry/reg_eventlog.c b/source/registry/reg_eventlog.c
new file mode 100644 (file)
index 0000000..cc2ffb5
--- /dev/null
@@ -0,0 +1,302 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "includes.h"
+
+/**********************************************************************
+ handle enumeration of values AT KEY_EVENTLOG
+ *********************************************************************/
+static int eventlog_topkey_values( char *key, REGVAL_CTR *val )
+{
+    int                num_values = 0;
+    char               *keystr, *key2 = NULL;
+    char               *base, *new_path;
+    fstring            evtlogname; 
+    UNISTR2            data;
+    int             iDisplayNameId;
+    int             iMaxSize;
+    
+    /* 
+     *  TODO - callout to get these values...
+     */
+    
+    if ( key ) 
+    {
+       key2 = strdup( key );
+       keystr = key2;
+       reg_split_path( keystr, &base, &new_path );
+       
+       iDisplayNameId = 0x00000100;
+       iMaxSize=        0x00080000;
+       
+       fstrcpy( evtlogname, base );
+       DEBUG(10,("eventlog_topkey_values: subkey root=> [%s] subkey path=>[%s]\n", base,new_path));
+       
+       if ( !new_path ) 
+       {
+           iDisplayNameId = 0x01;
+           regval_ctr_addvalue( val, "ErrorControl",    REG_DWORD, (char*)&iDisplayNameId,       sizeof(int) ); 
+           
+           init_unistr2( &data, "EventLog", UNI_STR_TERMINATE);
+           regval_ctr_addvalue( val, "DisplayName",             REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+           
+           num_values = regval_ctr_numvals( val );     
+           
+           
+           num_values = 0;
+       }
+    }
+    
+    SAFE_FREE( key2 ); 
+    return num_values;
+}
+
+/**********************************************************************
+ handle enumeration of values below KEY_EVENTLOG\<Eventlog>
+ *********************************************************************/
+static int eventlog_subkey_values( char *key, REGVAL_CTR *val )
+{
+    int        num_values = 0;
+    char       *keystr, *key2 = NULL;
+    char       *base, *new_path;
+    fstring            evtlogname; 
+    UNISTR2            data;
+    int         iDisplayNameId;
+    int         iMaxSize;
+    int         iRetention;
+    
+    /* 
+     *  TODO - callout to get these values...
+     */
+    
+    if ( !key ) 
+       return num_values;
+    
+    key2 = SMB_STRDUP( key );
+    keystr = key2;
+    reg_split_path( keystr, &base, &new_path );
+    
+    iDisplayNameId = 0x00000100;
+    /* MaxSize is limited to 0xFFFF0000 (UINT_MAX - USHRT_MAX) as per MSDN documentation */
+    iMaxSize=        0xFFFF0000;
+    /* records in the samba log are not overwritten */
+    iRetention =     0xFFFFFFFF;
+    
+    fstrcpy( evtlogname, base );
+    DEBUG(10,("eventlog_subpath_values_printer: eventlogname [%s]\n", base));
+    DEBUG(10,("eventlog_subpath_values_printer: new_path [%s]\n", new_path));
+    if ( !new_path ) 
+    {
+#if 0
+       regval_ctr_addvalue( val, "DisplayNameId",    REG_DWORD, (char*)&iDisplayNameId,       sizeof(int) ); 
+       
+       init_unistr2( &data, "%SystemRoot%\\system32\\els.dll", UNI_STR_TERMINATE);
+       regval_ctr_addvalue( val, "DisplayNameFile",             REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+#endif
+       regval_ctr_addvalue( val, "MaxSize",          REG_DWORD, (char*)&iMaxSize, sizeof(int));
+       regval_ctr_addvalue( val, "Retention",  REG_DWORD, (char *)&iRetention, sizeof(int));
+#if 0
+       init_unistr2( &data, lp_logfile(), UNI_STR_TERMINATE);
+       regval_ctr_addvalue( val, "File",             REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+#endif
+       init_unistr2( &data, base, UNI_STR_TERMINATE);
+       regval_ctr_addvalue( val, "PrimaryModule",         REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+       
+       init_unistr2( &data, base, UNI_STR_TERMINATE);
+       regval_ctr_addvalue( val, "Sources",          REG_MULTI_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+       
+       num_values = regval_ctr_numvals( val ); 
+       
+    } 
+    else
+    {
+       iDisplayNameId = 0x07;
+       regval_ctr_addvalue( val, "CategoryCount",    REG_DWORD, (char*)&iDisplayNameId,       sizeof(int) ); 
+       
+       init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE);
+       regval_ctr_addvalue( val, "CategoryMessageFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+       
+       num_values = regval_ctr_numvals( val ); 
+       
+       num_values = 0;
+    }
+    
+    SAFE_FREE( key2 ); 
+    return num_values;
+}
+
+
+/**********************************************************************
+ It is safe to assume that every registry path passed into on of 
+ the exported functions here begins with KEY_EVENTLOG else
+ these functions would have never been called.  This is a small utility
+ function to strip the beginning of the path and make a copy that the 
+ caller can modify.  Note that the caller is responsible for releasing
+ the memory allocated here.
+ **********************************************************************/
+
+static char* trim_eventlog_reg_path( char *path )
+{
+       char *p;
+       uint16 key_len = strlen(KEY_EVENTLOG);
+       
+       /* 
+        * sanity check...this really should never be True.
+        * It is only here to prevent us from accessing outside
+        * the path buffer in the extreme case.
+        */
+       
+       if ( strlen(path) < key_len ) {
+               DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
+               DEBUG(0,("trim_reg_path: KEY_EVENTLOG => [%s]!\n", KEY_EVENTLOG));
+               return NULL;
+       }
+       
+       
+       p = path + strlen( KEY_EVENTLOG );
+       
+       if ( *p == '\\' )
+               p++;
+       
+       if ( *p )
+               return SMB_STRDUP(p);
+       else
+               return NULL;
+}
+/**********************************************************************
+ Enumerate registry subkey names given a registry path.  
+ Caller is responsible for freeing memory to **subkeys
+ *********************************************************************/
+int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
+{
+    char       *path;
+    BOOL               top_level = False;
+    int                num_subkeys = 0;
+    const char        **evtlog_list;
+    
+    path = trim_eventlog_reg_path( key );
+    DEBUG(10,("eventlog_subkey_info: entire key=>[%s] SUBkey=>[%s]\n", key,path));     
+    
+    /* check to see if we are dealing with the top level key */
+    num_subkeys = 0;
+    
+    if ( !path )
+       top_level = True;
+    
+    evtlog_list = lp_eventlog_list();
+    num_subkeys = 0;
+    
+    if ( top_level ) 
+    { 
+        /* todo - get the eventlog subkey values from the smb.conf file
+          for ( num_subkeys=0; num_subkeys<MAX_TOP_LEVEL_KEYS; num_subkeys++ )
+          regsubkey_ctr_addkey( subkey_ctr, top_level_keys[num_subkeys] ); */
+       DEBUG(10,("eventlog_subkey_info: Adding eventlog subkeys from globals\n"));     
+       /* TODO - make this  from the globals.szEventLogs list */
+       
+       while (*evtlog_list) 
+       {
+           DEBUG(10,("eventlog_subkey_info: Adding subkey =>[%s]\n",*evtlog_list));    
+           regsubkey_ctr_addkey( subkey_ctr, *evtlog_list);
+           evtlog_list++;
+           num_subkeys++;
+       }
+    }
+    else 
+    {
+       while (*evtlog_list && (0==num_subkeys) ) 
+       {
+           if (0 == StrCaseCmp(path,*evtlog_list)) 
+           {
+               DEBUG(10,("eventlog_subkey_info: Adding subkey [%s] for key =>[%s]\n",path,*evtlog_list));      
+               regsubkey_ctr_addkey( subkey_ctr, *evtlog_list);
+               num_subkeys = 1;
+           }
+           evtlog_list++;
+       }
+       
+       if (0==num_subkeys) 
+           DEBUG(10,("eventlog_subkey_info: No match on SUBkey=>[%s]\n", path));
+    }
+    
+    SAFE_FREE( path );
+    return num_subkeys;
+}
+
+/**********************************************************************
+ Enumerate registry values given a registry path.  
+ Caller is responsible for freeing memory 
+ *********************************************************************/
+
+int eventlog_value_info( char *key, REGVAL_CTR *val )
+{
+       char            *path;
+       BOOL            top_level = False;
+       int             num_values = 0;
+       
+       DEBUG(10,("eventlog_value_info: key=>[%s]\n", key));
+       
+       path = trim_eventlog_reg_path( key );
+       
+       /* check to see if we are dealing with the top level key */
+       
+       if ( !path )
+           top_level = True;
+       if ( top_level )
+           num_values = eventlog_topkey_values(path,val);
+       else 
+       {
+           DEBUG(10,("eventlog_value_info: SUBkey=>[%s]\n", path));
+           num_values = eventlog_subkey_values(path,val);
+       }
+       return num_values;
+}
+
+/**********************************************************************
+ Stub function which always returns failure since we don't want
+ people storing eventlog information directly via registry calls
+ (for now at least)
+ *********************************************************************/
+BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
+{
+       return False;
+}
+
+/**********************************************************************
+ Stub function which always returns failure since we don't want
+ people storing eventlog information directly via registry calls
+ (for now at least)
+ *********************************************************************/
+BOOL eventlog_store_value( char *key, REGVAL_CTR *val )
+{
+       return False;
+}
+
+/* 
+ * Table of function pointers for accessing eventlog data
+ */
+REGISTRY_OPS eventlog_ops = {
+       eventlog_subkey_info,
+       eventlog_value_info,
+       eventlog_store_subkey,
+       eventlog_store_value
+};
index 1f8c936290135f473b988c1db5ffbb15f8d338f1..9f8747ef378487913c65add261813c1c10173714 100644 (file)
 #define DBGC_CLASS DBGC_RPC_SRV
 
 extern REGISTRY_OPS printing_ops;
+extern REGISTRY_OPS eventlog_ops;
 extern REGISTRY_OPS regdb_ops;         /* these are the default */
 
 /* array of REGISTRY_HOOK's which are read into a tree for easy access */
 
-
 REGISTRY_HOOK reg_hooks[] = {
   { KEY_PRINTING,   &printing_ops },
+  { KEY_EVENTLOG,   &eventlog_ops }, 
   { NULL, NULL }
 };
 
@@ -124,6 +125,8 @@ BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index
        *subkey = NULL;
        
        /* simple caching for performance; very basic heuristic */
+
+       DEBUG(8,("fetch_reg_keys_specific: Looking for key [%d] of  [%s]\n", key_index, key->name));
        
        if ( !ctr_init ) {
                DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
index 45b7509d45144e343377b1edb5fb308630f440ff..f404b5144a6b13a37224438abd666aa105db7b6a 100644 (file)
@@ -24,6 +24,7 @@
 */
 
 #include "includes.h"
+#include "rpc_client.h"
 
 /** @defgroup lsa LSA - Local Security Architecture
  *  @ingroup rpc_client
@@ -636,89 +637,68 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                 char ***domain_names, DOM_SID **domain_sids)
 {
        prs_struct qbuf, rbuf;
-       LSA_Q_ENUM_TRUST_DOM q;
-       LSA_R_ENUM_TRUST_DOM r;
-       NTSTATUS result;
+       LSA_Q_ENUM_TRUST_DOM in;
+       LSA_R_ENUM_TRUST_DOM out;
        int i;
+       fstring tmp;
 
-       ZERO_STRUCT(q);
-       ZERO_STRUCT(r);
-
-       /* Initialise parse structures */
-
-       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
-       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
 
-       /* Marshall data and send request */
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
 
        /* 64k is enough for about 2000 trusted domains */
-        init_q_enum_trust_dom(&q, pol, *enum_ctx, 0x10000);
-
-       if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) ||
-           !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
-               result = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       /* Unmarshall response */
-
-       if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) {
-               result = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
+       
+        init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
 
-       result = r.status;
+       CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM, 
+                   in, out, 
+                   qbuf, rbuf,
+                   lsa_io_q_enum_trust_dom,
+                   lsa_io_r_enum_trust_dom, 
+                   NT_STATUS_UNSUCCESSFUL );
 
-       if (!NT_STATUS_IS_OK(result) &&
-           !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
-           !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
 
-               /* An actual error ocured */
+       /* check for an actual error */
 
-               goto done;
+       if ( !NT_STATUS_IS_OK(out.status) 
+               && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES) 
+               && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
+       {
+               return out.status;
        }
-
+               
        /* Return output parameters */
 
-       if (r.num_domains) {
+       *num_domains  = out.count;
+       *enum_ctx     = out.enum_context;
+       
+       if ( out.count ) {
 
                /* Allocate memory for trusted domain names and sids */
 
-               *domain_names = TALLOC_ARRAY(mem_ctx, char *, r.num_domains);
-
-               if (!*domain_names) {
+               if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
                        DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
-                       result = NT_STATUS_NO_MEMORY;
-                       goto done;
+                       return NT_STATUS_NO_MEMORY;
                }
 
-               *domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.num_domains);
-               if (!domain_sids) {
+               if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
                        DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
-                       result = NT_STATUS_NO_MEMORY;
-                       goto done;
+                       return NT_STATUS_NO_MEMORY;
                }
 
                /* Copy across names and sids */
 
-               for (i = 0; i < r.num_domains; i++) {
-                       fstring tmp;
+               for (i = 0; i < out.count; i++) {
 
-                       unistr2_to_ascii(tmp, &r.uni_domain_name[i]
-                                        sizeof(tmp) - 1);
+                       rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer
+                               sizeof(tmp), out.domlist->domains[i].name.length, 0);
                        (*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
-                       sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid);
+
+                       sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
                }
        }
 
-       *num_domains = r.num_domains;
-       *enum_ctx = r.enum_context;
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
-       return result;
+       return out.status;
 }
 
 
@@ -1260,12 +1240,16 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        }
 
        
-       privileges = TALLOC_ARRAY(mem_ctx, fstring, *count);
-       names = TALLOC_ARRAY(mem_ctx, char *, *count);
+       privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
+       names      = TALLOC_ARRAY( mem_ctx, char *, *count );
+
        for ( i=0; i<*count; i++ ) {
-               /* ensure NULL termination ... what a hack */
-               pull_ucs2(NULL, privileges[i], r.rights.strings[i].string.buffer, 
-                       sizeof(fstring), r.rights.strings[i].string.uni_str_len*2 , 0);
+               UNISTR4 *uni_string = &r.rights->strings[i];
+
+               if ( !uni_string->string )
+                       continue;
+
+               rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
                        
                /* now copy to the return array */
                names[i] = talloc_strdup( mem_ctx, privileges[i] );
@@ -1284,7 +1268,8 @@ done:
 
 NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                    POLICY_HND *pol, DOM_SID sid,
-                                   uint32 count, const char **privs_name)
+                                   
+uint32 count, const char **privs_name)
 {
        prs_struct qbuf, rbuf;
        LSA_Q_ADD_ACCT_RIGHTS q;
index 25f56085bac3ba2bee3dbd43963f0f99c6c419d2..0d7d194850c91608fcfd51d4cceebc82ade6617c 100644 (file)
@@ -2,11 +2,12 @@
    Unix SMB/CIFS implementation.
    RPC Pipe client
  
-   Copyright (C) Andrew Tridgell              1992-1998,
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
-   Copyright (C) Paul Ashton                  1997-1998.
+   Copyright (C) Andrew Tridgell              1992-2000,
+   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+   Copyright (C) Paul Ashton                  1997-2000.
    Copyright (C) Jeremy Allison                    1999.
    Copyright (C) Simo Sorce                        2001
+   Copyright (C) Jeremy Cooper                     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
 
 /* Shutdown a server */
 
+/* internal connect to a registry hive root (open a registry policy) */
+
+static WERROR cli_reg_open_hive_int(struct cli_state *cli,
+                                      TALLOC_CTX *mem_ctx, uint16 op_code,
+                                      const char *op_name,
+                                      uint32 access_mask, POLICY_HND *hnd)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_OPEN_HIVE q_o;
+       REG_R_OPEN_HIVE r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       ZERO_STRUCT(q_o);
+       ZERO_STRUCT(r_o);
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       init_reg_q_open_hive(&q_o, access_mask);
+
+       /* Marshall the query parameters */
+       if (!reg_io_q_open_hive("", &q_o, &qbuf, 0))
+               goto done;
+
+       /* Send the request, receive the response */
+       if (!rpc_api_pipe_req(cli, PI_WINREG, op_code, &qbuf, &rbuf))
+               goto done;
+
+       /* Unmarshall the response */
+       if (!reg_io_r_open_hive("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result))
+               *hnd = r_o.pol;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+
 WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
                           const char *msg, uint32 timeout, BOOL do_reboot,
                          BOOL force)
@@ -90,7 +136,7 @@ WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
            !rpc_api_pipe_req(cli, PI_WINREG, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
                goto done;
        
-               /* Unmarshall response */
+       /* Unmarshall response */
        
        if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0))
                result = r_s.status;
@@ -101,3 +147,670 @@ done:
 
        return result;
 }
+
+/* connect to a registry hive root (open a registry policy) */
+
+WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                         uint32 reg_type, uint32 access_mask,
+                         POLICY_HND *reg_hnd)
+{      uint16 op_code;
+       const char *op_name;
+
+       ZERO_STRUCTP(reg_hnd);
+
+       switch (reg_type)
+       {
+       case HKEY_CLASSES_ROOT:
+               op_code = REG_OPEN_HKCR;
+               op_name = "REG_OPEN_HKCR";
+               break;
+       case HKEY_LOCAL_MACHINE:
+               op_code = REG_OPEN_HKLM;
+               op_name = "REG_OPEN_HKLM";
+               break;
+       case HKEY_USERS:
+               op_code = REG_OPEN_HKU;
+               op_name = "REG_OPEN_HKU";
+               break;
+       case HKEY_PERFORMANCE_DATA:
+               op_code = REG_OPEN_HKPD;
+               op_name = "REG_OPEN_HKPD";
+               break;
+       default:
+               return WERR_INVALID_PARAM;
+       }
+
+       return cli_reg_open_hive_int(cli, mem_ctx, op_code, op_name,
+                                     access_mask, reg_hnd);
+}
+
+/****************************************************************************
+do a REG Unknown 0xB command.  sent after a create key or create value.
+this might be some sort of "sync" or "refresh" command, sent after
+modification of the registry...
+****************************************************************************/
+WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                           POLICY_HND *hnd)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_FLUSH_KEY q_o;
+       REG_R_FLUSH_KEY r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_flush_key(&q_o, hnd);
+
+       if (!reg_io_q_flush_key("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_FLUSH_KEY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (reg_io_r_flush_key("", &r_o, &rbuf, 0))
+               result = r_o.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Query Key
+****************************************************************************/
+WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                           POLICY_HND *hnd,
+                           char *key_class, uint32 *class_len,
+                           uint32 *num_subkeys, uint32 *max_subkeylen,
+                           uint32 *max_classlen, uint32 *num_values,
+                           uint32 *max_valnamelen, uint32 *max_valbufsize,
+                           uint32 *sec_desc, NTTIME *mod_time)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_QUERY_KEY q_o;
+       REG_R_QUERY_KEY r_o;
+       uint32 saved_class_len = *class_len;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_query_key( &q_o, hnd, key_class );
+
+       if (!reg_io_q_query_key("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_QUERY_KEY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_query_key("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER)) {
+               *class_len = r_o.class.string->uni_max_len;
+               goto done;
+       } else if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       *class_len      = r_o.class.string->uni_max_len;
+       unistr2_to_ascii(key_class, r_o.class.string, saved_class_len-1);
+       *num_subkeys    = r_o.num_subkeys   ;
+       *max_subkeylen  = r_o.max_subkeylen ;
+       *num_values     = r_o.num_values    ;
+       *max_valnamelen = r_o.max_valnamelen;
+       *max_valbufsize = r_o.max_valbufsize;
+       *sec_desc       = r_o.sec_desc      ;
+       *mod_time       = r_o.mod_time      ;
+       /* Maybe: *max_classlen = r_o.reserved; */
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Unknown 1A
+****************************************************************************/
+WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, uint32 *unk)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_GETVERSION q_o;
+       REG_R_GETVERSION r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_getversion(&q_o, hnd);
+
+       if (!reg_io_q_getversion("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_GETVERSION, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_getversion("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result))
+               if (unk != NULL)
+                       *unk = r_o.unknown;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Query Info
+****************************************************************************/
+WERROR cli_reg_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                           POLICY_HND *hnd, const char *val_name,
+                           uint32 *type, REGVAL_BUFFER *buffer)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_INFO q_o;
+       REG_R_INFO r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_info(&q_o, hnd, val_name, buffer);
+
+       if (!reg_io_q_info("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_INFO, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_info("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result)) {
+               *type = *r_o.type;
+               *buffer = *r_o.value;
+       }
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Set Key Security 
+****************************************************************************/
+WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                             POLICY_HND *hnd, uint32 sec_info,
+                             size_t secdesc_size, SEC_DESC *sec_desc)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_SET_KEY_SEC q_o;
+       REG_R_SET_KEY_SEC r_o;
+       SEC_DESC_BUF *sec_desc_buf;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       /*
+        * Flatten the security descriptor.
+        */
+       sec_desc_buf = make_sec_desc_buf(mem_ctx, secdesc_size, sec_desc);
+       if (sec_desc_buf == NULL)
+               goto done;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_desc_buf);
+
+       if (!reg_io_q_set_key_sec("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_KEY_SEC, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (reg_io_r_set_key_sec("", &r_o, &rbuf, 0))
+               result = r_o.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+
+/****************************************************************************
+do a REG Query Key Security 
+****************************************************************************/
+WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                             POLICY_HND *hnd, uint32 sec_info,
+                             uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_GET_KEY_SEC q_o;
+       REG_R_GET_KEY_SEC r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf);
+
+       if (!reg_io_q_get_key_sec("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_GET_KEY_SEC, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       r_o.data = sec_buf;
+
+       if (*sec_buf_size != 0)
+       {
+               sec_buf->sec = (SEC_DESC*)talloc(mem_ctx, *sec_buf_size);
+       }
+
+       if (!reg_io_r_get_key_sec("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result))
+               (*sec_buf_size) = r_o.data->len;
+       else if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER)) 
+       {
+               /*
+                * get the maximum buffer size: it was too small
+                */
+               (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+       }
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Delete Value
+****************************************************************************/
+WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, char *val_name)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_DELETE_VALUE q_o;
+       REG_R_DELETE_VALUE r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_delete_val(&q_o, hnd, val_name);
+
+       if (!reg_io_q_delete_val("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_VALUE, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (reg_io_r_delete_val("", &r_o, &rbuf, 0))
+               result = r_o.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Delete Key
+****************************************************************************/
+WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, char *key_name)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_DELETE_KEY q_o;
+       REG_R_DELETE_KEY r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_delete_key(&q_o, hnd, key_name);
+
+       if (!reg_io_q_delete_key("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_KEY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (reg_io_r_delete_key("", &r_o, &rbuf, 0))
+               result = r_o.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Create Key
+****************************************************************************/
+WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, char *key_name, char *key_class,
+                            uint32 access_desired, POLICY_HND *key)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_CREATE_KEY q_o;
+       REG_R_CREATE_KEY r_o;
+       SEC_DESC *sec;
+       SEC_DESC_BUF *sec_buf;
+       size_t sec_len;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       ZERO_STRUCT(q_o);
+
+       if ((sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE,
+                                NULL, NULL, NULL, NULL, &sec_len)) == NULL)
+               goto done;
+
+       if ((sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) == NULL)
+               goto done;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_create_key(&q_o, hnd, key_name, key_class, access_desired, sec_buf);
+
+       if (!reg_io_q_create_key("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_CREATE_KEY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_create_key("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result))
+               *key = r_o.key_pol;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Enum Key
+****************************************************************************/
+WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                          POLICY_HND *hnd, int key_index, fstring key_name,
+                          uint32 *unk_1, uint32 *unk_2, time_t *mod_time)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_ENUM_KEY q_o;
+       REG_R_ENUM_KEY r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_enum_key(&q_o, hnd, key_index);
+
+       if (!reg_io_q_enum_key("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_KEY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_enum_key("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result)) {
+               (*unk_1) = r_o.unknown_1;
+               (*unk_2) = r_o.unknown_2;
+               unistr3_to_ascii(key_name, &r_o.key_name,
+                               sizeof(fstring)-1);
+               (*mod_time) = nt_time_to_unix(&r_o.time);
+       }
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Create Value
+****************************************************************************/
+WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, char *val_name, uint32 type,
+                            RPC_DATA_BLOB *data)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_SET_VALUE q_o;
+       REG_R_SET_VALUE r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_set_val(&q_o, hnd, val_name, type, data);
+
+       if (!reg_io_q_set_val("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_VALUE, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshal response */
+
+       if (reg_io_r_set_val("", &r_o, &rbuf, 0))
+               result = r_o.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Enum Value
+****************************************************************************/
+WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                          POLICY_HND *hnd, int val_index, int max_valnamelen,
+                          int max_valbufsize, fstring val_name,
+                          uint32 *val_type, REGVAL_BUFFER *value)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_ENUM_VALUE q_o;
+       REG_R_ENUM_VALUE r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_enum_val(&q_o, hnd, val_index, val_name, max_valbufsize);
+
+       if (!reg_io_q_enum_val("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_VALUE, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarshall response */
+
+       if (!reg_io_r_enum_val("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result) ||
+           NT_STATUS_EQUAL(result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+               (*val_type) = *r_o.type;
+               unistr2_to_ascii(val_name, r_o.name.string, sizeof(fstring)-1);
+               *value = *r_o.value;
+       }
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Open Key
+****************************************************************************/
+WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *hnd, char *key_name,
+                            uint32 access_desired, POLICY_HND *key_hnd)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_OPEN_ENTRY q_o;
+       REG_R_OPEN_ENTRY r_o;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_open_entry(&q_o, hnd, key_name, access_desired);
+
+       /* turn parameters into data stream */
+       if (!reg_io_q_open_entry("", &q_o, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_OPEN_ENTRY, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_o);
+
+       /* Unmarsall response */
+
+       if (!reg_io_r_open_entry("", &r_o, &rbuf, 0))
+               goto done;
+
+       result = r_o.status;
+       if (NT_STATUS_IS_OK(result))
+               *key_hnd = r_o.pol;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+/****************************************************************************
+do a REG Close
+****************************************************************************/
+WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                       POLICY_HND *hnd)
+{
+       prs_struct rbuf;
+       prs_struct qbuf; 
+       REG_Q_CLOSE q_c;
+       REG_R_CLOSE r_c;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_reg_q_close(&q_c, hnd);
+
+       if (!reg_io_q_close("", &q_c, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_WINREG, REG_CLOSE, &qbuf, &rbuf))
+               goto done;
+
+       ZERO_STRUCT(r_c);
+
+       /* Unmarshall response */
+
+       if (reg_io_r_close("", &r_c, &rbuf, 0))
+               result = r_c.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return result;
+}
+
+
index 9ad0510d1db58973dc18a633bc5aac227c5f0f4b..c342f255a9fec0e829f6445adbdc29e73c8e16a4 100644 (file)
@@ -36,9 +36,10 @@ NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
        prs_struct rbuf; 
        SHUTDOWN_Q_INIT q_s;
        SHUTDOWN_R_INIT r_s;
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       WERROR result = WERR_GENERAL_FAILURE;
 
-       if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
+       if (msg == NULL) 
+               return NT_STATUS_INVALID_PARAMETER;
 
        ZERO_STRUCT (q_s);
        ZERO_STRUCT (r_s);
@@ -63,7 +64,48 @@ done:
        prs_mem_free(&rbuf);
        prs_mem_free(&qbuf);
 
-       return result;
+       return werror_to_ntstatus(result);
+}
+
+/* Shutdown a server */
+
+NTSTATUS cli_shutdown_init_ex(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+                          const char *msg, uint32 timeout, BOOL do_reboot,
+                          BOOL force, uint32 reason)
+{
+       prs_struct qbuf;
+       prs_struct rbuf; 
+       SHUTDOWN_Q_INIT_EX q_s;
+       SHUTDOWN_R_INIT_EX r_s;
+       WERROR result = WERR_GENERAL_FAILURE;
+
+       if (msg == NULL) 
+               return NT_STATUS_INVALID_PARAMETER;
+
+       ZERO_STRUCT (q_s);
+       ZERO_STRUCT (r_s);
+
+       prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_shutdown_q_init_ex(&q_s, msg, timeout, do_reboot, force, reason);
+
+       if (!shutdown_io_q_init_ex("", &q_s, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_INIT_EX, &qbuf, &rbuf))
+               goto done;
+       
+       /* Unmarshall response */
+       
+       if(shutdown_io_r_init_ex("", &r_s, &rbuf, 0))
+               result = r_s.status;
+
+done:
+       prs_mem_free(&rbuf);
+       prs_mem_free(&qbuf);
+
+       return werror_to_ntstatus(result);
 }
 
 
@@ -75,7 +117,7 @@ NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
        prs_struct qbuf; 
        SHUTDOWN_Q_ABORT q_s;
        SHUTDOWN_R_ABORT r_s;
-       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       WERROR result = WERR_GENERAL_FAILURE;
 
        ZERO_STRUCT (q_s);
        ZERO_STRUCT (r_s);
@@ -100,5 +142,5 @@ done:
        prs_mem_free(&rbuf);
        prs_mem_free(&qbuf );
 
-       return result;
+       return werror_to_ntstatus(result);
 }
index 6ce74fed665e536dced964df409742c28f8f9ddd..518c20ff9b0067733ab57880ae1cdf29d37d2837 100644 (file)
  * @{
  **/
 
-/**********************************************************************
- Initialize a new spoolss buff for use by a client rpc
-**********************************************************************/
-static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
-{
-       buffer->ptr = (size != 0);
-       buffer->size = size;
-       buffer->string_at_end = size;
-       prs_init(&buffer->prs, size, ctx, MARSHALL);
-       buffer->struct_start = prs_offset(&buffer->prs);
-}
-
 /*********************************************************************
  Decode various spoolss rpc's and info levels
  ********************************************************************/
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_0 **info)
 {
         uint32 i;
@@ -69,7 +57,7 @@ static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_1 **info)
 {
         uint32 i;
@@ -89,7 +77,7 @@ static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                                uint32 returned, PRINTER_INFO_2 **info)
 {
         uint32 i;
@@ -111,7 +99,7 @@ static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                                uint32 returned, PRINTER_INFO_3 **info)
 {
         uint32 i;
@@ -132,7 +120,7 @@ static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_7 **info)
 {
        uint32 i;
@@ -153,7 +141,7 @@ static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, PORT_INFO_1 **info)
 {
         uint32 i;
@@ -173,7 +161,7 @@ static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, PORT_INFO_2 **info)
 {
         uint32 i;
@@ -193,7 +181,7 @@ static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_1 **info)
 {
         uint32 i;
@@ -213,7 +201,7 @@ static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_2 **info)
 {
         uint32 i;
@@ -233,7 +221,7 @@ static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_3 **info)
 {
         uint32 i;
@@ -253,7 +241,7 @@ static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                        uint32 returned, DRIVER_DIRECTORY_1 **info
 )
 {
@@ -430,7 +418,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPRINTERS q;
         SPOOL_R_ENUMPRINTERS r;
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
        WERROR result = W_ERROR(ERRgeneral);
 
        ZERO_STRUCT(q);
@@ -438,7 +426,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -525,7 +513,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPORTS q;
         SPOOL_R_ENUMPORTS r;
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
        WERROR result = W_ERROR(ERRgeneral);
        fstring server;
 
@@ -537,7 +525,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
        
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
        
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -600,7 +588,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETPRINTER q;
        SPOOL_R_GETPRINTER r;
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
        WERROR result = W_ERROR(ERRgeneral);
 
        ZERO_STRUCT(q);
@@ -608,7 +596,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
        
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -749,7 +737,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
        prs_struct qbuf, rbuf;
        SPOOL_Q_GETPRINTERDRIVER2 q;
         SPOOL_R_GETPRINTERDRIVER2 r;
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
        WERROR result = W_ERROR(ERRgeneral);
        fstring server;
 
@@ -761,7 +749,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -830,7 +818,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
        prs_struct qbuf, rbuf;
        SPOOL_Q_ENUMPRINTERDRIVERS q;
         SPOOL_R_ENUMPRINTERDRIVERS r;
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
        WERROR result = W_ERROR(ERRgeneral);
        fstring server;
 
@@ -842,7 +830,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -916,7 +904,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
        prs_struct                      qbuf, rbuf;
        SPOOL_Q_GETPRINTERDRIVERDIR     q;
         SPOOL_R_GETPRINTERDRIVERDIR    r;
-       NEW_BUFFER                      buffer;
+       RPC_BUFFER                      buffer;
        WERROR result = W_ERROR(ERRgeneral);
        fstring                         server;
 
@@ -928,7 +916,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1204,7 +1192,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
        SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
        int level = 1;
        WERROR result = W_ERROR(ERRgeneral);
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
@@ -1216,7 +1204,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
 
        /* Initialise input parameters */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        make_spoolss_q_getprintprocessordirectory(
                &q, name, environment, level, &buffer, offered);
@@ -1388,14 +1376,14 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        SPOOL_Q_GETFORM q;
        SPOOL_R_GETFORM r;
        WERROR result = W_ERROR(ERRgeneral);
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        /* Initialise parse structures */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1494,7 +1482,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        return result;
 }
 
-static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                           uint32 num_forms, FORM_1 **forms)
 {
        int i;
@@ -1530,14 +1518,14 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        SPOOL_Q_ENUMFORMS q;
        SPOOL_R_ENUMFORMS r;
        WERROR result = W_ERROR(ERRgeneral);
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        /* Initialise parse structures */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1576,7 +1564,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        return result;
 }
 
-static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                          uint32 num_jobs, JOB_INFO_1 **jobs)
 {
        uint32 i;
@@ -1588,7 +1576,7 @@ static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
                smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
 }
 
-static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, 
+static void decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                          uint32 num_jobs, JOB_INFO_2 **jobs)
 {
        uint32 i;
@@ -1611,14 +1599,14 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        SPOOL_Q_ENUMJOBS q;
        SPOOL_R_ENUMJOBS r;
        WERROR result = W_ERROR(ERRgeneral);
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        /* Initialise parse structures */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1728,14 +1716,14 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        SPOOL_Q_GETJOB q;
        SPOOL_R_GETJOB r;
        WERROR result = W_ERROR(ERRgeneral);
-       NEW_BUFFER buffer;
+       RPC_BUFFER buffer;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        /* Initialise parse structures */
 
-       init_buffer(&buffer, offered, mem_ctx);
+       rpcbuf_init(&buffer, offered, mem_ctx);
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
        prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
diff --git a/source/rpc_client/cli_svcctl.c b/source/rpc_client/cli_svcctl.c
new file mode 100644 (file)
index 0000000..9f80bb7
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Gerald Carter                   2005.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_client.h"
+
+struct svc_state_msg {
+       uint32 flag;
+       const char *message;
+};
+
+static struct svc_state_msg state_msg_table[] = {
+       { SVCCTL_STOPPED,            "stopped" },
+       { SVCCTL_START_PENDING,      "start pending" },
+       { SVCCTL_STOP_PENDING,       "stop pending" },
+       { SVCCTL_RUNNING,            "running" },
+       { SVCCTL_CONTINUE_PENDING,   "resume pending" },
+       { SVCCTL_PAUSE_PENDING,      "pause pending" },
+       { SVCCTL_PAUSED,             "paused" },
+       { 0,                          NULL }
+};
+       
+
+/********************************************************************
+********************************************************************/
+const char* svc_status_string( uint32 state )
+{
+       static fstring msg;
+       int i;
+       
+       fstr_sprintf( msg, "Unknown State [%d]", state );
+       
+       for ( i=0; state_msg_table[i].message; i++ ) {
+               if ( state_msg_table[i].flag == state ) {
+                       fstrcpy( msg, state_msg_table[i].message );
+                       break;  
+               }
+       }
+       
+       return msg;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                              POLICY_HND *hSCM, uint32 access_desired )
+{
+       SVCCTL_Q_OPEN_SCMANAGER in;
+       SVCCTL_R_OPEN_SCMANAGER out;
+       prs_struct qbuf, rbuf;
+       fstring server;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       /* leave the database name NULL to get the default service db */
+
+       in.database = NULL;
+
+       /* set the server name */
+
+       if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) )
+               return WERR_NOMEM;
+       fstr_sprintf( server, "\\\\%s", cli->desthost );
+       init_unistr2( in.servername, server, UNI_STR_TERMINATE );
+
+       in.access = access_desired;
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_open_scmanager,
+                   svcctl_io_r_open_scmanager, 
+                   WERR_GENERAL_FAILURE );
+       
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       memcpy( hSCM, &out.handle, sizeof(POLICY_HND) );
+       
+       return out.status;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                POLICY_HND *hSCM, POLICY_HND *hService, 
+                               const char *servicename, uint32 access_desired )
+{
+       SVCCTL_Q_OPEN_SERVICE in;
+       SVCCTL_R_OPEN_SERVICE out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
+       init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE );
+       in.access = access_desired;
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_open_service,
+                   svcctl_io_r_open_service, 
+                   WERR_GENERAL_FAILURE );
+       
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       memcpy( hService, &out.handle, sizeof(POLICY_HND) );
+       
+       return out.status;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
+{
+       SVCCTL_Q_CLOSE_SERVICE in;
+       SVCCTL_R_CLOSE_SERVICE out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CLOSE_SERVICE, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_close_service,
+                   svcctl_io_r_close_service, 
+                   WERR_GENERAL_FAILURE );
+
+       return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                      POLICY_HND *hSCM, uint32 type, uint32 state, 
+                                     uint32 *returned, ENUM_SERVICES_STATUS **service_array  )
+{
+       SVCCTL_Q_ENUM_SERVICES_STATUS in;
+       SVCCTL_R_ENUM_SERVICES_STATUS out;
+       prs_struct qbuf, rbuf;
+       uint32 resume = 0;
+       ENUM_SERVICES_STATUS *services;
+       int i;
+
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       /* setup the request */
+       
+       memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
+       
+       in.type        = type;
+       in.state       = state;
+       in.resume      = &resume;
+       
+       /* first time is to get the buffer size */
+       in.buffer_size = 0;
+
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_enum_services_status,
+                   svcctl_io_r_enum_services_status, 
+                   WERR_GENERAL_FAILURE );
+
+       /* second time with correct buffer size...should be ok */
+       
+       if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
+               in.buffer_size = out.needed;
+
+               CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W, 
+                           in, out, 
+                           qbuf, rbuf,
+                           svcctl_io_q_enum_services_status,
+                           svcctl_io_r_enum_services_status, 
+                           WERR_GENERAL_FAILURE );
+       }
+       
+       if ( !W_ERROR_IS_OK(out.status) ) 
+               return out.status;
+               
+       /* pull out the data */
+       if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) ) 
+               return WERR_NOMEM;
+               
+       for ( i=0; i<out.returned; i++ ) {
+               svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
+       }
+       
+       *service_array = services;
+       *returned      = out.returned;
+       
+       return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                POLICY_HND *hService, SERVICE_STATUS *status )
+{
+       SVCCTL_Q_QUERY_STATUS in;
+       SVCCTL_R_QUERY_STATUS out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_query_status,
+                   svcctl_io_r_query_status, 
+                   WERR_GENERAL_FAILURE );
+       
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
+       
+       return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                POLICY_HND *hService, SERVICE_CONFIG *config )
+{
+       SVCCTL_Q_QUERY_SERVICE_CONFIG in;
+       SVCCTL_R_QUERY_SERVICE_CONFIG out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       in.buffer_size = 0;
+       
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_query_service_config,
+                   svcctl_io_r_query_service_config, 
+                   WERR_GENERAL_FAILURE );
+       
+       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
+               in.buffer_size = out.needed;
+
+               CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
+                           in, out, 
+                           qbuf, rbuf,
+                           svcctl_io_q_query_service_config,
+                           svcctl_io_r_query_service_config, 
+                           WERR_GENERAL_FAILURE );
+       }
+       
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       memcpy( config, &out.config, sizeof(SERVICE_CONFIG) );
+       
+       config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+       config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+       config->dependencies   = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+       config->startname      = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+       config->displayname    = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+       
+       copy_unistr2( config->executablepath, out.config.executablepath );
+       copy_unistr2( config->loadordergroup, out.config.loadordergroup );
+       copy_unistr2( config->dependencies, out.config.dependencies );
+       copy_unistr2( config->startname, out.config.startname );
+       copy_unistr2( config->displayname, out.config.displayname );
+       
+       return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                 POLICY_HND *hService,
+                                 const char **parm_array, uint32 parmcount )
+{
+       SVCCTL_Q_START_SERVICE in;
+       SVCCTL_R_START_SERVICE out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       
+       in.parmcount  = 0;
+       in.parameters = NULL;
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_start_service,
+                   svcctl_io_r_start_service,
+                   WERR_GENERAL_FAILURE );
+       
+       return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                   POLICY_HND *hService, uint32 control,
+                                  SERVICE_STATUS *status )
+{
+       SVCCTL_Q_CONTROL_SERVICE in;
+       SVCCTL_R_CONTROL_SERVICE out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       in.control = control;
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_control_service,
+                   svcctl_io_r_control_service,
+                   WERR_GENERAL_FAILURE );
+       
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
+       
+       return out.status;
+}
+
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                POLICY_HND *hService, fstring displayname )
+{
+       SVCCTL_Q_GET_DISPLAY_NAME in;
+       SVCCTL_R_GET_DISPLAY_NAME out;
+       prs_struct qbuf, rbuf;
+       
+       ZERO_STRUCT(in);
+       ZERO_STRUCT(out);
+       
+       memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+       in.display_name_len = 0;
+       
+       CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, 
+                   in, out, 
+                   qbuf, rbuf,
+                   svcctl_io_q_get_display_name,
+                   svcctl_io_r_get_display_name, 
+                   WERR_GENERAL_FAILURE );
+       
+       /* second time with correct buffer size...should be ok */
+       
+       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
+               in.display_name_len = out.display_name_len;
+
+               CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, 
+                           in, out, 
+                           qbuf, rbuf,
+                           svcctl_io_q_get_display_name,
+                           svcctl_io_r_get_display_name, 
+                           WERR_GENERAL_FAILURE );
+       }
+
+       if ( !W_ERROR_IS_OK( out.status ) )
+               return out.status;
+
+       rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
+       
+       return out.status;
+}
+
diff --git a/source/rpc_parse/parse_buffer.c b/source/rpc_parse/parse_buffer.c
new file mode 100644 (file)
index 0000000..a48d5cf
--- /dev/null
@@ -0,0 +1,491 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ * 
+ *  Copyright (C) Andrew Tridgell              1992-2000,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000,
+ *  Copyright (C) Gerald Carter                2000-2005,
+ *  Copyright (C) Tim Potter                  2001-2002.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/**********************************************************************
+ Initialize a new spoolss buff for use by a client rpc
+**********************************************************************/
+void rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
+{
+       buffer->size = size;
+       buffer->string_at_end = size;
+       prs_init(&buffer->prs, size, ctx, MARSHALL);
+       buffer->struct_start = prs_offset(&buffer->prs);
+}
+
+/*******************************************************************
+ Read/write a RPC_BUFFER struct.
+********************************************************************/  
+
+BOOL prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer)
+{
+       prs_debug(ps, depth, desc, "prs_rpcbuffer");
+       depth++;
+               
+       /* reading */
+       if (UNMARSHALLING(ps)) {
+               buffer->size=0;
+               buffer->string_at_end=0;
+               
+               if (!prs_uint32("size", ps, depth, &buffer->size))
+                       return False;
+                                       
+               /*
+                * JRA. I'm not sure if the data in here is in big-endian format if
+                * the client is big-endian. Leave as default (little endian) for now.
+                */
+
+               if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
+                       return False;
+
+               if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
+                       return False;
+
+               if (!prs_set_offset(&buffer->prs, 0))
+                       return False;
+
+               if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
+                       return False;
+
+               buffer->string_at_end=buffer->size;
+               
+               return True;
+       }
+       else {
+               BOOL ret = False;
+
+               if (!prs_uint32("size", ps, depth, &buffer->size))
+                       goto out;
+
+               if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
+                       goto out;
+
+               ret = True;
+       out:
+
+               /* We have finished with the data in buffer->prs - free it. */
+               prs_mem_free(&buffer->prs);
+
+               return ret;
+       }
+}
+
+/*******************************************************************
+ Read/write an RPC_BUFFER* struct.(allocate memory if unmarshalling)
+********************************************************************/  
+
+BOOL prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer)
+{
+       uint32 data_p;
+
+       /* caputure the pointer value to stream */
+
+       data_p = (uint32) *buffer;
+
+       if ( !prs_uint32("ptr", ps, depth, &data_p ))
+               return False;
+
+       /* we're done if there is no data */
+
+       if ( !data_p )
+               return True;
+               
+       if ( UNMARSHALLING(ps) ) {
+               if ( !(*buffer = PRS_ALLOC_MEM(ps, RPC_BUFFER, 1)) )
+                       return False;
+       }
+
+       return prs_rpcbuffer( desc, ps, depth, *buffer);
+}
+
+/****************************************************************************
+ Allocate more memory for a RPC_BUFFER.
+****************************************************************************/
+
+BOOL rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size)
+{
+       prs_struct *ps;
+       uint32 extra_space;
+       uint32 old_offset;
+       
+       /* if we don't need anything. don't do anything */
+       
+       if ( buffer_size == 0x0 )
+               return True;
+       
+       ps= &buffer->prs;
+
+       /* damn, I'm doing the reverse operation of prs_grow() :) */
+       if (buffer_size < prs_data_size(ps))
+               extra_space=0;
+       else    
+               extra_space = buffer_size - prs_data_size(ps);
+
+       /*
+        * save the offset and move to the end of the buffer
+        * prs_grow() checks the extra_space against the offset
+        */
+       old_offset=prs_offset(ps);      
+       prs_set_offset(ps, prs_data_size(ps));
+       
+       if (!prs_grow(ps, extra_space))
+               return False;
+
+       prs_set_offset(ps, old_offset);
+
+       buffer->string_at_end=prs_data_size(ps);
+
+       return True;
+}
+
+/*******************************************************************
+ move a BUFFER from the query to the reply.
+ As the data pointers in RPC_BUFFER are malloc'ed, not talloc'ed,
+ this is ok. This is an OPTIMIZATION and is not strictly neccessary.
+ Clears the memory to zero also.
+********************************************************************/  
+
+void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest)
+{
+       SMB_ASSERT( src != NULL );
+
+       prs_switch_type(&src->prs, MARSHALL);
+       if(!prs_set_offset(&src->prs, 0))
+               return;
+       prs_force_dynamic(&src->prs);
+       prs_mem_clear(&src->prs);
+       *dest=src;
+}
+
+/*******************************************************************
+ Get the size of a BUFFER struct.
+********************************************************************/  
+
+uint32 rpcbuf_get_size(RPC_BUFFER *buffer)
+{
+       return (buffer->size);
+}
+
+
+/*******************************************************************
+ * write a UNICODE string and its relative pointer.
+ * used by all the RPC structs passing a buffer
+ *
+ * As I'm a nice guy, I'm forcing myself to explain this code.
+ * MS did a good job in the overall spoolss code except in some
+ * functions where they are passing the API buffer directly in the
+ * RPC request/reply. That's to maintain compatiility at the API level.
+ * They could have done it the good way the first time.
+ *
+ * So what happen is: the strings are written at the buffer's end, 
+ * in the reverse order of the original structure. Some pointers to
+ * the strings are also in the buffer. Those are relative to the
+ * buffer's start.
+ *
+ * If you don't understand or want to change that function,
+ * first get in touch with me: jfm@samba.org
+ *
+ ********************************************************************/
+
+BOOL smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string)
+{
+       prs_struct *ps=&buffer->prs;
+       
+       if (MARSHALLING(ps)) {
+               uint32 struct_offset = prs_offset(ps);
+               uint32 relative_offset;
+               
+               buffer->string_at_end -= (size_of_relative_string(string) - 4);
+               if(!prs_set_offset(ps, buffer->string_at_end))
+                       return False;
+#if 0  /* JERRY */
+               /*
+                * Win2k does not align strings in a buffer
+                * Tested against WinNT 4.0 SP 6a & 2k SP2  --jerry
+                */
+               if (!prs_align(ps))
+                       return False;
+#endif
+               buffer->string_at_end = prs_offset(ps);
+               
+               /* write the string */
+               if (!smb_io_unistr(desc, string, ps, depth))
+                       return False;
+
+               if(!prs_set_offset(ps, struct_offset))
+                       return False;
+               
+               relative_offset=buffer->string_at_end - buffer->struct_start;
+               /* write its offset */
+               if (!prs_uint32("offset", ps, depth, &relative_offset))
+                       return False;
+       }
+       else {
+               uint32 old_offset;
+               
+               /* read the offset */
+               if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
+                       return False;
+
+               if (buffer->string_at_end == 0)
+                       return True;
+
+               old_offset = prs_offset(ps);
+               if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
+                       return False;
+
+               /* read the string */
+               if (!smb_io_unistr(desc, string, ps, depth))
+                       return False;
+
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
+       }
+       return True;
+}
+
+/*******************************************************************
+ * write a array of UNICODE strings and its relative pointer.
+ * used by 2 RPC structs
+ ********************************************************************/
+
+BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string)
+{
+       UNISTR chaine;
+       
+       prs_struct *ps=&buffer->prs;
+       
+       if (MARSHALLING(ps)) {
+               uint32 struct_offset = prs_offset(ps);
+               uint32 relative_offset;
+               uint16 *p;
+               uint16 *q;
+               uint16 zero=0;
+               p=*string;
+               q=*string;
+
+               /* first write the last 0 */
+               buffer->string_at_end -= 2;
+               if(!prs_set_offset(ps, buffer->string_at_end))
+                       return False;
+
+               if(!prs_uint16("leading zero", ps, depth, &zero))
+                       return False;
+
+               while (p && (*p!=0)) {  
+                       while (*q!=0)
+                               q++;
+
+                       /* Yes this should be malloc not talloc. Don't change. */
+
+                       chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16));
+                       if (chaine.buffer == NULL)
+                               return False;
+
+                       memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
+
+                       buffer->string_at_end -= (q-p+1)*sizeof(uint16);
+
+                       if(!prs_set_offset(ps, buffer->string_at_end)) {
+                               SAFE_FREE(chaine.buffer);
+                               return False;
+                       }
+
+                       /* write the string */
+                       if (!smb_io_unistr(desc, &chaine, ps, depth)) {
+                               SAFE_FREE(chaine.buffer);
+                               return False;
+                       }
+                       q++;
+                       p=q;
+
+                       SAFE_FREE(chaine.buffer);
+               }
+               
+               if(!prs_set_offset(ps, struct_offset))
+                       return False;
+               
+               relative_offset=buffer->string_at_end - buffer->struct_start;
+               /* write its offset */
+               if (!prs_uint32("offset", ps, depth, &relative_offset))
+                       return False;
+
+       } else {
+
+               /* UNMARSHALLING */
+
+               uint32 old_offset;
+               uint16 *chaine2=NULL;
+               int l_chaine=0;
+               int l_chaine2=0;
+               size_t realloc_size = 0;
+
+               *string=NULL;
+                               
+               /* read the offset */
+               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
+                       return False;
+
+               old_offset = prs_offset(ps);
+               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
+                       return False;
+       
+               do {
+                       if (!smb_io_unistr(desc, &chaine, ps, depth))
+                               return False;
+                       
+                       l_chaine=str_len_uni(&chaine);
+                       
+                       /* we're going to add two more bytes here in case this
+                          is the last string in the array and we need to add 
+                          an extra NULL for termination */
+                       if (l_chaine > 0)
+                       {
+                               uint16 *tc2;
+                       
+                               realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
+
+                               /* Yes this should be realloc - it's freed below. JRA */
+
+                               if((tc2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
+                                       SAFE_FREE(chaine2);
+                                       return False;
+                               }
+                               else chaine2 = tc2;
+                               memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
+                               l_chaine2+=l_chaine+1;
+                       }
+               
+               } while(l_chaine!=0);
+               
+               /* the end should be bould NULL terminated so add 
+                  the second one here */
+               if (chaine2)
+               {
+                       chaine2[l_chaine2] = '\0';
+                       *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
+                       SAFE_FREE(chaine2);
+               }
+
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
+       }
+       return True;
+}
+
+/*******************************************************************
+ Parse a DEVMODE structure and its relative pointer.
+********************************************************************/
+
+BOOL smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc)
+{
+       prs_struct *ps= &buffer->prs;
+
+       prs_debug(ps, depth, desc, "smb_io_relsecdesc");
+       depth++;
+
+       if (MARSHALLING(ps)) {
+               uint32 struct_offset = prs_offset(ps);
+               uint32 relative_offset;
+
+               if (! *secdesc) {
+                       relative_offset = 0;
+                       if (!prs_uint32("offset", ps, depth, &relative_offset))
+                               return False;
+                       return True;
+               }
+               
+               if (*secdesc != NULL) {
+                       buffer->string_at_end -= sec_desc_size(*secdesc);
+
+                       if(!prs_set_offset(ps, buffer->string_at_end))
+                               return False;
+                       /* write the secdesc */
+                       if (!sec_io_desc(desc, secdesc, ps, depth))
+                               return False;
+
+                       if(!prs_set_offset(ps, struct_offset))
+                               return False;
+               }
+
+               relative_offset=buffer->string_at_end - buffer->struct_start;
+               /* write its offset */
+
+               if (!prs_uint32("offset", ps, depth, &relative_offset))
+                       return False;
+       } else {
+               uint32 old_offset;
+               
+               /* read the offset */
+               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
+                       return False;
+
+               old_offset = prs_offset(ps);
+               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
+                       return False;
+
+               /* read the sd */
+               if (!sec_io_desc(desc, secdesc, ps, depth))
+                       return False;
+
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
+       }
+       return True;
+}
+
+
+
+/*******************************************************************
+ * return the length of a UNICODE string in number of char, includes:
+ * - the leading zero
+ * - the relative pointer size
+ ********************************************************************/
+
+uint32 size_of_relative_string(UNISTR *string)
+{
+       uint32 size=0;
+       
+       size=str_len_uni(string);       /* the string length       */
+       size=size+1;                    /* add the trailing zero   */
+       size=size*2;                    /* convert in char         */
+       size=size+4;                    /* add the size of the ptr */   
+
+#if 0  /* JERRY */
+       /* 
+        * Do not include alignment as Win2k does not align relative
+        * strings within a buffer   --jerry 
+        */
+       /* Ensure size is 4 byte multiple (prs_align is being called...). */
+       /* size += ((4 - (size & 3)) & 3); */
+#endif 
+
+       return size;
+}
+
diff --git a/source/rpc_parse/parse_eventlog.c b/source/rpc_parse/parse_eventlog.c
new file mode 100644 (file)
index 0000000..9bb0a13
--- /dev/null
@@ -0,0 +1,457 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/*
+ * called from eventlog_q_open_eventlog (srv_eventlog.c)
+ */
+
+BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u,
+                                prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+    
+    /* Data format seems to be:
+       UNKNOWN structure
+         uint32            unknown
+         uint16            unknown
+         uint16            unknown
+       Eventlog name
+         uint16            eventlog name length
+         uint16            eventlog name size
+         Character Array
+          uint32          unknown
+          uint32          max count
+           uint32          offset
+           uint32          actual count
+          UNISTR2         log file name
+       Server Name
+         uint16            server name length
+         uint16            server name size
+        Character Array
+          UNISTR2         server name
+    */
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_open_eventlog");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       /* Munch unknown bits */
+
+       if(!prs_uint32("", ps, depth, &q_u->unknown1))
+               return False;
+       if(!prs_uint16("", ps, depth, &q_u->unknown2))
+               return False;
+       if(!prs_uint16("", ps, depth, &q_u->unknown3))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       /* Get name of log source */
+
+       if(!prs_uint16("sourcename_length", ps, depth, &q_u->sourcename_length))
+               return False;
+       if(!prs_uint16("sourcename_size", ps, depth, &q_u->sourcename_size))
+               return False;
+       if(!prs_uint32("sourcename_ptr", ps, depth, &q_u->sourcename_ptr))
+               return False;
+       if(!smb_io_unistr2("", &q_u->sourcename, q_u->sourcename_ptr, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       /* Get server name */
+
+       if(!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
+               return False;
+       if(!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_r_open_eventlog(const char *desc, EVENTLOG_R_OPEN_EVENTLOG *r_u,
+                                prs_struct *ps, int depth)
+{
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_open_eventlog");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth)))
+               return False;
+
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_q_get_num_records(const char *desc, EVENTLOG_Q_GET_NUM_RECORDS *q_u,
+                                  prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_get_num_records");
+       depth++;
+
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+               return False;
+    
+       return True;
+}
+
+BOOL eventlog_io_r_get_num_records(const char *desc, EVENTLOG_R_GET_NUM_RECORDS *r_u,
+                                  prs_struct *ps, int depth)
+{
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_get_num_records");
+       depth++;
+
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(prs_uint32("num records", ps, depth, &(r_u->num_records))))
+               return False;
+
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_q_get_oldest_entry(const char *desc, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u,
+                                   prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_get_oldest_entry");
+       depth++;
+    
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_r_get_oldest_entry(const char *desc, EVENTLOG_R_GET_OLDEST_ENTRY *r_u,
+                                   prs_struct *ps, int depth)
+{
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_get_oldest_entry");
+       depth++;
+
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(prs_uint32("oldest entry", ps, depth, &(r_u->oldest_entry))))
+               return False;
+
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_q_close_eventlog(const char *desc, EVENTLOG_Q_CLOSE_EVENTLOG *q_u,
+                                 prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_close_eventlog");
+       depth++;
+    
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_r_close_eventlog(const char *desc, EVENTLOG_R_CLOSE_EVENTLOG *r_u,
+                                 prs_struct *ps, int depth)
+{
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_close_eventlog");
+       depth++;
+
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth)))
+               return False;
+
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
+
+BOOL eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u,
+                                prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_read_eventlog");
+       depth++;
+
+       if(!(prs_align(ps)))
+               return False;
+
+       if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+               return False;
+
+       if(!(prs_uint32("read flags", ps, depth, &(q_u->flags))))
+               return False;
+
+       if(!(prs_uint32("read offset", ps, depth, &(q_u->offset))))
+               return False;
+
+       if(!(prs_uint32("read buf size", ps, depth, &(q_u->max_read_size))))
+               return False;
+
+       return True;
+}
+/* Structure of response seems to be:
+   DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size
+   for i=0..n
+       EVENTLOGRECORD record
+   DWORD sent_size -- sum of EVENTLOGRECORD lengths if records returned, 0 otherwise
+   DWORD real_size -- 0 if records returned, otherwise length of next record to be returned
+   WERROR status */
+BOOL eventlog_io_r_read_eventlog(const char *desc,
+                                EVENTLOG_Q_READ_EVENTLOG *q_u,
+                                EVENTLOG_R_READ_EVENTLOG *r_u,
+                                prs_struct *ps,
+                                int depth)
+{
+       Eventlog_entry *entry;
+       uint32 record_written = 0;
+       uint32 record_total = 0;
+
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_read_eventlog");
+       depth++;
+
+       /* First, see if we've read more logs than we can output */
+
+       if(r_u->num_bytes_in_resp > q_u->max_read_size) {
+               entry = r_u->entry;
+
+               /* remove the size of the last entry from the list */
+
+               while(entry->next != NULL)
+                       entry = entry->next;
+
+               r_u->num_bytes_in_resp -= entry->record.length;
+
+               /* do not output the last log entry */
+       
+               r_u->num_records--;
+       }
+    
+       entry = r_u->entry;
+       record_total = r_u->num_records;
+
+       if(r_u->num_bytes_in_resp != 0)
+               r_u->sent_size = r_u->num_bytes_in_resp;
+       else
+               r_u->real_size = entry->record.length;
+
+       if(!(prs_align(ps)))
+               return False;
+       if(!(prs_uint32("bytes in resp", ps, depth, &(q_u->max_read_size))))
+               return False;
+
+       while(entry != NULL && record_written < record_total)
+       {
+               DEBUG(10, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total));
+
+               /* Encode the actual eventlog record record */
+
+               if(!(prs_uint32("length", ps, depth, &(entry->record.length))))
+                       return False;
+               if(!(prs_uint32("reserved", ps, depth, &(entry->record.reserved1))))
+                       return False;
+               if(!(prs_uint32("record number", ps, depth, &(entry->record.record_number))))
+                       return False;
+               if(!(prs_uint32("time generated", ps, depth, &(entry->record.time_generated))))
+                       return False;
+               if(!(prs_uint32("time written", ps, depth, &(entry->record.time_written))))
+                       return False;
+               if(!(prs_uint32("event id", ps, depth, &(entry->record.event_id))))
+                       return False;
+               if(!(prs_uint16("event type", ps, depth, &(entry->record.event_type))))
+                       return False;
+               if(!(prs_uint16("num strings", ps, depth, &(entry->record.num_strings))))
+                       return False;
+               if(!(prs_uint16("event category", ps, depth, &(entry->record.event_category))))
+                       return False;
+               if(!(prs_uint16("reserved2", ps, depth, &(entry->record.reserved2))))
+                       return False;
+               if(!(prs_uint32("closing record", ps, depth, &(entry->record.closing_record_number))))
+                       return False;
+               if(!(prs_uint32("string offset", ps, depth, &(entry->record.string_offset))))
+                       return False;
+               if(!(prs_uint32("user sid length", ps, depth, &(entry->record.user_sid_length))))
+                       return False;
+               if(!(prs_uint32("user sid offset", ps, depth, &(entry->record.user_sid_offset))))
+                       return False;
+               if(!(prs_uint32("data length", ps, depth, &(entry->record.data_length))))
+                       return False;
+               if(!(prs_uint32("data offset", ps, depth, &(entry->record.data_offset))))
+                       return False;
+               if(!(prs_align(ps)))
+                       return False;
+       
+               /* Now encoding data */
+
+               if(!(prs_uint8s(False, "buffer", ps, depth, entry->data, 
+                       entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length))))
+               {
+                       return False;
+               }
+
+               if(!(prs_align(ps)))
+                       return False;
+               if(!(prs_uint32("length 2", ps, depth, &(entry->record.length))))
+                       return False;
+
+               entry = entry->next;
+               record_written++;
+
+       }       /* end of encoding EVENTLOGRECORD */
+
+       /* Now pad with whitespace until the end of the response buffer */
+
+       r_u->end_of_entries_padding = (uint8 *)calloc(q_u->max_read_size - r_u->num_bytes_in_resp, sizeof(uint8));
+
+       if(!(prs_uint8s(False, "end of entries padding", ps, 
+               depth, r_u->end_of_entries_padding,
+               (q_u->max_read_size - r_u->num_bytes_in_resp))))
+       {
+               return False;
+       }
+
+       free(r_u->end_of_entries_padding);
+
+       /* We had better be DWORD aligned here */
+
+       if(!(prs_uint32("sent size", ps, depth, &(r_u->sent_size))))
+               return False;
+       if(!(prs_uint32("real size", ps, depth, &(r_u->real_size))))
+               return False;
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
+
+/* The windows client seems to be doing something funny with the file name
+   A call like
+      ClearEventLog(handle, "backup_file")
+   on the client side will result in the backup file name looking like this on the
+   server side:
+      \??\${CWD of client}\backup_file
+   If an absolute path gets specified, such as
+      ClearEventLog(handle, "C:\\temp\\backup_file")
+   then it is still mangled by the client into this:
+      \??\C:\temp\backup_file
+   when it is on the wire.
+   I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
+   would be added in given that the backup file gets written on the server side. */
+
+BOOL eventlog_io_q_clear_eventlog(const char *desc, EVENTLOG_Q_CLEAR_EVENTLOG *q_u,
+                                 prs_struct *ps, int depth)
+{
+       if(q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_q_clear_eventlog");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!(prs_uint32("unknown1", ps, depth, &q_u->unknown1)))
+               return False;
+       if(!(prs_uint16("backup_file_length", ps, depth, &q_u->backup_file_length)))
+               return False;
+       if(!(prs_uint16("backup_file_size", ps, depth, &q_u->backup_file_size)))
+               return False;
+       if(!prs_uint32("backup_file_ptr", ps, depth, &q_u->backup_file_ptr))
+               return False;
+       if(!smb_io_unistr2("backup file", &q_u->backup_file, q_u->backup_file_ptr, ps, depth))
+               return False;
+
+       return True;
+
+}
+
+BOOL eventlog_io_r_clear_eventlog(const char *desc, EVENTLOG_R_CLEAR_EVENTLOG *r_u,
+                                 prs_struct *ps, int depth)
+{
+       if(r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "eventlog_io_r_clear_eventlog");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+               return False;
+
+       return True;
+}
index bbff258722ae6cdb93e35d52e5a95878fe63be39..ab3d3fcfe819cc7ba6ecd1368ab869c00618f33b 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Paul Ashton                       1997,
  *  Copyright (C) Andrew Bartlett                   2002,
  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002.
+ *  Copyright (C) Gerald )Jerry) Carter             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
@@ -516,100 +517,99 @@ void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 en
 
         DEBUG(5, ("init_r_enum_trust_dom\n"));
        
-        r_e->enum_context = enum_context;
-       r_e->num_domains = num_domains;
-       r_e->ptr_enum_domains = 0;
-       r_e->num_domains2 = num_domains;
-       
-       if (num_domains != 0) {
+        r_e->enum_context  = enum_context;
+       r_e->count         = num_domains;
+                       
+       if ( num_domains != 0 ) {
        
-               /* 
-                * allocating empty arrays of unicode headers, strings
-                * and sids of enumerated trusted domains
-                */
-               if (!(r_e->hdr_domain_name = TALLOC_ARRAY(ctx,UNIHDR2,num_domains))) {
-                       r_e->status = NT_STATUS_NO_MEMORY;
-                       return;
-               }
+               /* allocate container memory */
                
-               if (!(r_e->uni_domain_name = TALLOC_ARRAY(ctx,UNISTR2,num_domains))) {
-                       r_e->status = NT_STATUS_NO_MEMORY;
-                       return;
-               }
-
-               if (!(r_e->domain_sid = TALLOC_ARRAY(ctx,DOM_SID2,num_domains))) {
+               r_e->domlist = TALLOC_P( ctx, DOMAIN_LIST );
+               r_e->domlist->domains = TALLOC_ARRAY( ctx, DOMAIN_INFO, r_e->count );
+               
+               if ( !r_e->domlist || !r_e->domlist->domains ) {
                        r_e->status = NT_STATUS_NO_MEMORY;
                        return;
                }
+               
+               r_e->domlist->count = r_e->count;
+               
+               /* initialize the list of domains and their sid */
+               
+               for (i = 0; i < num_domains; i++) {     
+                       if ( !(r_e->domlist->domains[i].sid = TALLOC_P(ctx, DOM_SID2)) ) {
+                               r_e->status = NT_STATUS_NO_MEMORY;
+                               return;
+                       }
                                
-               for (i = 0; i < num_domains; i++) {
-                       
-                       /* don't know what actually is this for */
-                       r_e->ptr_enum_domains = 1;
-                       
-                       init_dom_sid2(&r_e->domain_sid[i], &(td[i])->sid);
-                       
-                       init_unistr2_w(ctx, &r_e->uni_domain_name[i], (td[i])->name);
-                       init_uni_hdr2(&r_e->hdr_domain_name[i], &r_e->uni_domain_name[i]);
-                       
-               };
+                       init_dom_sid2(r_e->domlist->domains[i].sid, &(td[i])->sid);
+                       init_unistr4_w(ctx, &r_e->domlist->domains[i].name, (td[i])->name);     
+               }
        }
 
 }
 
 /*******************************************************************
- Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
 ********************************************************************/
 
-BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e, 
-                            prs_struct *ps, int depth)
+BOOL lsa_io_domain_list( const char *desc, prs_struct *ps, int depth, DOMAIN_LIST *domlist )
 {
-       prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
+       int i;
+       
+       prs_debug(ps, depth, desc, "lsa_io_domain_list");
        depth++;
 
-       if(!prs_uint32("enum_context    ", ps, depth, &r_e->enum_context))
-               return False;
-       if(!prs_uint32("num_domains     ", ps, depth, &r_e->num_domains))
-               return False;
-       if(!prs_uint32("ptr_enum_domains", ps, depth, &r_e->ptr_enum_domains))
+       if(!prs_uint32("count", ps, depth, &domlist->count))
                return False;
 
-       if (r_e->ptr_enum_domains) {
-               int i, num_domains;
+       if ( domlist->count == 0 )
+               return True;
+               
+       if ( UNMARSHALLING(ps) ) {
+               if ( !(domlist->domains = PRS_ALLOC_MEM( ps, DOMAIN_INFO, domlist->count )) )
+                       return False;
+       }
+       
+       /* headers */
+       
+       for ( i=0; i<domlist->count; i++ ) {
+               if ( !prs_unistr4_hdr("name_header", ps, depth, &domlist->domains[i].name) )
+                       return False;
+               if ( !smb_io_dom_sid2_p("sid_header", ps, depth, &domlist->domains[i].sid) )
+                       return False;
+       }
 
-               if(!prs_uint32("num_domains2", ps, depth, &r_e->num_domains2))
+       /* data */
+       
+       for ( i=0; i<domlist->count; i++ ) {
+               if ( !prs_unistr4_str("name", ps, depth, &domlist->domains[i].name) )
                        return False;
+               if( !smb_io_dom_sid2("sid", domlist->domains[i].sid, ps, depth) )
+                       return False;
+       }
+       
+       return True;
+}
 
-               num_domains = r_e->num_domains2;
+/*******************************************************************
+ Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
 
-               if (UNMARSHALLING(ps)) {
-                       if (!(r_e->hdr_domain_name = PRS_ALLOC_MEM(ps,UNIHDR2,num_domains)))
-                               return False;
+BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e, 
+                            prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
+       depth++;
 
-                       if (!(r_e->uni_domain_name = PRS_ALLOC_MEM(ps,UNISTR2,num_domains)))
-                               return False;
+       if(!prs_uint32("enum_context", ps, depth, &r_e->enum_context))
+               return False;
 
-                       if (!(r_e->domain_sid = PRS_ALLOC_MEM(ps,DOM_SID2,num_domains)))
-                               return False;
-               }
+       if(!prs_uint32("count", ps, depth, &r_e->count))
+               return False;
 
-               for (i = 0; i < num_domains; i++) {
-                       if(!smb_io_unihdr2 ("", &r_e->hdr_domain_name[i], ps, 
-                                           depth))
-                               return False;
-               }
+       if ( !prs_pointer("trusted_domains", ps, depth, (void**)&r_e->domlist, sizeof(DOMAIN_LIST), (PRS_POINTER_CAST)lsa_io_domain_list))
+               return False;
                
-               for (i = 0; i < num_domains; i++) {
-                       if(!smb_io_unistr2 ("", &r_e->uni_domain_name[i],
-                                           r_e->hdr_domain_name[i].buffer,
-                                           ps, depth))
-                               return False;
-                       if(!smb_io_dom_sid2("", &r_e->domain_sid[i], ps, 
-                                           depth))
-                               return False;
-               }
-       }
-
        if(!prs_ntstatus("status", ps, depth, &r_e->status))
                return False;
 
@@ -906,7 +906,7 @@ void init_q_lookup_sids(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_SIDS *q_l,
        memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
        init_lsa_sid_enum(mem_ctx, &q_l->sids, num_sids, sids);
        
-       q_l->level.value = level;
+       q_l->level = level;
 }
 
 /*******************************************************************
@@ -928,7 +928,10 @@ BOOL lsa_io_q_lookup_sids(const char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *
                return False;
        if(!lsa_io_trans_names("names  ", &q_s->names, ps, depth)) /* translated names */
                return False;
-       if(!smb_io_lookup_level("switch ", &q_s->level, ps, depth)) /* lookup level */
+
+       if(!prs_uint16("level", ps, depth, &q_s->level)) /* lookup level */
+               return False;
+       if(!prs_align(ps))
                return False;
 
        if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count))
@@ -2319,7 +2322,9 @@ NTSTATUS init_r_enum_acct_rights( LSA_R_ENUM_ACCT_RIGHTS *r_u, PRIVILEGE_SET *pr
        }
 
        if ( num_priv ) {
-               if ( !init_unistr2_array( &r_u->rights, num_priv, privname_array ) ) 
+               r_u->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+
+               if ( !init_unistr4_array( r_u->rights, num_priv, privname_array ) ) 
                        return NT_STATUS_NO_MEMORY;
 
                r_u->count = num_priv;
@@ -2361,7 +2366,7 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr
        if(!prs_uint32("count   ", ps, depth, &r_c->count))
                return False;
 
-       if(!smb_io_unistr2_array("rights", &r_c->rights, ps, depth))
+       if ( !prs_pointer("rights", ps, depth, (void**)&r_c->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
                return False;
 
        if(!prs_align(ps))
@@ -2377,17 +2382,17 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr
 /*******************************************************************
  Inits an LSA_Q_ADD_ACCT_RIGHTS structure.
 ********************************************************************/
-void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q, 
-                           POLICY_HND *hnd, 
-                           DOM_SID *sid,
-                           uint32 count, 
-                           const char **rights)
+void init_q_add_acct_rights( LSA_Q_ADD_ACCT_RIGHTS *q_q, POLICY_HND *hnd, 
+                             DOM_SID *sid, uint32 count, const char **rights )
 {
        DEBUG(5, ("init_q_add_acct_rights\n"));
 
        q_q->pol = *hnd;
        init_dom_sid2(&q_q->sid, sid);
-       init_unistr2_array(&q_q->rights, count, rights);
+       
+       q_q->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+       init_unistr4_array( q_q->rights, count, rights );
+       
        q_q->count = count;
 }
 
@@ -2409,7 +2414,7 @@ BOOL lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *q_q, prs_
        if(!prs_uint32("count", ps, depth, &q_q->count))
                return False;
 
-       if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
+       if ( !prs_pointer("rights", ps, depth, (void**)&q_q->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
                return False;
 
        return True;
@@ -2443,10 +2448,14 @@ void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q,
        DEBUG(5, ("init_q_remove_acct_rights\n"));
 
        q_q->pol = *hnd;
+
        init_dom_sid2(&q_q->sid, sid);
+
        q_q->removeall = removeall;
-       init_unistr2_array(&q_q->rights, count, rights);
        q_q->count = count;
+
+       q_q->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+       init_unistr4_array( q_q->rights, count, rights );
 }
 
 
@@ -2470,7 +2479,7 @@ BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q
        if(!prs_uint32("count", ps, depth, &q_q->count))
                return False;
 
-       if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
+       if ( !prs_pointer("rights", ps, depth, (void**)&q_q->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
                return False;
 
        return True;
index bca40a64c829b147086d890a5d271de1a2451f09..faa00d1862421bd260c9fcb0014a7a7dd6ba1990 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Gerald (Jerry) Carter             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
@@ -131,28 +132,6 @@ BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
        return True;
 }
 
-/*******************************************************************
- Reads or writes a LOOKUP_LEVEL structure.
-********************************************************************/
-
-BOOL smb_io_lookup_level(const char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
-{
-       if (level == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_lookup_level");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       if(!prs_uint16("value", ps, depth, &level->value))
-               return False;
-       if(!prs_align(ps))
-               return False;
-
-       return True;
-}
-
 /*******************************************************************
  Gets an enumeration handle from an ENUM_HND structure.
 ********************************************************************/
@@ -302,6 +281,33 @@ void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
  Reads or writes a DOM_SID2 structure.
 ********************************************************************/
 
+BOOL smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2)
+{
+       uint32 data_p;
+
+       /* caputure the pointer value to stream */
+
+       data_p = (uint32) *sid2;
+
+       if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
+               return False;
+
+       /* we're done if there is no data */
+
+       if ( !data_p )
+               return True;
+
+       if (UNMARSHALLING(ps)) {
+               if ( !(*sid2 = PRS_ALLOC_MEM(ps, DOM_SID2, 1)) )
+               return False;
+       }
+
+       return True;
+}
+/*******************************************************************
+ Reads or writes a DOM_SID2 structure.
+********************************************************************/
+
 BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
 {
        if (sid == NULL)
@@ -506,39 +512,6 @@ BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
        return True;
 }
 
-/*******************************************************************
-creates a UNIHDR2 structure.
-********************************************************************/
-
-void init_uni_hdr2(UNIHDR2 *hdr, UNISTR2 *str2)
-{
-       init_uni_hdr(&hdr->unihdr, str2);
-       hdr->buffer = (str2->uni_str_len > 0) ? 1 : 0;
-}
-
-/*******************************************************************
- Reads or writes a UNIHDR2 structure.
-********************************************************************/
-
-BOOL smb_io_unihdr2(const char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
-{
-       if (hdr2 == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_unihdr2");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-
-       if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
-               return False;
-       if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
-               return False;
-
-       return True;
-}
-
 /*******************************************************************
  Inits a UNISTR structure.
 ********************************************************************/
@@ -581,105 +554,69 @@ BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
 }
 
 /*******************************************************************
- Allocate the BUFFER3 memory.
+ Allocate the RPC_DATA_BLOB memory.
 ********************************************************************/
 
-static size_t create_buffer3(BUFFER3 *str, size_t len)
+static size_t create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
 {
        str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
        if (str->buffer == NULL)
-               smb_panic("create_buffer3: talloc fail\n");
+               smb_panic("create_rpc_blob: talloc fail\n");
        return len;
 }
 
 /*******************************************************************
- Inits a BUFFER3 structure from a uint32
+ Inits a RPC_DATA_BLOB structure from a uint32
 ********************************************************************/
 
-void init_buffer3_uint32(BUFFER3 *str, uint32 val)
+void init_rpc_blob_uint32(RPC_DATA_BLOB *str, uint32 val)
 {
        ZERO_STRUCTP(str);
 
        /* set up string lengths. */
-       str->buf_max_len = str->buf_len = create_buffer3(str, sizeof(uint32));
+       str->buf_len = create_rpc_blob(str, sizeof(uint32));
        SIVAL(str->buffer, 0, val);
 }
 
 /*******************************************************************
- Inits a BUFFER3 structure.
+ Inits a RPC_DATA_BLOB structure.
 ********************************************************************/
 
-void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
+void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len)
 {
        ZERO_STRUCTP(str);
 
        /* set up string lengths. */
-       str->buf_max_len = str->buf_len = create_buffer3(str, len*2);
-       rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
+       str->buf_len = create_rpc_blob(str, len*2);
+       rpcstr_push(str->buffer, buf, str->buf_len, STR_TERMINATE);
        
 }
 
 /*******************************************************************
- Inits a BUFFER3 structure from a hex string.
+ Inits a RPC_DATA_BLOB structure from a hex string.
 ********************************************************************/
 
-void init_buffer3_hex(BUFFER3 *str, const char *buf)
+void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf)
 {
        ZERO_STRUCTP(str);
-       str->buf_max_len = str->buf_len = create_buffer3(str, strlen(buf));
-       str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
+       str->buf_len = create_rpc_blob(str, strlen(buf));
+       str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
 }
 
 /*******************************************************************
- Inits a BUFFER3 structure.
+ Inits a RPC_DATA_BLOB structure.
 ********************************************************************/
 
-void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, size_t len)
+void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len)
 {
        ZERO_STRUCTP(str);
 
        /* max buffer size (allocated size) */
        if (buf != NULL) {
-               len = create_buffer3(str, len);
+               len = create_rpc_blob(str, len);
                memcpy(str->buffer, buf, len);
        }
-       str->buf_max_len = len;
-       str->buf_len = buf != NULL ? len : 0;
-}
-
-/*******************************************************************
- Reads or writes a BUFFER3 structure.
-   the uni_max_len member tells you how large the buffer is.
-   the uni_str_len member tells you how much of the buffer is really used.
-********************************************************************/
-
-BOOL smb_io_buffer3(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
-{
-       if (buf3 == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "smb_io_buffer3");
-       depth++;
-
-       if(!prs_align(ps))
-               return False;
-       
-       if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
-               return False;
-
-       if (UNMARSHALLING(ps)) {
-               buf3->buffer = PRS_ALLOC_MEM(ps, unsigned char, buf3->buf_max_len);
-               if (buf3->buffer == NULL)
-                       return False;
-       }
-
-       if(!prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len))
-               return False;
-
-       if(!prs_uint32("buf_len    ", ps, depth, &buf3->buf_len))
-               return False;
-
-       return True;
+       str->buf_len = len;
 }
 
 /*******************************************************************
@@ -707,10 +644,10 @@ BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
 }
 
 /*******************************************************************
- Inits a BUFFER2 structure.
+ Inits a REGVAL_BUFFER structure.
 ********************************************************************/
 
-void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
+void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len)
 {
        ZERO_STRUCTP(str);
 
@@ -723,50 +660,39 @@ void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
                SMB_ASSERT(str->buf_max_len >= str->buf_len);
                str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->buf_max_len);
                if (str->buffer == NULL)
-                       smb_panic("init_buffer2: talloc fail\n");
+                       smb_panic("init_regval_buffer: talloc fail\n");
                memcpy(str->buffer, buf, str->buf_len);
        }
 }
 
 /*******************************************************************
- Reads or writes a BUFFER2 structure.
+ Reads or writes a REGVAL_BUFFER structure.
    the uni_max_len member tells you how large the buffer is.
    the uni_str_len member tells you how much of the buffer is really used.
 ********************************************************************/
 
-BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2)
 {
-       if (buf2 == NULL)
-               return False;
 
-       if (buffer) {
-
-               prs_debug(ps, depth, desc, "smb_io_buffer2");
-               depth++;
+       prs_debug(ps, depth, desc, "smb_io_regval_buffer");
+       depth++;
 
-               if(!prs_align(ps))
-                       return False;
+       if(!prs_align(ps))
+               return False;
                
-               if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
-                       return False;
-               if(!prs_uint32("offset     ", ps, depth, &buf2->offset))
-                       return False;
-               if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
-                       return False;
-
-               /* buffer advanced by indicated length of string
-                  NOT by searching for null-termination */
-
-               if(!prs_buffer2(True, "buffer     ", ps, depth, buf2))
-                       return False;
+       if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
+               return False;
+       if(!prs_uint32("offset     ", ps, depth, &buf2->offset))
+               return False;
+       if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
+               return False;
 
-       } else {
+       /* buffer advanced by indicated length of string
+          NOT by searching for null-termination */
 
-               prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
-               depth++;
-               memset((char *)buf2, '\0', sizeof(*buf2));
+       if(!prs_regval_buffer(True, "buffer     ", ps, depth, buf2))
+               return False;
 
-       }
        return True;
 }
 
@@ -933,6 +859,28 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
                str->uni_max_len++;
 }
 
+/*******************************************************************
+ Inits a UNISTR4 structure.
+********************************************************************/
+
+void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
+{
+       uni4->string = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+       init_unistr2( uni4->string, buf, flags );
+
+       uni4->length = 2 * (uni4->string->uni_str_len);
+       uni4->size   = 2 * (uni4->string->uni_max_len);
+}
+
+void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
+{
+       uni4->string = TALLOC_P( ctx, UNISTR2 );
+       init_unistr2_w( ctx, uni4->string, buf );
+
+       uni4->length = 2 * (uni4->string->uni_str_len);
+       uni4->size   = 2 * (uni4->string->uni_max_len);
+}
+
 /** 
  *  Inits a UNISTR2 structure.
  *  @param  ctx talloc context to allocate string on
@@ -1033,6 +981,57 @@ void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob)
        }
 }
 
+/*******************************************************************
+ UNISTR2* are a little different in that the pointer and the UNISTR2
+ are not necessarily read/written back to back.  So we break it up 
+ into 2 separate functions.
+ See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
+********************************************************************/
+
+BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
+{
+       uint32 data_p;
+
+       /* caputure the pointer value to stream */
+
+       data_p = (uint32) *uni2;
+
+       if ( !prs_uint32("ptr", ps, depth, &data_p ))
+               return False;
+
+       /* we're done if there is no data */
+
+       if ( !data_p )
+               return True;
+
+       if (UNMARSHALLING(ps)) {
+               if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
+                       return False;
+       }
+
+       return True;
+}
+
+/*******************************************************************
+ now read/write the actual UNISTR2.  Memory for the UNISTR2 (but
+ not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
+********************************************************************/
+
+BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
+{
+       /* just return true if there is no pointer to deal with.
+          the memory must have been previously allocated on unmarshalling
+          by prs_unistr2_p() */
+
+       if ( !uni2 )
+               return True;
+
+       /* just pass off to smb_io_unstr2() passing the uni2 address as 
+          the pointer (like you would expect) */
+
+       return smb_io_unistr2( desc, uni2, (uint32)uni2, ps, depth );
+}
+
 /*******************************************************************
  Reads or writes a UNISTR2 structure.
  XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
@@ -1076,32 +1075,114 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *
        return True;
 }
 
+/*******************************************************************
+ now read/write UNISTR4
+********************************************************************/
+
+BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+       if ( !prs_uint16("length", ps, depth, &uni4->length ))
+               return False;
+       if ( !prs_uint16("size", ps, depth, &uni4->size ))
+               return False;
+               
+       if ( !prs_pointer( desc, ps, depth, (void**)&uni4->string, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
+               return False;
+               
+       return True;
+}
+
+/*******************************************************************
+ now read/write UNISTR4 header
+********************************************************************/
+
+BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+       prs_debug(ps, depth, desc, "prs_unistr4_hdr");
+       depth++;
+
+       if ( !prs_uint16("length", ps, depth, &uni4->length) )
+               return False;
+       if ( !prs_uint16("size", ps, depth, &uni4->size) )
+               return False;
+       if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
+               return False;
+               
+       return True;
+}
+
+/*******************************************************************
+ now read/write UNISTR4 string
+********************************************************************/
+
+BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+       prs_debug(ps, depth, desc, "prs_unistr4_str");
+       depth++;
+
+       if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
+               return False;
+               
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes a UNISTR2_ARRAY structure.
+********************************************************************/
 
-/*
+BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
+{
+       unsigned int i;
+
+       prs_debug(ps, depth, desc, "prs_unistr4_array");
+       depth++;
+
+       if(!prs_uint32("count", ps, depth, &array->count))
+               return False;
+
+       if ( array->count == 0 ) 
+               return True;
+       
+       if (UNMARSHALLING(ps)) {
+               if ( !(array->strings = TALLOC_ZERO_ARRAY( get_talloc_ctx(), UNISTR4, array->count)) )
+                       return False;
+       }
+       
+       /* write the headers and then the actual string buffer */
+       
+       for ( i=0; i<array->count; i++ ) {
+               if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
+                       return False;
+       }
+
+       for (i=0;i<array->count;i++) {
+               if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) ) 
+                       return False;
+       }
+       
+       return True;
+}
+
+/********************************************************************
   initialise a UNISTR_ARRAY from a char**
-*/
-BOOL init_unistr2_array(UNISTR2_ARRAY *array, 
-                      uint32 count, const char **strings)
+********************************************************************/
+
+BOOL init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
 {
        unsigned int i;
 
        array->count = count;
-       array->ref_id = count?1:0;
-       if (array->count == 0) {
+
+       if ( array->count == 0 )
                return True;
-       }
 
-       array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR2_ARRAY_EL, count );
-       if (!array->strings) {
+       /* allocate memory for the array of UNISTR4 objects */
+
+       if ( !(array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR4, count )) )
                return False;
-       }
 
-       for (i=0;i<count;i++) {
-               init_unistr2(&array->strings[i].string, strings[i], UNI_FLAGS_NONE);
-               array->strings[i].size = array->strings[i].string.uni_max_len*2;
-               array->strings[i].length = array->strings[i].size;
-               array->strings[i].ref_id = 1;
-       }
+       for ( i=0; i<count; i++ ) 
+               init_unistr4( &array->strings[i], strings[i], STR_TERMINATE );
 
        return True;
 }
@@ -1153,55 +1234,6 @@ BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockou
        return True;
 }
 
-/*******************************************************************
- Reads or writes a UNISTR2_ARRAY structure.
-********************************************************************/
-BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps, int depth)
-{
-       unsigned int i;
-
-       prs_debug(ps, depth, desc, "smb_io_unistr2_array");
-       depth++;
-
-       if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
-               return False;
-
-       if (! array->ref_id) {
-               return True;
-       }
-
-       if(!prs_uint32("count", ps, depth, &array->count))
-               return False;
-
-       if (array->count == 0) {
-               return True;
-       }
-
-       if (UNMARSHALLING(ps)) {
-               array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR2_ARRAY_EL, array->count );
-       }
-       if (! array->strings) {
-               return False;
-       }
-
-       for (i=0;i<array->count;i++) {
-               if(!prs_uint16("length", ps, depth, &array->strings[i].length))
-                       return False;
-               if(!prs_uint16("size", ps, depth, &array->strings[i].size))
-                       return False;
-               if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
-                       return False;
-       }
-
-       for (i=0;i<array->count;i++) {
-               if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth)) 
-                       return False;
-       }
-       
-       return True;
-}
-
-
 /*******************************************************************
  Inits a DOM_RID2 structure.
 ********************************************************************/
@@ -1748,23 +1780,30 @@ BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
 }
 
 /*******************************************************************
-reads or writes a BUFFER4 structure.
+reads or writes a RPC_DATA_BLOB structure.
 ********************************************************************/
 
-BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "smb_io_buffer4");
+       prs_debug(ps, depth, desc, "smb_io_rpc_blob");
        depth++;
 
        prs_align(ps);
-       prs_uint32("buf_len", ps, depth, &buf4->buf_len);
+       if ( !prs_uint32("buf_len", ps, depth, &blob->buf_len) )
+               return False;
+
+       if ( blob->buf_len == 0 )
+               return True;
+
        if (UNMARSHALLING(ps)) {
-               buf4->buffer = PRS_ALLOC_MEM(ps, uint8, buf4->buf_len);
-               if (!buf4->buffer) {
+               blob->buffer = PRS_ALLOC_MEM(ps, uint8, blob->buf_len);
+               if (!blob->buffer) {
                        return False;
                }
        }
-       prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
+
+       if ( !prs_uint8s(True, "buffer", ps, depth, blob->buffer, blob->buf_len) )
+               return False;
 
        return True;
 }
@@ -1797,3 +1836,22 @@ BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
 
        return True;
 }
+
+/*******************************************************************
+return the length of a UNISTR string.
+********************************************************************/  
+
+uint32 str_len_uni(UNISTR *source)
+{
+       uint32 i=0;
+
+       if (!source->buffer)
+               return 0;
+
+       while (source->buffer[i])
+               i++;
+
+       return i;
+}
+
+
index d7bdca4df995a763b80689a891cf3002ace02cbe..ed95656fdae0f7847cf76be35aa719c4914384ab 100644 (file)
@@ -1972,8 +1972,7 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
                             info->hdr_oem_info.buffer, ps, depth))
                 return False;
 
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
                 return False;
 
        if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, 
@@ -2021,8 +2020,7 @@ static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
        if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
                             info->hdr_grp_desc.buffer, ps, depth))
                 return False;
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
                 return False;
 
        return True;
@@ -2274,8 +2272,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
        if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
                 return False;
 
-       if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
-                            info->ptr_logon_hrs, ps, depth))
+       if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
                 return False;
        prs_align(ps);
        if (!smb_io_unistr2("uni_comment", &info->uni_comment,
@@ -2316,8 +2313,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
                         return False;
                ps->data_offset = old_offset + len;
        }
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
                 return False;
        prs_align(ps);
        if (!smb_io_unistr2("uni_profile", &info->uni_profile,
@@ -2436,8 +2432,7 @@ static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
        if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
                             info->hdr_als_name.buffer, ps, depth))
                 return False;
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
                 return False;
 
        if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
@@ -2596,8 +2591,7 @@ static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
        if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
                return False;
 
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
 
                return False;
 
@@ -2831,8 +2825,7 @@ static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
                if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
                        return False;
 
-       if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
-                            info->hdr_sec_desc.buffer, ps, depth))
+       if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
                 return False;
 
        return True;
index 4b78d373bab93ae0bdbcdc02318e2b01e6cd3917..1b9ac51c61364e0655e0a0dc67f34247300139ae 100644 (file)
@@ -588,6 +588,37 @@ BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
        return True;
 }
 
+/*******************************************************************
+ Stream a uint16* (allocate memory if unmarshalling)
+ ********************************************************************/
+
+BOOL prs_pointer( const char *name, prs_struct *ps, int depth, 
+                 void **data, size_t data_size,
+                 BOOL(*prs_fn)(const char*, prs_struct*, int, void*) )
+{
+       uint32 data_p;
+
+       /* caputure the pointer value to stream */
+
+       data_p = (uint32) *data;
+
+       if ( !prs_uint32("ptr", ps, depth, &data_p ))
+               return False;
+
+       /* we're done if there is no data */
+
+       if ( !data_p )
+               return True;
+
+       if (UNMARSHALLING(ps)) {
+               if ( !(*data = PRS_ALLOC_MEM_VOID(ps, data_size)) )
+                       return False;
+       }
+
+       return prs_fn(name, ps, depth, *data);
+}
+
+
 /*******************************************************************
  Stream a uint16.
  ********************************************************************/
@@ -598,12 +629,12 @@ BOOL prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)
        if (q == NULL)
                return False;
 
-    if (UNMARSHALLING(ps)) {
+       if (UNMARSHALLING(ps)) {
                if (ps->bigendian_data)
                        *data16 = RSVAL(q,0);
                else
                        *data16 = SVAL(q,0);
-    } else {
+       } else {
                if (ps->bigendian_data)
                        RSSVAL(q,0,*data16);
                else
@@ -916,28 +947,28 @@ BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
  in byte chars. String is in little-endian format.
  ********************************************************************/
 
-BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER2 *str)
+BOOL prs_regval_buffer(BOOL charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf)
 {
        char *p;
-       char *q = prs_mem_get(ps, str->buf_len);
+       char *q = prs_mem_get(ps, buf->buf_len);
        if (q == NULL)
                return False;
 
        if (UNMARSHALLING(ps)) {
-               if (str->buf_len > str->buf_max_len) {
+               if (buf->buf_len > buf->buf_max_len) {
                        return False;
                }
-               if ( str->buf_max_len ) {
-                       str->buffer = PRS_ALLOC_MEM(ps, uint16, str->buf_max_len);
-                       if ( str->buffer == NULL )
+               if ( buf->buf_max_len ) {
+                       buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len);
+                       if ( buf->buffer == NULL )
                                return False;
                }
        }
 
-       p = (char *)str->buffer;
+       p = (char *)buf->buffer;
 
-       dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len/2);
-       ps->data_offset += str->buf_len;
+       dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2);
+       ps->data_offset += buf->buf_len;
 
        return True;
 }
index a67a3973b95df8e8e35eda5d1e588fe85446e39e..a51b4269e3ad8c85981f8ae020805b335e4a8789 100644 (file)
@@ -6,7 +6,8 @@
  *  Copyright (C) Paul Ashton                       1997.
  *  Copyright (C) Marc Jacobsen                     1999.
  *  Copyright (C) Simo Sorce                        2000.
- *  Copyright (C) Gerald Carter                     2002.
+ *  Copyright (C) Jeremy Cooper                     2004
+ *  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
 #define DBGC_CLASS DBGC_RPC_PARSE
 
 /*******************************************************************
- Fill in a BUFFER2 for the data given a REGISTRY_VALUE
+ Fill in a REGVAL_BUFFER for the data given a REGISTRY_VALUE
  *******************************************************************/
 
-static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
+static uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val )
 {
        uint32          real_size = 0;
        
@@ -40,151 +41,72 @@ static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
                return 0;
                
        real_size = regval_size(val);
-       init_buffer2( buf2, (unsigned char*)regval_data_p(val), real_size );
+       init_regval_buffer( buf2, (unsigned char*)regval_data_p(val), real_size );
 
        return real_size;
 }
 
 /*******************************************************************
- Inits a structure.
+ Inits a hive connect request structure
 ********************************************************************/
 
-void init_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
-                               uint16 unknown_0, uint32 level)
+void init_reg_q_open_hive( REG_Q_OPEN_HIVE *q_o, uint32 access_desired )
 {
-       q_o->ptr = 1;
-       q_o->unknown_0 = unknown_0;
-       q_o->unknown_1 = 0x0; /* random - changes */
-       q_o->level = level;
+       
+       q_o->server = TALLOC_P( get_talloc_ctx(), uint16);
+       *q_o->server = 0x1;
+       
+       q_o->access = access_desired;
 }
 
 /*******************************************************************
-reads or writes a structure.
+Marshalls a hive connect request
 ********************************************************************/
 
-BOOL reg_io_q_open_hkcr(const char *desc,  REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hive(const char *desc, REG_Q_OPEN_HIVE *q_u,
+                        prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
+       prs_debug(ps, depth, desc, "reg_io_q_open_hive");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+       if(!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
                return False;
 
-       if (r_q->ptr != 0) {
-               if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
-                       return False;
-               if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
-                       return False;
-               if(!prs_uint32("level    ", ps, depth, &r_q->level))
-                       return False;
-       }
+       if(!prs_uint32("access", ps, depth, &q_u->access))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+Unmarshalls a hive connect response
 ********************************************************************/
 
-BOOL reg_io_r_open_hkcr(const char *desc,  REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hive(const char *desc,  REG_R_OPEN_HIVE *r_u,
+                        prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
+       prs_debug(ps, depth, desc, "reg_io_r_open_hive");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
-               return False;
-
-       if(!prs_werror("status", ps, depth, &r_r->status))
-               return False;
-
-       return True;
-}
-
-/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-void init_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
-                         uint16 unknown_0, uint32 access_mask)
-{
-       q_o->ptr = 1;
-       q_o->unknown_0 = unknown_0;
-       q_o->unknown_1 = 0x0;   /* random - changes */
-       q_o->access_mask = access_mask;
-
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL reg_io_q_open_hklm(const char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
-                       int depth)
-{
-       if (r_q == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!prs_uint32("ptr      ", ps, depth, &(r_q->ptr)))
-               return False;
-       if (r_q->ptr != 0)
-       {
-               if (!prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0)))
-                       return False;
-               if (!prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)))
-                       return False;
-               if (!prs_uint32("access_mask", ps, depth, &(r_q->access_mask)))
-                       return False;
-       }
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL reg_io_r_open_hklm(const char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
-                       int depth)
-{
-       if (r_r == NULL)
-               return False;
-
-       prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
-       depth++;
-
-       if (!prs_align(ps))
-               return False;
-
-       if (!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
                return False;
 
-       if (!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
 }
 
-
-
-
 /*******************************************************************
  Inits a structure.
 ********************************************************************/
@@ -198,9 +120,9 @@ void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_flush_key(const char *desc,  REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_flush_key(const char *desc,  REG_Q_FLUSH_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_flush_key");
@@ -209,19 +131,20 @@ BOOL reg_io_q_flush_key(const char *desc,  REG_Q_FLUSH_KEY *r_q, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+Unmarshalls a registry key flush response
 ********************************************************************/
 
-BOOL reg_io_r_flush_key(const char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_flush_key(const char *desc,  REG_R_FLUSH_KEY *r_u,
+                        prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_flush_key");
@@ -230,7 +153,7 @@ BOOL reg_io_r_flush_key(const char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -240,12 +163,14 @@ BOOL reg_io_r_flush_key(const char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps,
 reads or writes SEC_DESC_BUF and SEC_DATA structures.
 ********************************************************************/
 
-static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DESC_BUF *data, prs_struct *ps, int depth)
+static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
+                              SEC_DESC_BUF *data, prs_struct *ps, int depth)
 {
        if (ptr != 0) {
                uint32 hdr_offset;
                uint32 old_offset;
-               if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset))
+               if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth,
+                                     &hdr_offset))
                        return False;
 
                old_offset = prs_offset(ps);
@@ -256,14 +181,16 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DES
                }
 
                if (ptr3 == NULL || *ptr3 != 0) {
-                       if(!sec_io_desc_buf("data   ", &data, ps, depth)) /* JRA - this line is probably wrong... */
+                       /* JRA - this next line is probably wrong... */
+                       if(!sec_io_desc_buf("data   ", &data, ps, depth))
                                return False;
                }
 
-               if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
-                                  data->max_len, data->len))
+               if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth,
+                                      hdr_offset, data->max_len, data->len))
                                return False;
-               if(!prs_set_offset(ps, old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
+               if(!prs_set_offset(ps, old_offset + data->len +
+                                      sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
                        return False;
 
                if(!prs_align(ps))
@@ -274,28 +201,25 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DES
 }
 
 /*******************************************************************
- Inits a structure.
+ Inits a registry key create request
 ********************************************************************/
 
 void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
-                               char *name, char *class, SEC_ACCESS *sam_access,
-                               SEC_DESC_BUF *sec_buf)
+                           char *name, char *class, uint32 access_desired,
+                           SEC_DESC_BUF *sec_buf)
 {
        ZERO_STRUCTP(q_c);
 
        memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
 
-       init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
-       init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
 
-       init_unistr2(&q_c->uni_class, class, UNI_STR_TERMINATE);
-       init_uni_hdr(&q_c->hdr_class, &q_c->uni_class);
+       init_unistr4( &q_c->name, name, UNI_STR_TERMINATE );
+       init_unistr4( &q_c->class, class, UNI_STR_TERMINATE );
 
-       q_c->reserved = 0x00000000;
-       memcpy(&q_c->sam_access, sam_access, sizeof(q_c->sam_access));
+       q_c->access = access_desired;
 
-       q_c->ptr1 = 1;
-       q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
+       q_c->sec_info = TALLOC_P( get_talloc_ctx(), uint32 );
+       *q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
 
        q_c->data = sec_buf;
        q_c->ptr2 = 1;
@@ -305,12 +229,13 @@ void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
 }
 
 /*******************************************************************
-reads or writes a structure.
+Marshalls a registry key create request
 ********************************************************************/
 
-BOOL reg_io_q_create_key(const char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_key(const char *desc,  REG_Q_CREATE_KEY *q_u,
+                         prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_create_key");
@@ -319,54 +244,49 @@ BOOL reg_io_q_create_key(const char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *p
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
                return False;
 
-       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4 ("name", ps, depth, &q_u->name))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+       if(!prs_unistr4 ("class", ps, depth, &q_u->class))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("reserved", ps, depth, &r_q->reserved))
+       if(!prs_uint32("reserved", ps, depth, &q_u->reserved))
                return False;
-       if(!sec_io_access("sam_access", &r_q->sam_access, ps, depth))
+       if(!prs_uint32("access", ps, depth, &q_u->access))
                return False;
 
-       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+       if(!prs_pointer("sec_info", ps, depth, (void**)&q_u->sec_info, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
 
-       if (r_q->ptr1 != 0) {
-               if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
-                       return False;
-       }
-
-       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+       if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
                return False;
-       if(!reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth))
+       if(!reg_io_hdrbuf_sec(q_u->ptr2, &q_u->ptr3, &q_u->hdr_sec, q_u->data,
+                             ps, depth))
                return False;
 
-       if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+#if 0
+       if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
                return False;
+#endif
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+Unmarshalls a registry key create response
 ********************************************************************/
 
-BOOL reg_io_r_create_key(const char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_create_key(const char *desc,  REG_R_CREATE_KEY *r_u,
+                         prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_create_key");
@@ -375,12 +295,12 @@ BOOL reg_io_r_create_key(const char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *p
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_r->key_pol, ps, depth))
+       if(!smb_io_pol_hnd("", &r_u->key_pol, ps, depth))
                return False;
-       if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+       if(!prs_uint32("unknown", ps, depth, &r_u->unknown))
                return False;
 
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -392,23 +312,22 @@ BOOL reg_io_r_create_key(const char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *p
 ********************************************************************/
 
 void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
-                               char *name)
+                           char *name)
 {
        ZERO_STRUCTP(q_c);
 
        memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
-
-       init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
-       init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+       init_unistr4(&q_c->name, name, UNI_STR_TERMINATE);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_delete_val(const char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *q_u,
+                         prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_delete_val");
@@ -417,12 +336,10 @@ BOOL reg_io_q_delete_val(const char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
                return False;
 
-       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &q_u->name))
                return False;
        if(!prs_align(ps))
                return False;
@@ -435,9 +352,10 @@ BOOL reg_io_q_delete_val(const char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_delete_val(const char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_val(const char *desc,  REG_R_DELETE_VALUE *r_u,
+                         prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_delete_val");
@@ -446,7 +364,7 @@ BOOL reg_io_r_delete_val(const char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -457,23 +375,23 @@ BOOL reg_io_r_delete_val(const char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct
 ********************************************************************/
 
 void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
-                               char *name)
+                           char *name)
 {
        ZERO_STRUCTP(q_c);
 
        memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
 
-       init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
-       init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+       init_unistr4(&q_c->name, name, UNI_STR_TERMINATE);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_delete_key(const char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_key(const char *desc,  REG_Q_DELETE_KEY *q_u,
+                         prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_delete_key");
@@ -482,12 +400,10 @@ BOOL reg_io_q_delete_key(const char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *p
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
                return False;
 
-       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("", ps, depth, &q_u->name))
                return False;
        if(!prs_align(ps))
                return False;
@@ -499,9 +415,9 @@ BOOL reg_io_q_delete_key(const char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *p
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_delete_key(const char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_key(const char *desc,  REG_R_DELETE_KEY *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_delete_key");
@@ -510,7 +426,7 @@ BOOL reg_io_r_delete_key(const char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *p
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -520,21 +436,21 @@ BOOL reg_io_r_delete_key(const char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *p
  Inits a structure.
 ********************************************************************/
 
-void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, UNISTR2 *uni2)
+void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, const char *class)
 {
        ZERO_STRUCTP(q_o);
 
        memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
-       init_uni_hdr(&q_o->hdr_class, uni2);
+       init_unistr4(&q_o->class, class, UNI_STR_TERMINATE);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_query_key(const char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_query_key(const char *desc,  REG_Q_QUERY_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_query_key");
@@ -543,11 +459,9 @@ BOOL reg_io_q_query_key(const char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
-               return False;
-       if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
-       if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+       if(!prs_unistr4("class", ps, depth, &q_u->class))
                return False;
 
        if(!prs_align(ps))
@@ -561,9 +475,9 @@ BOOL reg_io_q_query_key(const char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps,
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_query_key(const char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_query_key(const char *desc,  REG_R_QUERY_KEY *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_query_key");
@@ -572,32 +486,30 @@ BOOL reg_io_r_query_key(const char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_unihdr ("", &r_r->hdr_class, ps, depth))
-               return False;
-       if(!smb_io_unistr2("", &r_r->uni_class, r_r->hdr_class.buffer, ps, depth))
+       if(!prs_unistr4("class", ps, depth, &r_u->class))
                return False;
 
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("num_subkeys   ", ps, depth, &r_r->num_subkeys))
+       if(!prs_uint32("num_subkeys   ", ps, depth, &r_u->num_subkeys))
                return False;
-       if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen))
+       if(!prs_uint32("max_subkeylen ", ps, depth, &r_u->max_subkeylen))
                return False;
-       if(!prs_uint32("reserved      ", ps, depth, &r_r->reserved))
+       if(!prs_uint32("reserved      ", ps, depth, &r_u->reserved))
                return False;
-       if(!prs_uint32("num_values    ", ps, depth, &r_r->num_values))
+       if(!prs_uint32("num_values    ", ps, depth, &r_u->num_values))
                return False;
-       if(!prs_uint32("max_valnamelen", ps, depth, &r_r->max_valnamelen))
+       if(!prs_uint32("max_valnamelen", ps, depth, &r_u->max_valnamelen))
                return False;
-       if(!prs_uint32("max_valbufsize", ps, depth, &r_r->max_valbufsize))
+       if(!prs_uint32("max_valbufsize", ps, depth, &r_u->max_valbufsize))
                return False;
-       if(!prs_uint32("sec_desc      ", ps, depth, &r_r->sec_desc))
+       if(!prs_uint32("sec_desc      ", ps, depth, &r_u->sec_desc))
                return False;
-       if(!smb_io_time("mod_time     ", &r_r->mod_time, ps, depth))
+       if(!smb_io_time("mod_time     ", &r_u->mod_time, ps, depth))
                return False;
 
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -607,7 +519,7 @@ BOOL reg_io_r_query_key(const char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps,
  Inits a structure.
 ********************************************************************/
 
-void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
+void init_reg_q_getversion(REG_Q_GETVERSION *q_o, POLICY_HND *hnd)
 {
        memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
 }
@@ -617,18 +529,18 @@ void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_unknown_1a(const char *desc,  REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_getversion(const char *desc,  REG_Q_GETVERSION *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_q_unknown_1a");
+       prs_debug(ps, depth, desc, "reg_io_q_getversion");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
 
        return True;
@@ -638,20 +550,20 @@ BOOL reg_io_q_unknown_1a(const char *desc,  REG_Q_UNKNOWN_1A *r_q, prs_struct *p
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_unknown_1a(const char *desc,  REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_getversion(const char *desc,  REG_R_GETVERSION *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_unknown_1a");
+       prs_debug(ps, depth, desc, "reg_io_r_getversion");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+       if(!prs_uint32("unknown", ps, depth, &r_u->unknown))
                return False;
-       if(!prs_werror("status" , ps, depth, &r_r->status))
+       if(!prs_werror("status" , ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -662,26 +574,24 @@ BOOL reg_io_r_unknown_1a(const char *desc,  REG_R_UNKNOWN_1A *r_r, prs_struct *p
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_save_key(const char *desc,  REG_Q_SAVE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_restore_key(const char *desc,  REG_Q_RESTORE_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_q_save_key");
+       prs_debug(ps, depth, desc, "reg_io_q_restore_key");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
 
-       if(!smb_io_unihdr ("hdr_file", &r_q->hdr_file, ps, depth))
-               return False;
-       if(!smb_io_unistr2("uni_file", &r_q->uni_file, r_q->hdr_file.buffer, ps, depth))
+       if(!prs_unistr4("filename", ps, depth, &q_u->filename))
                return False;
 
-       if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
+       if(!prs_uint32("flags", ps, depth, &q_u->flags))
                return False;
 
        return True;
@@ -691,61 +601,48 @@ BOOL reg_io_q_save_key(const char *desc,  REG_Q_SAVE_KEY *r_q, prs_struct *ps, i
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_save_key(const char *desc,  REG_R_SAVE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_restore_key(const char *desc,  REG_R_RESTORE_KEY *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_save_key");
+       prs_debug(ps, depth, desc, "reg_io_r_restore_key");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status" , ps, depth, &r_r->status))
+       if(!prs_werror("status" , ps, depth, &r_u->status))
                return False;
 
        return True;
 }
 
-/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
-                               uint16 unknown_0, uint32 access_mask)
-{
-       q_o->ptr = 1;
-       q_o->unknown_0 = unknown_0;
-       q_o->unknown_1 = 0x0; /* random - changes */
-       q_o->access_mask = access_mask;
-}
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_open_hku(const char *desc,  REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_save_key(const char *desc,  REG_Q_SAVE_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_q_open_hku");
+       prs_debug(ps, depth, desc, "reg_io_q_save_key");
        depth++;
 
        if(!prs_align(ps))
                return False;
-       
-       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
-       if (r_q->ptr != 0) {
-               if(!prs_uint16("unknown_0   ", ps, depth, &r_q->unknown_0))
-                       return False;
-               if(!prs_uint16("unknown_1   ", ps, depth, &r_q->unknown_1))
-                       return False;
-               if(!prs_uint32("access_mask ", ps, depth, &r_q->access_mask))
-                       return False;
-       }
+
+       if(!prs_unistr4("filename", ps, depth, &q_u->filename))
+               return False;
+
+#if 0  /* reg_io_sec_attr() */
+       if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
+               return False;
+#endif
 
        return True;
 }
@@ -754,21 +651,18 @@ BOOL reg_io_q_open_hku(const char *desc,  REG_Q_OPEN_HKU *r_q, prs_struct *ps, i
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_open_hku(const char *desc,  REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_save_key(const char *desc,  REG_R_SAVE_KEY *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_open_hku");
+       prs_debug(ps, depth, desc, "reg_io_r_save_key");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
-               return False;
-
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status" , ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -814,7 +708,7 @@ reads or writes a structure.
 
 BOOL reg_io_r_close(const char *desc,  REG_R_CLOSE *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_close");
@@ -838,24 +732,25 @@ BOOL reg_io_r_close(const char *desc,  REG_R_CLOSE *r_u, prs_struct *ps, int dep
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf)
+void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_u, POLICY_HND *pol,
+                            uint32 sec_info, SEC_DESC_BUF *sec_desc_buf)
 {
-       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       q_i->sec_info = DACL_SECURITY_INFORMATION;
+       q_u->sec_info = sec_info;
 
-       q_i->ptr = 1;
-       init_buf_hdr(&q_i->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
-       q_i->data = sec_desc_buf;
+       q_u->ptr = 1;
+       init_buf_hdr(&q_u->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
+       q_u->data = sec_desc_buf;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_set_key_sec(const char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_key_sec(const char *desc,  REG_Q_SET_KEY_SEC *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
@@ -864,15 +759,15 @@ BOOL reg_io_q_set_key_sec(const char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
 
-       if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+       if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
                return False;
-       if(!prs_uint32("ptr    ", ps, depth, &r_q->ptr))
+       if(!prs_uint32("ptr    ", ps, depth, &q_u->ptr))
                return False;
 
-       if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+       if(!reg_io_hdrbuf_sec(q_u->ptr, NULL, &q_u->hdr_sec, q_u->data, ps, depth))
                return False;
 
        return True;
@@ -882,9 +777,9 @@ BOOL reg_io_q_set_key_sec(const char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
@@ -893,7 +788,7 @@ BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status", ps, depth, &r_q->status))
+       if(!prs_werror("status", ps, depth, &q_u->status))
                return False;
 
        return True;
@@ -904,28 +799,27 @@ BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, 
-                               uint32 sec_buf_size, SEC_DESC_BUF *psdb)
+void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_u, POLICY_HND *pol, 
+                            uint32 sec_info, uint32 sec_buf_size,
+                            SEC_DESC_BUF *psdb)
 {
-       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       q_i->sec_info = OWNER_SECURITY_INFORMATION |
-                       GROUP_SECURITY_INFORMATION |
-                       DACL_SECURITY_INFORMATION;
+       q_u->sec_info = sec_info;
 
-       q_i->ptr = psdb != NULL ? 1 : 0;
-       q_i->data = psdb;
+       q_u->ptr = psdb != NULL ? 1 : 0;
+       q_u->data = psdb;
 
-       init_buf_hdr(&q_i->hdr_sec, sec_buf_size, 0);
+       init_buf_hdr(&q_u->hdr_sec, sec_buf_size, 0);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_get_key_sec(const char *desc,  REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_get_key_sec(const char *desc,  REG_Q_GET_KEY_SEC *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_get_key_sec");
@@ -934,15 +828,15 @@ BOOL reg_io_q_get_key_sec(const char *desc,  REG_Q_GET_KEY_SEC *r_q, prs_struct
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
 
-       if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+       if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
                return False;
-       if(!prs_uint32("ptr     ", ps, depth, &r_q->ptr))
+       if(!prs_uint32("ptr     ", ps, depth, &q_u->ptr))
                return False;
 
-       if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+       if(!reg_io_hdrbuf_sec(q_u->ptr, NULL, &q_u->hdr_sec, q_u->data, ps, depth))
                return False;
 
        return True;
@@ -968,9 +862,9 @@ makes a structure.
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_get_key_sec(const char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_get_key_sec(const char *desc,  REG_R_GET_KEY_SEC *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_get_key_sec");
@@ -979,19 +873,19 @@ BOOL reg_io_r_get_key_sec(const char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct
        if(!prs_align(ps))
                return False;
        
-       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+       if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
                return False;
 
-       if (r_q->ptr != 0) {
-               if(!smb_io_hdrbuf("", &r_q->hdr_sec, ps, depth))
+       if (q_u->ptr != 0) {
+               if(!smb_io_hdrbuf("", &q_u->hdr_sec, ps, depth))
                        return False;
-               if(!sec_io_desc_buf("", &r_q->data, ps, depth))
+               if(!sec_io_desc_buf("", &q_u->data, ps, depth))
                        return False;
                if(!prs_align(ps))
                        return False;
        }
 
-       if(!prs_werror("status", ps, depth, &r_q->status))
+       if(!prs_werror("status", ps, depth, &q_u->status))
                return False;
 
        return True;
@@ -1001,29 +895,29 @@ BOOL reg_io_r_get_key_sec(const char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct
 makes a structure.
 ********************************************************************/
 
-BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name)
+BOOL init_reg_q_info(REG_Q_INFO *q_u, POLICY_HND *pol, const char *val_name,
+                     REGVAL_BUFFER *value_output)
 {
-        if (q_i == NULL)
+        if (q_u == NULL)
                 return False;
 
-        q_i->pol = *pol;
+        q_u->pol = *pol;
 
-        init_unistr2(&q_i->uni_type, val_name, UNI_STR_TERMINATE);
-        init_uni_hdr(&q_i->hdr_type, &q_i->uni_type);
+        init_unistr4(&q_u->name, val_name, UNI_STR_TERMINATE);
 
-        q_i->ptr_reserved = 1;
-        q_i->ptr_buf = 1;
+        q_u->ptr_reserved = 1;
+        q_u->ptr_buf = 1;
 
-        q_i->ptr_bufsize = 1;
-        q_i->bufsize = 0;
-        q_i->buf_unk = 0;
+        q_u->ptr_bufsize = 1;
+        q_u->bufsize = value_output->buf_max_len;
+        q_u->buf_unk = 0;
 
-        q_i->unk1 = 0;
-        q_i->ptr_buflen = 1;
-        q_i->buflen = 0;
+        q_u->unk1 = 0;
+        q_u->ptr_buflen = 1;
+        q_u->buflen = value_output->buf_max_len; 
 
-        q_i->ptr_buflen2 = 1;
-        q_i->buflen2 = 0;
+        q_u->ptr_buflen2 = 1;
+        q_u->buflen2 = 0;
 
         return True;
 }
@@ -1032,9 +926,9 @@ BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name)
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_info(const char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_info(const char *desc,  REG_Q_INFO *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_info");
@@ -1043,43 +937,41 @@ BOOL reg_io_q_info(const char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
-               return False;
-       if(!smb_io_unihdr ("", &r_q->hdr_type, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
-       if(!smb_io_unistr2("", &r_q->uni_type, r_q->hdr_type.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &q_u->name))
                return False;
 
        if(!prs_align(ps))
                return False;
        
-       if(!prs_uint32("ptr_reserved", ps, depth, &(r_q->ptr_reserved)))
+       if(!prs_uint32("ptr_reserved", ps, depth, &(q_u->ptr_reserved)))
                return False;
 
-       if(!prs_uint32("ptr_buf", ps, depth, &(r_q->ptr_buf)))
+       if(!prs_uint32("ptr_buf", ps, depth, &(q_u->ptr_buf)))
                return False;
 
-       if(r_q->ptr_buf) {
-               if(!prs_uint32("ptr_bufsize", ps, depth, &(r_q->ptr_bufsize)))
+       if(q_u->ptr_buf) {
+               if(!prs_uint32("ptr_bufsize", ps, depth, &(q_u->ptr_bufsize)))
                        return False;
-               if(!prs_uint32("bufsize", ps, depth, &(r_q->bufsize)))
+               if(!prs_uint32("bufsize", ps, depth, &(q_u->bufsize)))
                        return False;
-               if(!prs_uint32("buf_unk", ps, depth, &(r_q->buf_unk)))
+               if(!prs_uint32("buf_unk", ps, depth, &(q_u->buf_unk)))
                        return False;
        }
 
-       if(!prs_uint32("unk1", ps, depth, &(r_q->unk1)))
+       if(!prs_uint32("unk1", ps, depth, &(q_u->unk1)))
                return False;
 
-       if(!prs_uint32("ptr_buflen", ps, depth, &(r_q->ptr_buflen)))
+       if(!prs_uint32("ptr_buflen", ps, depth, &(q_u->ptr_buflen)))
                return False;
 
-       if (r_q->ptr_buflen) {
-               if(!prs_uint32("buflen", ps, depth, &(r_q->buflen)))
+       if (q_u->ptr_buflen) {
+               if(!prs_uint32("buflen", ps, depth, &(q_u->buflen)))
                        return False;
-               if(!prs_uint32("ptr_buflen2", ps, depth, &(r_q->ptr_buflen2)))
+               if(!prs_uint32("ptr_buflen2", ps, depth, &(q_u->ptr_buflen2)))
                        return False;
-               if(!prs_uint32("buflen2", ps, depth, &(r_q->buflen2)))
+               if(!prs_uint32("buflen2", ps, depth, &(q_u->buflen2)))
                        return False;
        }
 
@@ -1091,72 +983,36 @@ BOOL reg_io_q_info(const char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth
  New version to replace older init_reg_r_info()
 ********************************************************************/
 
-BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
+BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_u,
                     REGISTRY_VALUE *val, WERROR status)
 {
-       uint32          buf_len = 0;
-       BUFFER2         buf2;
+       uint32                  buf_len = 0;
+       REGVAL_BUFFER           buf2;
                
-       if(r_r == NULL)
+       if( !r_u || !val )
                return False;
        
-       if ( !val )
-               return False;
-  
-       r_r->ptr_type = 1;
-       r_r->type = val->type;
+       r_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->type = val->type;
 
-       /* if include_keyval is not set, don't send the key value, just
-          the buflen data. probably used by NT5 to allocate buffer space - SK */
-
-       if ( include_keyval ) {
-               r_r->ptr_uni_val = 1;
-               buf_len = reg_init_buffer2( &r_r->uni_val, val );
+       buf_len = reg_init_regval_buffer( &buf2, val );
        
-       }
-       else {
-               /* dummy buffer used so we can get the size */
-               r_r->ptr_uni_val = 0;
-               buf_len = reg_init_buffer2( &buf2, val );
-       }
-
-       r_r->ptr_max_len = 1;
-       r_r->buf_max_len = buf_len;
-
-       r_r->ptr_len = 1;
-       r_r->buf_len = buf_len;
-
-       r_r->status = status;
-
-       return True;
-}
-
-/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
-                    BUFFER2* buf, uint32 type, WERROR status)
-{
-       if(r_r == NULL)
-               return False;
-  
-       r_r->ptr_type = 1;
-       r_r->type = type;
+       r_u->buf_max_len = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->buf_max_len = buf_len;
 
+       r_u->buf_len = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->buf_len = buf_len;
+       
        /* if include_keyval is not set, don't send the key value, just
           the buflen data. probably used by NT5 to allocate buffer space - SK */
 
-       r_r->ptr_uni_val = include_keyval ? 1:0;
-       r_r->uni_val = *buf;
-
-       r_r->ptr_max_len = 1;
-       r_r->buf_max_len = r_r->uni_val.buf_max_len;
-
-       r_r->ptr_len = 1;
-       r_r->buf_len = r_r->uni_val.buf_len;
+       if ( include_keyval ) {
+               r_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+               /* steal the memory */
+               *r_u->value = buf2;
+       }
 
-       r_r->status = status;
+       r_u->status = status;
 
        return True;
 }
@@ -1165,9 +1021,9 @@ BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_info");
@@ -1176,41 +1032,20 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
        if(!prs_align(ps))
                return False;
        
-       if(!prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type)))
+       if ( !prs_pointer("type", ps, depth, (void**)&r_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
 
-       if (r_r->ptr_type != 0) {
-               if(!prs_uint32("type", ps, depth, &r_r->type))
-                       return False;
-       }
-
-       if(!prs_uint32("ptr_uni_val", ps, depth, &(r_r->ptr_uni_val)))
+       if ( !prs_pointer("value", ps, depth, (void**)&r_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
                return False;
-
-       if(r_r->ptr_uni_val != 0) {
-               if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
-                       return False;
-       }
-
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len)))
+       if ( !prs_pointer("buf_max_len", ps, depth, (void**)&r_u->buf_max_len, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-
-       if (r_r->ptr_max_len != 0) {
-               if(!prs_uint32("buf_max_len", ps, depth, &(r_r->buf_max_len)))
+       if ( !prs_pointer("buf_len", ps, depth, (void**)&r_u->buf_len, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-       }
 
-       if(!prs_uint32("ptr_len", ps, depth, &(r_r->ptr_len)))
-               return False;
-       if (r_r->ptr_len != 0) {
-               if(!prs_uint32("buf_len", ps, depth, &(r_r->buf_len)))
-                       return False;
-       }
-
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -1220,28 +1055,29 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
-                               uint32 val_idx, UNISTR2 *uni2,
+void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_u, POLICY_HND *pol,
+                               uint32 val_idx, char *name,
                                uint32 max_buf_len)
 {
-       ZERO_STRUCTP(q_i);
+       ZERO_STRUCTP(q_u);
+
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+       q_u->val_index = val_idx;
 
-       q_i->val_index = val_idx;
-       init_uni_hdr(&q_i->hdr_name, uni2);
+       init_unistr4( &q_u->name, name, UNI_STR_TERMINATE );
        
-       q_i->ptr_type = 1;
-       q_i->type = 0x0;
+       q_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+       *q_u->type = 0x0;
 
-       q_i->ptr_value = 1;
-       q_i->buf_value.buf_max_len = max_buf_len;
+       q_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+       q_u->value->buf_max_len = max_buf_len;
 
-       q_i->ptr1 = 1;
-       q_i->len_value1 = max_buf_len;
+       q_u->len_value1 = TALLOC_P( get_talloc_ctx(), uint32 );
+       *q_u->len_value1 = max_buf_len;
 
-       q_i->ptr2 = 1;
-       q_i->len_value2 = 0;
+       q_u->len_value2 = TALLOC_P( get_talloc_ctx(), uint32 );
+       *q_u->len_value2 = max_buf_len;
 }
 
 /*******************************************************************
@@ -1260,26 +1096,25 @@ void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
 
        DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
        
-       init_unistr2( &r_u->uni_name, val->valuename, UNI_STR_TERMINATE);
-       init_uni_hdr( &r_u->hdr_name, &r_u->uni_name);
+       init_unistr4( &r_u->name, val->valuename, UNI_STR_TERMINATE);
                
        /* type */
        
-       r_u->ptr_type = 1;
-       r_u->type = val->type;
+       r_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->type = val->type;
 
        /* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
        
-       r_u->ptr_value = 1;
-       real_size = reg_init_buffer2( &r_u->buf_value, val );
+       r_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+       real_size = reg_init_regval_buffer( r_u->value, val );
        
        /* lengths */
 
-       r_u->ptr1 = 1;
-       r_u->len_value1 = real_size;
+       r_u->len_value1 = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->len_value1 = real_size;
        
-       r_u->ptr2 = 1;
-       r_u->len_value2 = real_size;
+       r_u->len_value2 = TALLOC_P( get_talloc_ctx(), uint32 );
+       *r_u->len_value2 = real_size;
                
        DEBUG(8,("init_reg_r_enum_val: Exit\n"));
 }
@@ -1288,9 +1123,9 @@ void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_enum_val(const char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_val(const char *desc,  REG_Q_ENUM_VALUE *q_u, prs_struct *ps, int depth)
 {
-       if (q_q == NULL)
+       if (q_u == NULL)
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_enum_val");
@@ -1299,46 +1134,29 @@ BOOL reg_io_q_enum_val(const char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
        
-       if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
+       if(!prs_uint32("val_index", ps, depth, &q_u->val_index))
                return False;
                
-       if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &q_u->name ))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr_type", ps, depth, &q_q->ptr_type))
+       if(!prs_pointer("type", ps, depth, (void**)&q_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
 
-       if (q_q->ptr_type != 0) {
-               if(!prs_uint32("type", ps, depth, &q_q->type))
-                       return False;
-       }
-
-       if(!prs_uint32("ptr_value", ps, depth, &q_q->ptr_value))
-               return False;
-       if(!smb_io_buffer2("buf_value", &q_q->buf_value, q_q->ptr_value, ps, depth))
+       if ( !prs_pointer("value", ps, depth, (void**)&q_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+       if(!prs_pointer("len_value1", ps, depth, (void**)&q_u->len_value1, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-       if (q_q->ptr1 != 0) {
-               if(!prs_uint32("len_value1", ps, depth, &q_q->len_value1))
-                       return False;
-       }
-       if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+       if(!prs_pointer("len_value2", ps, depth, (void**)&q_u->len_value2, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-       if (q_q->ptr2 != 0) {
-               if(!prs_uint32("len_value2", ps, depth, &q_q->len_value2))
-                       return False;
-       }
 
        return True;
 }
@@ -1347,9 +1165,9 @@ BOOL reg_io_q_enum_val(const char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps,
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_enum_val(const char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_val(const char *desc,  REG_R_ENUM_VALUE *r_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_enum_val");
@@ -1358,43 +1176,26 @@ BOOL reg_io_r_enum_val(const char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_unihdr ("hdr_name", &r_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("uni_name", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &r_u->name ))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr_type", ps, depth, &r_q->ptr_type))
+       if(!prs_pointer("type", ps, depth, (void**)&r_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
 
-       if (r_q->ptr_type != 0) {
-               if(!prs_uint32("type", ps, depth, &r_q->type))
-                       return False;
-       }
-
-       if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
-               return False;
-       if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
+       if ( !prs_pointer("value", ps, depth, (void**)&r_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+       if(!prs_pointer("len_value1", ps, depth, (void**)&r_u->len_value1, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-       if (r_q->ptr1 != 0) {
-               if(!prs_uint32("len_value1", ps, depth, &r_q->len_value1))
-                       return False;
-       }
-
-       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+       if(!prs_pointer("len_value2", ps, depth, (void**)&r_u->len_value2, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
                return False;
-       if (r_q->ptr2 != 0) {
-               if(!prs_uint32("len_value2", ps, depth, &r_q->len_value2))
-                       return False;
-       }
 
-       if(!prs_werror("status", ps, depth, &r_q->status))
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -1404,53 +1205,55 @@ BOOL reg_io_r_enum_val(const char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps,
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
+void init_reg_q_set_val(REG_Q_SET_VALUE *q_u, POLICY_HND *pol,
                                char *val_name, uint32 type,
-                               BUFFER3 *val)
+                               RPC_DATA_BLOB *val)
 {
-       ZERO_STRUCTP(q_i);
+       ZERO_STRUCTP(q_u);
 
-       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       init_unistr2(&q_i->uni_name, val_name, UNI_STR_TERMINATE);
-       init_uni_hdr(&q_i->hdr_name, &q_i->uni_name);
+       init_unistr4(&q_u->name, val_name, UNI_STR_TERMINATE);
        
-       q_i->type      = type;
-       q_i->buf_value = val;
+       q_u->type      = type;
+       q_u->value     = *val;
+       q_u->size      = val->buf_len;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_create_val(const char *desc,  REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_val(const char *desc,  REG_Q_SET_VALUE *q_u, prs_struct *ps, int depth)
 {
-       if (q_q == NULL)
+       if (q_u == NULL)
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_q_create_val");
+       prs_debug(ps, depth, desc, "reg_io_q_set_val");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
        
-       if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
-               return False;
-       if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &q_u->name ))
                return False;
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("type", ps, depth, &q_q->type))
+       if(!prs_uint32("type", ps, depth, &q_u->type))
                return False;
-       if(!smb_io_buffer3("buf_value", q_q->buf_value, ps, depth))
+
+       if(!smb_io_rpc_blob("value", &q_u->value, ps, depth ))
                return False;
        if(!prs_align(ps))
                return False;
 
+       if(!prs_uint32("size", ps, depth, &q_u->size))
+               return False;
+
        return True;
 }
 
@@ -1458,18 +1261,18 @@ BOOL reg_io_q_create_val(const char *desc,  REG_Q_CREATE_VALUE *q_q, prs_struct
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_create_val(const char *desc,  REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_val(const char *desc,  REG_R_SET_VALUE *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_create_val");
+       prs_debug(ps, depth, desc, "reg_io_r_set_val");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!prs_werror("status", ps, depth, &r_q->status))
+       if(!prs_werror("status", ps, depth, &q_u->status))
                return False;
 
        return True;
@@ -1479,23 +1282,23 @@ BOOL reg_io_r_create_val(const char *desc,  REG_R_CREATE_VALUE *r_q, prs_struct
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_u, POLICY_HND *pol, uint32 key_idx)
 {
-       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       q_i->key_index = key_idx;
-       q_i->key_name_len = 0;
-       q_i->unknown_1 = 0x0414;
+       q_u->key_index = key_idx;
+       q_u->key_name_len = 0;
+       q_u->unknown_1 = 0x0414;
 
-       q_i->ptr1 = 1;
-       q_i->unknown_2 = 0x0000020A;
-       memset(q_i->pad1, 0, sizeof(q_i->pad1));
+       q_u->ptr1 = 1;
+       q_u->unknown_2 = 0x0000020A;
+       memset(q_u->pad1, 0, sizeof(q_u->pad1));
 
-       q_i->ptr2 = 1;
-       memset(q_i->pad2, 0, sizeof(q_i->pad2));
+       q_u->ptr2 = 1;
+       memset(q_u->pad2, 0, sizeof(q_u->pad2));
 
-       q_i->ptr3 = 1;
-       unix_to_nt_time(&q_i->time, 0);            /* current time? */
+       q_u->ptr3 = 1;
+       unix_to_nt_time(&q_u->time, 0);            /* current time? */
 }
 
 /*******************************************************************
@@ -1525,9 +1328,9 @@ void init_reg_r_enum_key(REG_R_ENUM_KEY *r_u, char *subkey, uint32 unknown_1,
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_enum_key(const char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_key(const char *desc,  REG_Q_ENUM_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (q_q == NULL)
+       if (q_u == NULL)
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_enum_key");
@@ -1536,39 +1339,39 @@ BOOL reg_io_q_enum_key(const char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, i
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
        
-       if(!prs_uint32("key_index", ps, depth, &q_q->key_index))
+       if(!prs_uint32("key_index", ps, depth, &q_u->key_index))
                return False;
-       if(!prs_uint16("key_name_len", ps, depth, &q_q->key_name_len))
+       if(!prs_uint16("key_name_len", ps, depth, &q_u->key_name_len))
                return False;
-       if(!prs_uint16("unknown_1", ps, depth, &q_q->unknown_1))
+       if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
                return False;
 
-       if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+       if(!prs_uint32("ptr1", ps, depth, &q_u->ptr1))
                return False;
 
-       if (q_q->ptr1 != 0) {
-               if(!prs_uint32("unknown_2", ps, depth, &q_q->unknown_2))
+       if (q_u->ptr1 != 0) {
+               if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
                        return False;
-               if(!prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1)))
+               if(!prs_uint8s(False, "pad1", ps, depth, q_u->pad1, sizeof(q_u->pad1)))
                        return False;
        }
 
-       if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+       if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
                return False;
 
-       if (q_q->ptr2 != 0) {
-               if(!prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2)))
+       if (q_u->ptr2 != 0) {
+               if(!prs_uint8s(False, "pad2", ps, depth, q_u->pad2, sizeof(q_u->pad2)))
                        return False;
        }
 
-       if(!prs_uint32("ptr3", ps, depth, &q_q->ptr3))
+       if(!prs_uint32("ptr3", ps, depth, &q_u->ptr3))
                return False;
 
-       if (q_q->ptr3 != 0) {
-               if(!smb_io_time("", &q_q->time, ps, depth))
+       if (q_u->ptr3 != 0) {
+               if(!smb_io_time("", &q_u->time, ps, depth))
                        return False;
        }
 
@@ -1579,9 +1382,9 @@ BOOL reg_io_q_enum_key(const char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, i
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_enum_key(const char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_key(const char *desc,  REG_R_ENUM_KEY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_enum_key");
@@ -1590,42 +1393,42 @@ BOOL reg_io_r_enum_key(const char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, i
        if(!prs_align(ps))
                return False;
        
-       if(!prs_uint16("key_name_len", ps, depth, &r_q->key_name_len))
+       if(!prs_uint16("key_name_len", ps, depth, &q_u->key_name_len))
                return False;
-       if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
+       if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
                return False;
 
-       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+       if(!prs_uint32("ptr1", ps, depth, &q_u->ptr1))
                return False;
 
-       if (r_q->ptr1 != 0) {
-               if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+       if (q_u->ptr1 != 0) {
+               if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
                        return False;
-               if(!prs_uint32("unknown_3", ps, depth, &r_q->unknown_3))
+               if(!prs_uint32("unknown_3", ps, depth, &q_u->unknown_3))
                        return False;
-               if(!smb_io_unistr3("key_name", &r_q->key_name, ps, depth))
+               if(!smb_io_unistr3("key_name", &q_u->key_name, ps, depth))
                        return False;
                if(!prs_align(ps))
                        return False;
        }
 
-       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+       if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
                return False;
 
-       if (r_q->ptr2 != 0) {
-               if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
+       if (q_u->ptr2 != 0) {
+               if(!prs_uint8s(False, "pad2", ps, depth, q_u->pad2, sizeof(q_u->pad2)))
                        return False;
        }
 
-       if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
+       if(!prs_uint32("ptr3", ps, depth, &q_u->ptr3))
                return False;
 
-       if (r_q->ptr3 != 0) {
-               if(!smb_io_time("", &r_q->time, ps, depth))
+       if (q_u->ptr3 != 0) {
+               if(!smb_io_time("", &q_u->time, ps, depth))
                        return False;
        }
 
-       if(!prs_werror("status", ps, depth, &r_q->status))
+       if(!prs_werror("status", ps, depth, &q_u->status))
                return False;
 
        return True;
@@ -1635,46 +1438,43 @@ BOOL reg_io_r_enum_key(const char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, i
 makes a structure.
 ********************************************************************/
 
-void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *q_u, POLICY_HND *pol,
                                char *key_name, uint32 access_desired)
 {
-       memcpy(&r_q->pol, pol, sizeof(r_q->pol));
+       memcpy(&q_u->pol, pol, sizeof(q_u->pol));
 
-       init_unistr2(&r_q->uni_name, key_name, UNI_STR_TERMINATE);
-       init_uni_hdr(&r_q->hdr_name, &r_q->uni_name);
+       init_unistr4(&q_u->name, key_name, UNI_STR_TERMINATE);
 
-       r_q->unknown_0 = 0x00000000;
-       r_q->access_desired = access_desired;
+       q_u->unknown_0 = 0x00000000;
+       q_u->access = access_desired;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_open_entry(const char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_entry(const char *desc,  REG_Q_OPEN_ENTRY *q_u, prs_struct *ps, int depth)
 {
-       if (r_q == NULL)
+       if ( !q_u )
                return False;
 
-       prs_debug(ps, depth, desc, "reg_io_q_entry");
+       prs_debug(ps, depth, desc, "reg_io_q_open_entry");
        depth++;
 
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
-               return False;
-       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
                return False;
-       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+       if(!prs_unistr4("name", ps, depth, &q_u->name))
                return False;
 
        if(!prs_align(ps))
                return False;
        
-       if(!prs_uint32("unknown_0        ", ps, depth, &r_q->unknown_0))
+       if(!prs_uint32("unknown_0        ", ps, depth, &q_u->unknown_0))
                return False;
-       if(!prs_uint32("access_desired  ", ps, depth, &r_q->access_desired))
+       if(!prs_uint32("access", ps, depth, &q_u->access))
                return False;
 
        return True;
@@ -1684,24 +1484,24 @@ BOOL reg_io_q_open_entry(const char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *p
  Inits a structure.
 ********************************************************************/
 
-void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_u,
                           POLICY_HND *pol, WERROR werr)
 {
        if (W_ERROR_IS_OK(werr)) {
-               memcpy(&r_r->pol, pol, sizeof(r_r->pol));
+               memcpy(&r_u->pol, pol, sizeof(r_u->pol));
        } else {
-               ZERO_STRUCT(r_r->pol);
+               ZERO_STRUCT(r_u->pol);
        }
-       r_r->status = werr;
+       r_u->status = werr;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_r_open_entry(const char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_entry(const char *desc,  REG_R_OPEN_ENTRY *r_u, prs_struct *ps, int depth)
 {
-       if (r_r == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_open_entry");
@@ -1710,10 +1510,10 @@ BOOL reg_io_r_open_entry(const char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *p
        if(!prs_align(ps))
                return False;
        
-       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+       if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
                return False;
 
-       if(!prs_werror("status", ps, depth, &r_r->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
@@ -1723,30 +1523,53 @@ BOOL reg_io_r_open_entry(const char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *p
 Inits a structure.
 ********************************************************************/
 
-void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s, const char *msg,
+void init_reg_q_shutdown(REG_Q_SHUTDOWN *q_u, const char *msg,
                        uint32 timeout, BOOL do_reboot, BOOL force)
 {
-       q_s->ptr_0 = 1;
-       q_s->ptr_1 = 1;
-       q_s->ptr_2 = 1;
+       q_u->server = TALLOC_P( get_talloc_ctx(), uint16 );
+       *q_u->server = 0x1;
+
+       q_u->message = TALLOC_P( get_talloc_ctx(), UNISTR4 );
+       init_unistr4( q_u->message, msg, UNI_FLAGS_NONE );
 
-       init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
-       init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+       q_u->timeout = timeout;
+
+       q_u->reboot = do_reboot ? 1 : 0;
+       q_u->force = force ? 1 : 0;
+}
 
-       q_s->timeout = timeout;
+/*******************************************************************
+Inits a REG_Q_SHUTDOWN_EX structure.
+********************************************************************/
 
-       q_s->reboot = do_reboot ? 1 : 0;
-       q_s->force = force ? 1 : 0;
+void init_reg_q_shutdown_ex(REG_Q_SHUTDOWN_EX * q_u_ex, const char *msg,
+                       uint32 timeout, BOOL do_reboot, BOOL force, uint32 reason)
+{
+       REG_Q_SHUTDOWN q_u;
+       
+       ZERO_STRUCT( q_u );
+       
+       init_reg_q_shutdown( &q_u, msg, timeout, do_reboot, force );
+       
+       /* steal memory */
+       
+       q_u_ex->server  = q_u.server;
+       q_u_ex->message = q_u.message;
+       
+       q_u_ex->reboot  = q_u.reboot;
+       q_u_ex->force   = q_u.force;
+       
+       q_u_ex->reason = reason;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
-BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
+BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN *q_u, prs_struct *ps,
                       int depth)
 {
-       if (q_s == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_shutdown");
@@ -1755,37 +1578,34 @@ BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("ptr_0", ps, depth, &(q_s->ptr_0)))
-               return False;
-       if (!prs_uint32("ptr_1", ps, depth, &(q_s->ptr_1)))
-               return False;
-       if (!prs_uint32("ptr_2", ps, depth, &(q_s->ptr_2)))
+       if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
                return False;
 
-       if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
-               return False;
-       if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
+       if (!prs_pointer("message", ps, depth, (void**)&q_u->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
                return False;
+
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
+       if (!prs_uint32("timeout", ps, depth, &(q_u->timeout)))
                return False;
-       if (!prs_uint8("force  ", ps, depth, &(q_s->force)))
+
+       if (!prs_uint8("force  ", ps, depth, &(q_u->force)))
                return False;
-       if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
+       if (!prs_uint8("reboot ", ps, depth, &(q_u->reboot)))
                return False;
 
+
        return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
+BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN *r_u, prs_struct *ps,
                       int depth)
 {
-       if (r_s == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_shutdown");
@@ -1794,29 +1614,93 @@ BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
        if(!prs_align(ps))
                return False;
 
-       if(!prs_werror("status", ps, depth, &r_s->status))
+       if(!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
 }
 
 /*******************************************************************
-Inits a structure.
+reads or writes a REG_Q_SHUTDOWN_EX structure.
 ********************************************************************/
-void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN * q_s)
+
+BOOL reg_io_q_shutdown_ex(const char *desc, REG_Q_SHUTDOWN_EX *q_u, prs_struct *ps,
+                      int depth)
 {
+       if ( !q_u )
+               return False;
+
+       prs_debug(ps, depth, desc, "reg_io_q_shutdown_ex");
+       depth++;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
+               return False;
+
+       if (!prs_pointer("message", ps, depth, (void**)&q_u->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
+               return False;
 
-       q_s->ptr_server = 0;
+       if (!prs_align(ps))
+               return False;
 
+       if (!prs_uint32("timeout", ps, depth, &(q_u->timeout)))
+               return False;
+
+       if (!prs_uint8("force  ", ps, depth, &(q_u->force)))
+               return False;
+       if (!prs_uint8("reboot ", ps, depth, &(q_u->reboot)))
+               return False;
+
+       if (!prs_align(ps))
+               return False;
+       if (!prs_uint32("reason", ps, depth, &(q_u->reason)))
+               return False;
+
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a REG_R_SHUTDOWN_EX structure.
+********************************************************************/
+BOOL reg_io_r_shutdown_ex(const char *desc, REG_R_SHUTDOWN_EX *r_u, prs_struct *ps,
+                      int depth)
+{
+       if ( !r_u )
+               return False;
+
+       prs_debug(ps, depth, desc, "reg_io_r_shutdown_ex");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN *q_u)
+{
+       q_u->server = TALLOC_P( get_talloc_ctx(), uint16 );
+       *q_u->server = 0x1;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
+BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN *q_u,
                             prs_struct *ps, int depth)
 {
-       if (q_s == NULL)
+       if ( !q_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_abort_shutdown");
@@ -1825,11 +1709,8 @@ BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+       if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
                return False;
-       if (q_s->ptr_server != 0)
-               if (!prs_uint16("server", ps, depth, &(q_s->server)))
-                       return False;
 
        return True;
 }
@@ -1837,10 +1718,10 @@ BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
+BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN *r_u,
                             prs_struct *ps, int depth)
 {
-       if (r_s == NULL)
+       if ( !r_u )
                return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_abort_shutdown");
@@ -1849,7 +1730,7 @@ BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_werror("status", ps, depth, &r_s->status))
+       if (!prs_werror("status", ps, depth, &r_u->status))
                return False;
 
        return True;
index aa296eb70a160f068018cad749095706120e2067..6bdab2e437c566e766284f2ed6159617c6607d38 100644 (file)
@@ -36,7 +36,7 @@ interface/version dce/rpc pipe identification
                0x8a885d04, 0x1ceb, 0x11c9, \
                { 0x9f, 0xe8 },             \
                { 0x08, 0x00,               \
-               0x2b, 0x10, 0x48, 0x60 }    \
+                         0x2b, 0x10, 0x48, 0x60 }  \
        }, 0x02                             \
 }
 
@@ -46,7 +46,7 @@ interface/version dce/rpc pipe identification
                0x8a885d04, 0x1ceb, 0x11c9, \
                { 0x9f, 0xe8 },             \
                { 0x08, 0x00,               \
-               0x2b, 0x10, 0x48, 0x60 }    \
+                 0x2b, 0x10, 0x48, 0x60 }  \
        }, 0x02                             \
 }
 
@@ -56,7 +56,7 @@ interface/version dce/rpc pipe identification
                0x6bffd098, 0xa112, 0x3610, \
                { 0x98, 0x33 },             \
                { 0x46, 0xc3,               \
-               0xf8, 0x7e, 0x34, 0x5a }    \
+                 0xf8, 0x7e, 0x34, 0x5a }  \
        }, 0x01                             \
 }
 
@@ -66,7 +66,7 @@ interface/version dce/rpc pipe identification
                0x4b324fc8, 0x1670, 0x01d3, \
                { 0x12, 0x78 },             \
                { 0x5a, 0x47,               \
-               0xbf, 0x6e, 0xe1, 0x88 }    \
+                 0xbf, 0x6e, 0xe1, 0x88 }  \
        }, 0x03                             \
 }
 
@@ -76,7 +76,7 @@ interface/version dce/rpc pipe identification
                0x12345778, 0x1234, 0xabcd, \
                { 0xef, 0x00 },             \
                { 0x01, 0x23,               \
-               0x45, 0x67, 0x89, 0xab }    \
+                 0x45, 0x67, 0x89, 0xab }  \
        }, 0x00                             \
 }
 
@@ -86,7 +86,7 @@ interface/version dce/rpc pipe identification
                0x3919286a, 0xb10c, 0x11d0, \
                { 0x9b, 0xa8 },             \
                { 0x00, 0xc0,               \
-               0x4f, 0xd9, 0x2e, 0xf5 }    \
+                 0x4f, 0xd9, 0x2e, 0xf5 }  \
        }, 0x00                             \
 }
 
@@ -96,7 +96,7 @@ interface/version dce/rpc pipe identification
                0x12345778, 0x1234, 0xabcd, \
                { 0xef, 0x00 },             \
                { 0x01, 0x23,               \
-               0x45, 0x67, 0x89, 0xac }    \
+                 0x45, 0x67, 0x89, 0xac }  \
        }, 0x01                             \
 }
 
@@ -106,7 +106,7 @@ interface/version dce/rpc pipe identification
                0x12345678, 0x1234, 0xabcd, \
                { 0xef, 0x00 },             \
                { 0x01, 0x23,               \
-               0x45, 0x67, 0xcf, 0xfb }    \
+                 0x45, 0x67, 0xcf, 0xfb }  \
        }, 0x01                             \
 }
 
@@ -116,7 +116,7 @@ interface/version dce/rpc pipe identification
                0x338cd001, 0x2244, 0x31f1, \
                { 0xaa, 0xaa },             \
                { 0x90, 0x00,               \
-               0x38, 0x00, 0x10, 0x03 }    \
+                 0x38, 0x00, 0x10, 0x03 }  \
        }, 0x01                             \
 }
 
@@ -126,7 +126,7 @@ interface/version dce/rpc pipe identification
                0x12345678, 0x1234, 0xabcd, \
                { 0xef, 0x00 },             \
                { 0x01, 0x23,               \
-               0x45, 0x67, 0x89, 0xab }    \
+                 0x45, 0x67, 0x89, 0xab }  \
        }, 0x01                             \
 }
 
@@ -136,7 +136,7 @@ interface/version dce/rpc pipe identification
                0x0, 0x0, 0x0,              \
                { 0x00, 0x00 },             \
                { 0x00, 0x00,               \
-               0x00, 0x00, 0x00, 0x00 }    \
+                 0x00, 0x00, 0x00, 0x00 }  \
        }, 0x00                             \
 }
 
@@ -170,6 +170,27 @@ interface/version dce/rpc pipe identification
         }, 0x01                             \
 }
 
+#define SYNT_SVCCTL_V2                      \
+{                                           \
+       {                                   \
+               0x367abb81, 0x9844, 0x35f1, \
+                { 0xad, 0x32 },             \
+                { 0x98, 0xf0,               \
+                  0x38, 0x00, 0x10, 0x03 }  \
+       }, 0x02                             \
+}
+
+
+#define SYNT_EVENTLOG_V0                   \
+{                                          \
+       {                                   \
+               0x82273fdc, 0xe32a, 0x18c3, \
+               { 0x3f, 0x78 },             \
+               { 0x82, 0x79,               \
+                 0x29, 0xdc, 0x23, 0xea }  \
+       }, 0x00                             \
+}
+
 /*
  * IMPORTANT!!  If you update this structure, make sure to
  * update the index #defines in smb.h.
@@ -189,6 +210,8 @@ const struct pipe_id_info pipe_names [] =
        { PIPE_NETDFS  , SYNT_NETDFS_V3        , PIPE_NETDFS   , TRANS_SYNT_V2 },
        { PIPE_ECHO    , SYNT_ECHO_V1          , PIPE_ECHO     , TRANS_SYNT_V2 },
        { PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1      , PIPE_SHUTDOWN , TRANS_SYNT_V2 },
+       { PIPE_SVCCTL  , SYNT_SVCCTL_V2        , PIPE_NTSVCS   , TRANS_SYNT_V2 },
+       { PIPE_EVENTLOG, SYNT_EVENTLOG_V0      , PIPE_EVENTLOG , TRANS_SYNT_V2 },
        { NULL         , SYNT_NONE_V0          , NULL          , SYNT_NONE_V0  }
 };
 
index 14d4bb9fdf7914bd7299fcf7b9698bad00f260de..d3f709c352c839add06f539115b64b6693b75f2f 100644 (file)
@@ -1516,75 +1516,42 @@ BOOL samr_io_q_query_dispinfo(const char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
 inits a SAM_DISPINFO_1 structure.
 ********************************************************************/
 
-NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
-                            uint32 start_idx, SAM_ACCOUNT *disp_user_info,
-                            DOM_SID *domain_sid)
+NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 **sam,
+                            uint32 num_entries, uint32 start_idx,
+                            struct samr_displayentry *entries)
 {
        uint32 i;
 
-       SAM_ACCOUNT *pwd = NULL;
-       ZERO_STRUCTP(sam);
-
        DEBUG(10, ("init_sam_dispinfo_1: num_entries: %d\n", num_entries));
 
        if (num_entries==0)
                return NT_STATUS_OK;
 
-       sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY1, num_entries);
-       if (!sam->sam)
+       *sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_1, num_entries);
+       if (*sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       sam->str=TALLOC_ARRAY(ctx, SAM_STR1, num_entries);
-       if (!sam->str)
+       (*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY1, num_entries);
+       if ((*sam)->sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       ZERO_STRUCTP(sam->sam);
-       ZERO_STRUCTP(sam->str);
+       (*sam)->str=TALLOC_ARRAY(ctx, SAM_STR1, num_entries);
+       if ((*sam)->str == NULL)
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_entries ; i++) {
-               const char *username;
-               const char *fullname;
-               const char *acct_desc;
-               uint32 user_rid;
-               const DOM_SID *user_sid;
-               fstring user_sid_string, domain_sid_string;                     
-
-               DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
-               
-               pwd=&disp_user_info[i+start_idx];
-               
-               username = pdb_get_username(pwd);
-               fullname = pdb_get_fullname(pwd);
-               acct_desc = pdb_get_acct_desc(pwd);
-               
-               if (!username) 
-                       username = "";
-
-               if (!fullname) 
-                       fullname = "";
-               
-               if (!acct_desc) 
-                       acct_desc = "";
-
-               user_sid = pdb_get_user_sid(pwd);
-
-               if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
-                       DEBUG(0, ("init_sam_dispinfo_1: User %s has SID %s, which conflicts with "
-                                 "the domain sid %s.  Failing operation.\n", 
-                                 username, 
-                                 sid_to_string(user_sid_string, user_sid),
-                                 sid_to_string(domain_sid_string, domain_sid)));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-                       
-               init_unistr2(&sam->str[i].uni_acct_name, pdb_get_username(pwd), UNI_FLAGS_NONE);
-               init_unistr2(&sam->str[i].uni_full_name, pdb_get_fullname(pwd), UNI_FLAGS_NONE);
-               init_unistr2(&sam->str[i].uni_acct_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
-
-               init_sam_entry1(&sam->sam[i], start_idx + i + 1,
-                               &sam->str[i].uni_acct_name, &sam->str[i].uni_full_name, &sam->str[i].uni_acct_desc,
-                               user_rid, pdb_get_acct_ctrl(pwd));
-               
+               init_unistr2(&(*sam)->str[i].uni_acct_name,
+                            entries[i].account_name, UNI_FLAGS_NONE);
+               init_unistr2(&(*sam)->str[i].uni_full_name,
+                            entries[i].fullname, UNI_FLAGS_NONE);
+               init_unistr2(&(*sam)->str[i].uni_acct_desc,
+                            entries[i].description, UNI_FLAGS_NONE);
+
+               init_sam_entry1(&(*sam)->sam[i], start_idx+i+1,
+                               &(*sam)->str[i].uni_acct_name,
+                               &(*sam)->str[i].uni_full_name,
+                               &(*sam)->str[i].uni_acct_desc,
+                               entries[i].rid, entries[i].acct_flags);
        }
 
        return NT_STATUS_OK;
@@ -1639,58 +1606,39 @@ static BOOL sam_io_sam_dispinfo_1(const char *desc, SAM_DISPINFO_1 * sam,
 inits a SAM_DISPINFO_2 structure.
 ********************************************************************/
 
-NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
-                            uint32 start_idx, SAM_ACCOUNT *disp_user_info, 
-                            DOM_SID *domain_sid )
+NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 **sam,
+                            uint32 num_entries, uint32 start_idx,
+                            struct samr_displayentry *entries)
 {
        uint32 i;
 
-       SAM_ACCOUNT *pwd = NULL;
-       ZERO_STRUCTP(sam);
-
        DEBUG(10, ("init_sam_dispinfo_2: num_entries: %d\n", num_entries));
 
        if (num_entries==0)
                return NT_STATUS_OK;
 
-       if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY2, num_entries)))
+       *sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_2, num_entries);
+       if (*sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR2, num_entries)))
+       (*sam)->sam = TALLOC_ARRAY(ctx, SAM_ENTRY2, num_entries);
+       if ((*sam)->sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       ZERO_STRUCTP(sam->sam);
-       ZERO_STRUCTP(sam->str);
+       (*sam)->str=TALLOC_ARRAY(ctx, SAM_STR2, num_entries);
+       if ((*sam)->str == NULL)
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_entries; i++) {
-               uint32 user_rid;
-               const DOM_SID *user_sid;
-               const char *username;
-               const char *acct_desc;
-               fstring user_sid_string, domain_sid_string;                     
-
-               DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
-               pwd=&disp_user_info[i+start_idx];
-
-               username = pdb_get_username(pwd);
-               acct_desc = pdb_get_acct_desc(pwd);
-               user_sid = pdb_get_user_sid(pwd);
-
-               if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
-                       DEBUG(0, ("init_sam_dispinfo_2: User %s has SID %s, which conflicts with "
-                                 "the domain sid %s.  Failing operation.\n", 
-                                 username, 
-                                 sid_to_string(user_sid_string, user_sid),
-                                 sid_to_string(domain_sid_string, domain_sid)));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-                       
-               init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
-               init_unistr2(&sam->str[i].uni_srv_desc, acct_desc, UNI_FLAGS_NONE);
-
-               init_sam_entry2(&sam->sam[i], start_idx + i + 1,
-                         &sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
-                         user_rid, pdb_get_acct_ctrl(pwd));
+               init_unistr2(&(*sam)->str[i].uni_srv_name,
+                            entries[i].account_name, UNI_FLAGS_NONE);
+               init_unistr2(&(*sam)->str[i].uni_srv_desc,
+                            entries[i].description, UNI_FLAGS_NONE);
+
+               init_sam_entry2(&(*sam)->sam[i], start_idx + i + 1,
+                               &(*sam)->str[i].uni_srv_name,
+                               &(*sam)->str[i].uni_srv_desc,
+                               entries[i].rid, entries[i].acct_flags);
        }
 
        return NT_STATUS_OK;
@@ -1747,37 +1695,39 @@ static BOOL sam_io_sam_dispinfo_2(const char *desc, SAM_DISPINFO_2 * sam,
 inits a SAM_DISPINFO_3 structure.
 ********************************************************************/
 
-NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
-                        uint32 start_idx, DOMAIN_GRP *disp_group_info)
+NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 **sam,
+                            uint32 num_entries, uint32 start_idx,
+                            struct samr_displayentry *entries)
 {
        uint32 i;
 
-       ZERO_STRUCTP(sam);
-
        DEBUG(5, ("init_sam_dispinfo_3: num_entries: %d\n", num_entries));
 
        if (num_entries==0)
                return NT_STATUS_OK;
 
-       if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY3, num_entries)))
+       *sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_3, num_entries);
+       if (*sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR3, num_entries)))
+       if (!((*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY3, num_entries)))
                return NT_STATUS_NO_MEMORY;
 
-       ZERO_STRUCTP(sam->sam);
-       ZERO_STRUCTP(sam->str);
+       if (!((*sam)->str=TALLOC_ARRAY(ctx, SAM_STR3, num_entries)))
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_entries; i++) {
-               DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
-
                DEBUG(11, ("init_sam_dispinfo_3: entry: %d\n",i));
 
-               init_unistr2(&sam->str[i].uni_grp_name, grp->name, UNI_FLAGS_NONE);
-               init_unistr2(&sam->str[i].uni_grp_desc, grp->comment, UNI_FLAGS_NONE);
+               init_unistr2(&(*sam)->str[i].uni_grp_name,
+                            entries[i].account_name, UNI_FLAGS_NONE);
+               init_unistr2(&(*sam)->str[i].uni_grp_desc,
+                            entries[i].description, UNI_FLAGS_NONE);
 
-               init_sam_entry3(&sam->sam[i], start_idx + i + 1, &sam->str[i].uni_grp_name,
-                               &sam->str[i].uni_grp_desc, grp->rid);
+               init_sam_entry3(&(*sam)->sam[i], start_idx+i+1,
+                               &(*sam)->str[i].uni_grp_name,
+                               &(*sam)->str[i].uni_grp_desc,
+                               entries[i].rid);
        }
 
        return NT_STATUS_OK;
@@ -1834,38 +1784,40 @@ static BOOL sam_io_sam_dispinfo_3(const char *desc, SAM_DISPINFO_3 * sam,
 inits a SAM_DISPINFO_4 structure.
 ********************************************************************/
 
-NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
-                        uint32 start_idx, SAM_ACCOUNT *disp_user_info)
+NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 **sam,
+                            uint32 num_entries, uint32 start_idx,
+                            struct samr_displayentry *entries)
 {
-       uint32 len_sam_name;
        uint32 i;
 
-       SAM_ACCOUNT *pwd = NULL;
-       ZERO_STRUCTP(sam);
-
        DEBUG(5, ("init_sam_dispinfo_4: num_entries: %d\n", num_entries));
 
        if (num_entries==0)
                return NT_STATUS_OK;
 
-       if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY4, num_entries)))
+       *sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_4, num_entries);
+       if (*sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR4, num_entries)))
+       (*sam)->sam = TALLOC_ARRAY(ctx, SAM_ENTRY4, num_entries);
+       if ((*sam)->sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       ZERO_STRUCTP(sam->sam);
-       ZERO_STRUCTP(sam->str);
+       (*sam)->str=TALLOC_ARRAY(ctx, SAM_STR4, num_entries);
+       if ((*sam)->str == NULL)
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_entries; i++) {
-               DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
-               pwd=&disp_user_info[i+start_idx];
+               size_t len_sam_name = strlen(entries[i].account_name);
 
-               len_sam_name = strlen(pdb_get_username(pwd));
+               DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
          
-               init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
+               init_sam_entry4(&(*sam)->sam[i], start_idx + i + 1,
+                               len_sam_name);
 
-               init_string2(&sam->str[i].acct_name, pdb_get_username(pwd), len_sam_name+1, len_sam_name);
+               init_string2(&(*sam)->str[i].acct_name,
+                            entries[i].account_name, len_sam_name+1,
+                            len_sam_name);
        }
        
        return NT_STATUS_OK;
@@ -1921,37 +1873,36 @@ static BOOL sam_io_sam_dispinfo_4(const char *desc, SAM_DISPINFO_4 * sam,
 inits a SAM_DISPINFO_5 structure.
 ********************************************************************/
 
-NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
-                        uint32 start_idx, DOMAIN_GRP *disp_group_info)
+NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 **sam,
+                            uint32 num_entries, uint32 start_idx,
+                            struct samr_displayentry *entries)
 {
        uint32 len_sam_name;
        uint32 i;
 
-       ZERO_STRUCTP(sam);
-
        DEBUG(5, ("init_sam_dispinfo_5: num_entries: %d\n", num_entries));
 
        if (num_entries==0)
                return NT_STATUS_OK;
 
-       if (!(sam->sam=TALLOC_ARRAY(ctx, SAM_ENTRY5, num_entries)))
+       *sam = TALLOC_ZERO_ARRAY(ctx, SAM_DISPINFO_5, num_entries);
+       if (*sam == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       if (!(sam->str=TALLOC_ARRAY(ctx, SAM_STR5, num_entries)))
+       if (!((*sam)->sam=TALLOC_ARRAY(ctx, SAM_ENTRY5, num_entries)))
                return NT_STATUS_NO_MEMORY;
 
-       ZERO_STRUCTP(sam->sam);
-       ZERO_STRUCTP(sam->str);
+       if (!((*sam)->str=TALLOC_ARRAY(ctx, SAM_STR5, num_entries)))
+               return NT_STATUS_NO_MEMORY;
 
        for (i = 0; i < num_entries; i++) {
-               DOMAIN_GRP *grp = &disp_group_info[i+start_idx];
-
                DEBUG(11, ("init_sam_dispinfo_5: entry: %d\n",i));
 
-               len_sam_name = strlen(grp->name);
+               len_sam_name = strlen(entries[i].account_name);
          
-               init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name);
-               init_string2(&sam->str[i].grp_name, grp->name, len_sam_name+1, len_sam_name);
+               init_sam_entry5(&(*sam)->sam[i], start_idx+i+1, len_sam_name);
+               init_string2(&(*sam)->str[i].grp_name, entries[i].account_name,
+                            len_sam_name+1, len_sam_name);
        }
 
        return NT_STATUS_OK;
index f6fdf102928647b2ffc91f8ea5ab1d6c05c11378..6a752688a0bc59ab5d48829b0c04368540c1e1b1 100644 (file)
@@ -133,7 +133,7 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
         * Note that the size is always a multiple of 4 bytes due to the
         * nature of the data structure.  Therefore the prs_align() calls
         * have been removed as they through us off when doing two-layer
-        * marshalling such as in the printing code (NEW_BUFFER).  --jerry
+        * marshalling such as in the printing code (RPC_BUFFER).  --jerry
         */
 
        if (ppsa == NULL)
index ad2d6e1a028aa10ff2740d8b415a8a013be48156..00daeaaaee75a30c917752f9cad99af8e6531c99 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Jim McDonough (jmcd@us.ibm.com)   2003.
+ *  Copyright (C) Gerald (Jerry) 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
@@ -30,12 +31,11 @@ Inits a structure.
 void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
                        uint32 timeout, BOOL do_reboot, BOOL force)
 {
-       q_s->ptr_server = 1;
-       q_s->server = 1;
-       q_s->ptr_msg = 1;
+       q_s->server = TALLOC_P( get_talloc_ctx(), uint16 );
+       *q_s->server = 0x1;
 
-       init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
-       init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+       q_s->message = TALLOC_P( get_talloc_ctx(), UNISTR4 );
+       init_unistr4( q_s->message, msg, UNI_FLAGS_NONE );
 
        q_s->timeout = timeout;
 
@@ -43,6 +43,29 @@ void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
        q_s->force = force ? 1 : 0;
 }
 
+/*******************************************************************
+********************************************************************/
+
+void init_shutdown_q_init_ex(SHUTDOWN_Q_INIT_EX * q_u_ex, const char *msg,
+                       uint32 timeout, BOOL do_reboot, BOOL force, uint32 reason)
+{
+       SHUTDOWN_Q_INIT q_u;
+       
+       ZERO_STRUCT( q_u );
+       
+       init_shutdown_q_init( &q_u, msg, timeout, do_reboot, force );
+       
+       /* steal memory */
+       
+       q_u_ex->server  = q_u.server;
+       q_u_ex->message = q_u.message;
+       
+       q_u_ex->reboot  = q_u.reboot;
+       q_u_ex->force   = q_u.force;
+       
+       q_u_ex->reason = reason;
+}
+
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
@@ -59,62 +82,119 @@ BOOL shutdown_io_q_init(const char *desc, SHUTDOWN_Q_INIT *q_s, prs_struct *ps,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+       if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
                return False;
-       if (!prs_uint16("server", ps, depth, &(q_s->server)))
+
+       if (!prs_pointer("message", ps, depth, (void**)&q_s->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
                return False;
 
        if (!prs_align(ps))
                return False;
-       if (!prs_uint32("ptr_msg", ps, depth, &(q_s->ptr_msg)))
+
+       if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
                return False;
 
-       if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
+       if (!prs_uint8("force  ", ps, depth, &(q_s->force)))
                return False;
-       if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
+       if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
                return False;
+
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
+                       int depth)
+{
+       if (r_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_r_init");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_s->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a REG_Q_SHUTDOWN_EX structure.
+********************************************************************/
+
+BOOL shutdown_io_q_init_ex(const char *desc, SHUTDOWN_Q_INIT_EX * q_s, prs_struct *ps,
+                      int depth)
+{
+       if (q_s == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "shutdown_io_q_init_ex");
+       depth++;
+
+       if (!prs_align(ps))
+               return False;
+
+       if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
+               return False;
+
+       if (!prs_pointer("message", ps, depth, (void**)&q_s->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
+               return False;
+
        if (!prs_align(ps))
                return False;
 
        if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
                return False;
+
        if (!prs_uint8("force  ", ps, depth, &(q_s->force)))
                return False;
        if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
                return False;
 
+       if (!prs_align(ps))
+               return False;
+       if (!prs_uint32("reason", ps, depth, &(q_s->reason)))
+               return False;
+
+
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+reads or writes a REG_R_SHUTDOWN_EX structure.
 ********************************************************************/
-BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
-                       int depth)
+BOOL shutdown_io_r_init_ex(const char *desc, SHUTDOWN_R_INIT_EX * r_s, prs_struct *ps,
+                      int depth)
 {
        if (r_s == NULL)
                return False;
 
-       prs_debug(ps, depth, desc, "shutdown_io_r_init");
+       prs_debug(ps, depth, desc, "shutdown_io_r_init_ex");
        depth++;
 
        if(!prs_align(ps))
                return False;
 
-       if(!prs_ntstatus("status", ps, depth, &r_s->status))
+       if(!prs_werror("status", ps, depth, &r_s->status))
                return False;
 
        return True;
 }
 
+
 /*******************************************************************
 Inits a structure.
 ********************************************************************/
 void init_shutdown_q_abort(SHUTDOWN_Q_ABORT *q_s)
 {
-
-       q_s->ptr_server = 0;
-
+       q_s->server = TALLOC_P( get_talloc_ctx(), uint16 );
+       *q_s->server = 0x1;
 }
 
 /*******************************************************************
@@ -132,11 +212,8 @@ BOOL shutdown_io_q_abort(const char *desc, SHUTDOWN_Q_ABORT *q_s,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+       if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
                return False;
-       if (q_s->ptr_server != 0)
-               if (!prs_uint16("server", ps, depth, &(q_s->server)))
-                       return False;
 
        return True;
 }
@@ -156,7 +233,7 @@ BOOL shutdown_io_r_abort(const char *desc, SHUTDOWN_R_ABORT *r_s,
        if (!prs_align(ps))
                return False;
 
-       if (!prs_ntstatus("status", ps, depth, &r_s->status))
+       if (!prs_werror("status", ps, depth, &r_s->status))
                return False;
 
        return True;
index dc419a73b5f454e100539db0b24ca537f89493fc..78602dd806a5bc88e5e9890ba04797ce6dd020f7 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
-/*******************************************************************
-return the length of a UNISTR string.
-********************************************************************/  
-
-static uint32 str_len_uni(UNISTR *source)
-{
-       uint32 i=0;
-
-       if (!source->buffer)
-               return 0;
-
-       while (source->buffer[i])
-               i++;
-
-       return i;
-}
 
 /*******************************************************************
 This should be moved in a more generic lib.
@@ -566,23 +550,22 @@ static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_st
 /*******************************************************************
 ********************************************************************/  
 
-static BOOL spool_io_user_level_1(const char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
+BOOL spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
 {
        prs_debug(ps, depth, desc, "");
        depth++;
 
-       /* reading */
-       if (UNMARSHALLING(ps))
-               ZERO_STRUCTP(q_u);
-
        if (!prs_align(ps))
                return False;
+
        if (!prs_uint32("size", ps, depth, &q_u->size))
                return False;
-       if (!prs_uint32("client_name_ptr", ps, depth, &q_u->client_name_ptr))
+
+       if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
                return False;
-       if (!prs_uint32("user_name_ptr", ps, depth, &q_u->user_name_ptr))
+       if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
                return False;
+
        if (!prs_uint32("build", ps, depth, &q_u->build))
                return False;
        if (!prs_uint32("major", ps, depth, &q_u->major))
@@ -592,11 +575,12 @@ static BOOL spool_io_user_level_1(const char *desc, SPOOL_USER_1 *q_u, prs_struc
        if (!prs_uint32("processor", ps, depth, &q_u->processor))
                return False;
 
-       if (!smb_io_unistr2("", &q_u->client_name, q_u->client_name_ptr, ps, depth))
+       if (!prs_io_unistr2("", ps, depth, q_u->client_name))
                return False;
        if (!prs_align(ps))
                return False;
-       if (!smb_io_unistr2("", &q_u->user_name,   q_u->user_name_ptr,   ps, depth))
+
+       if (!prs_io_unistr2("", ps, depth, q_u->user_name))
                return False;
 
        return True;
@@ -616,21 +600,20 @@ static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struc
        if (!prs_align(ps))
                return False;
 
-       /* From looking at many captures in ethereal, it looks like
-          the level and ptr fields should be transposed.  -tpot */
-
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
-       if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
-               return False;
        
-       switch (q_u->level) {   
-       case 1:
-               if (!spool_io_user_level_1("", &q_u->user1, ps, depth))
-                       return False;
-               break;
-       default:
-               return False;   
+       switch ( q_u->level ) 
+       {       
+               case 1:
+                       if ( !prs_pointer( "" , ps, depth, (void**)&q_u->user.user1, 
+                               sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
+                       {
+                               return False;
+                       }
+                       break;
+               default:
+                       return False;   
        }       
 
        return True;
@@ -915,30 +898,31 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
                const fstring user_name)
 {
        DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
-       q_u->printername_ptr = (printername!=NULL)?1:0;
-       init_unistr2(&q_u->printername, printername, UNI_STR_TERMINATE);
+
+       q_u->printername = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+       init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
 
        q_u->printer_default.datatype_ptr = 0;
-/*
-       q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
-       init_unistr2(&q_u->printer_default.datatype, datatype, UNI_FLAGS_NONE);
-*/
+
        q_u->printer_default.devmode_cont.size=0;
        q_u->printer_default.devmode_cont.devmode_ptr=0;
        q_u->printer_default.devmode_cont.devmode=NULL;
        q_u->printer_default.access_required=access_required;
-       q_u->user_switch=1;
-       q_u->user_ctr.level=1;
-       q_u->user_ctr.ptr=1;
-       q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+10;
-       q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
-       q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
-       q_u->user_ctr.user1.build=1381;
-       q_u->user_ctr.user1.major=2;
-       q_u->user_ctr.user1.minor=0;
-       q_u->user_ctr.user1.processor=0;
-       init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
-       init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
+
+       q_u->user_switch = 1;
+       
+       q_u->user_ctr.level           = 1;
+       q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
+       q_u->user_ctr.user.user1->build     = 1381;
+       q_u->user_ctr.user.user1->major     = 2;
+       q_u->user_ctr.user.user1->minor     = 0;
+       q_u->user_ctr.user.user1->processor = 0;
+
+       q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+       q_u->user_ctr.user.user1->user_name   = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+
+       init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
+       init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
        
        return True;
 }
@@ -947,23 +931,19 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
  * init a structure.
  ********************************************************************/
 
-BOOL make_spoolss_q_addprinterex(
-       TALLOC_CTX *mem_ctx,
-       SPOOL_Q_ADDPRINTEREX *q_u, 
-       const char *srv_name,
-       const char* clientname, 
-       const char* user_name,
-       uint32 level, 
-       PRINTER_INFO_CTR *ctr)
+BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
+       const char *srv_name, const char* clientname, const char* user_name,
+       uint32 level, PRINTER_INFO_CTR *ctr)
 {
        DEBUG(5,("make_spoolss_q_addprinterex\n"));
        
-       if (!ctr) return False;
+       if (!ctr) 
+               return False;
 
        ZERO_STRUCTP(q_u);
 
-       q_u->server_name_ptr = (srv_name!=NULL)?1:0;
-       init_unistr2(&q_u->server_name, srv_name, UNI_FLAGS_NONE);
+       q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
+       init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
 
        q_u->level = level;
        
@@ -983,18 +963,20 @@ BOOL make_spoolss_q_addprinterex(
 
        q_u->user_switch=1;
 
-       q_u->user_ctr.level=1;
-       q_u->user_ctr.ptr=1;
-       q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
-       q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
-       q_u->user_ctr.user1.build=1381;
-       q_u->user_ctr.user1.major=2;
-       q_u->user_ctr.user1.minor=0;
-       q_u->user_ctr.user1.processor=0;
-       init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
-       init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
-       q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
-                                q_u->user_ctr.user1.client_name.uni_str_len + 2;
+       q_u->user_ctr.level                = 1;
+       q_u->user_ctr.user.user1->build     = 1381;
+       q_u->user_ctr.user.user1->major     = 2; 
+       q_u->user_ctr.user.user1->minor     = 0;
+       q_u->user_ctr.user.user1->processor = 0;
+
+       q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
+       q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
+
+       init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
+       init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
+
+       q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
+                                  q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
        
        return True;
 }
@@ -1118,9 +1100,9 @@ BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
+       if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
                return False;
-       if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
+       if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
                return False;
        
        if (!prs_align(ps))
@@ -1174,9 +1156,9 @@ BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u
        if (!prs_align(ps))
                return False;
 
-       if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
+       if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
                return False;
-       if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
+       if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
                return False;
        
        if (!prs_align(ps))
@@ -2067,33 +2049,6 @@ static uint32 size_of_nttime(NTTIME *value)
        return (sizeof(*value));
 }
 
-/*******************************************************************
- * return the length of a UNICODE string in number of char, includes:
- * - the leading zero
- * - the relative pointer size
- ********************************************************************/
-
-static uint32 size_of_relative_string(UNISTR *string)
-{
-       uint32 size=0;
-       
-       size=str_len_uni(string);       /* the string length       */
-       size=size+1;                    /* add the trailing zero   */
-       size=size*2;                    /* convert in char         */
-       size=size+4;                    /* add the size of the ptr */   
-
-#if 0  /* JERRY */
-       /* 
-        * Do not include alignment as Win2k does not align relative
-        * strings within a buffer   --jerry 
-        */
-       /* Ensure size is 4 byte multiple (prs_align is being called...). */
-       /* size += ((4 - (size & 3)) & 3); */
-#endif 
-
-       return size;
-}
-
 /*******************************************************************
  * return the length of a uint32 (obvious, but the code is clean)
  ********************************************************************/
@@ -2118,278 +2073,11 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime)
                return (sizeof(SYSTEMTIME) +4);
 }
 
-/*******************************************************************
- * write a UNICODE string and its relative pointer.
- * used by all the RPC structs passing a buffer
- *
- * As I'm a nice guy, I'm forcing myself to explain this code.
- * MS did a good job in the overall spoolss code except in some
- * functions where they are passing the API buffer directly in the
- * RPC request/reply. That's to maintain compatiility at the API level.
- * They could have done it the good way the first time.
- *
- * So what happen is: the strings are written at the buffer's end, 
- * in the reverse order of the original structure. Some pointers to
- * the strings are also in the buffer. Those are relative to the
- * buffer's start.
- *
- * If you don't understand or want to change that function,
- * first get in touch with me: jfm@samba.org
- *
- ********************************************************************/
-
-static BOOL smb_io_relstr(const char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
-{
-       prs_struct *ps=&buffer->prs;
-       
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-               
-               buffer->string_at_end -= (size_of_relative_string(string) - 4);
-               if(!prs_set_offset(ps, buffer->string_at_end))
-                       return False;
-#if 0  /* JERRY */
-               /*
-                * Win2k does not align strings in a buffer
-                * Tested against WinNT 4.0 SP 6a & 2k SP2  --jerry
-                */
-               if (!prs_align(ps))
-                       return False;
-#endif
-               buffer->string_at_end = prs_offset(ps);
-               
-               /* write the string */
-               if (!smb_io_unistr(desc, string, ps, depth))
-                       return False;
-
-               if(!prs_set_offset(ps, struct_offset))
-                       return False;
-               
-               relative_offset=buffer->string_at_end - buffer->struct_start;
-               /* write its offset */
-               if (!prs_uint32("offset", ps, depth, &relative_offset))
-                       return False;
-       }
-       else {
-               uint32 old_offset;
-               
-               /* read the offset */
-               if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
-                       return False;
-
-               if (buffer->string_at_end == 0)
-                       return True;
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
-                       return False;
-
-               /* read the string */
-               if (!smb_io_unistr(desc, string, ps, depth))
-                       return False;
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-/*******************************************************************
- * write a array of UNICODE strings and its relative pointer.
- * used by 2 RPC structs
- ********************************************************************/
-
-static BOOL smb_io_relarraystr(const char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
-{
-       UNISTR chaine;
-       
-       prs_struct *ps=&buffer->prs;
-       
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-               uint16 *p;
-               uint16 *q;
-               uint16 zero=0;
-               p=*string;
-               q=*string;
-
-               /* first write the last 0 */
-               buffer->string_at_end -= 2;
-               if(!prs_set_offset(ps, buffer->string_at_end))
-                       return False;
-
-               if(!prs_uint16("leading zero", ps, depth, &zero))
-                       return False;
-
-               while (p && (*p!=0)) {  
-                       while (*q!=0)
-                               q++;
-
-                       /* Yes this should be malloc not talloc. Don't change. */
-
-                       chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16));
-                       if (chaine.buffer == NULL)
-                               return False;
-
-                       memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
-
-                       buffer->string_at_end -= (q-p+1)*sizeof(uint16);
-
-                       if(!prs_set_offset(ps, buffer->string_at_end)) {
-                               SAFE_FREE(chaine.buffer);
-                               return False;
-                       }
-
-                       /* write the string */
-                       if (!smb_io_unistr(desc, &chaine, ps, depth)) {
-                               SAFE_FREE(chaine.buffer);
-                               return False;
-                       }
-                       q++;
-                       p=q;
-
-                       SAFE_FREE(chaine.buffer);
-               }
-               
-               if(!prs_set_offset(ps, struct_offset))
-                       return False;
-               
-               relative_offset=buffer->string_at_end - buffer->struct_start;
-               /* write its offset */
-               if (!prs_uint32("offset", ps, depth, &relative_offset))
-                       return False;
-
-       } else {
-
-               /* UNMARSHALLING */
-
-               uint32 old_offset;
-               uint16 *chaine2=NULL;
-               int l_chaine=0;
-               int l_chaine2=0;
-               size_t realloc_size = 0;
-
-               *string=NULL;
-                               
-               /* read the offset */
-               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
-                       return False;
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
-                       return False;
-       
-               do {
-                       if (!smb_io_unistr(desc, &chaine, ps, depth))
-                               return False;
-                       
-                       l_chaine=str_len_uni(&chaine);
-                       
-                       /* we're going to add two more bytes here in case this
-                          is the last string in the array and we need to add 
-                          an extra NULL for termination */
-                       if (l_chaine > 0)
-                       {
-                               uint16 *tc2;
-                       
-                               realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
-
-                               /* Yes this should be realloc - it's freed below. JRA */
-
-                               if((tc2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
-                                       SAFE_FREE(chaine2);
-                                       return False;
-                               }
-                               else chaine2 = tc2;
-                               memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
-                               l_chaine2+=l_chaine+1;
-                       }
-               
-               } while(l_chaine!=0);
-               
-               /* the end should be bould NULL terminated so add 
-                  the second one here */
-               if (chaine2)
-               {
-                       chaine2[l_chaine2] = '\0';
-                       *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
-                       SAFE_FREE(chaine2);
-               }
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
 /*******************************************************************
  Parse a DEVMODE structure and its relative pointer.
 ********************************************************************/
 
-static BOOL smb_io_relsecdesc(const char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
-{
-       prs_struct *ps= &buffer->prs;
-
-       prs_debug(ps, depth, desc, "smb_io_relsecdesc");
-       depth++;
-
-       if (MARSHALLING(ps)) {
-               uint32 struct_offset = prs_offset(ps);
-               uint32 relative_offset;
-
-               if (! *secdesc) {
-                       relative_offset = 0;
-                       if (!prs_uint32("offset", ps, depth, &relative_offset))
-                               return False;
-                       return True;
-               }
-               
-               if (*secdesc != NULL) {
-                       buffer->string_at_end -= sec_desc_size(*secdesc);
-
-                       if(!prs_set_offset(ps, buffer->string_at_end))
-                               return False;
-                       /* write the secdesc */
-                       if (!sec_io_desc(desc, secdesc, ps, depth))
-                               return False;
-
-                       if(!prs_set_offset(ps, struct_offset))
-                               return False;
-               }
-
-               relative_offset=buffer->string_at_end - buffer->struct_start;
-               /* write its offset */
-
-               if (!prs_uint32("offset", ps, depth, &relative_offset))
-                       return False;
-       } else {
-               uint32 old_offset;
-               
-               /* read the offset */
-               if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
-                       return False;
-
-               old_offset = prs_offset(ps);
-               if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
-                       return False;
-
-               /* read the sd */
-               if (!sec_io_desc(desc, secdesc, ps, depth))
-                       return False;
-
-               if(!prs_set_offset(ps, old_offset))
-                       return False;
-       }
-       return True;
-}
-
-/*******************************************************************
- Parse a DEVMODE structure and its relative pointer.
-********************************************************************/
-
-static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
+static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2457,7 +2145,7 @@ static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, D
  Parse a PRINTER_INFO_0 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
+BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2558,7 +2246,7 @@ BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0
  Parse a PRINTER_INFO_1 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
+BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2583,7 +2271,7 @@ BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1
  Parse a PRINTER_INFO_2 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
+BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
        uint32 dm_offset, sd_offset, current_offset;
@@ -2674,7 +2362,7 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
  Parse a PRINTER_INFO_3 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
+BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2695,7 +2383,7 @@ BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3
  Parse a PRINTER_INFO_4 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
+BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2717,7 +2405,7 @@ BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4
  Parse a PRINTER_INFO_5 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
+BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2743,7 +2431,7 @@ BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5
  Parse a PRINTER_INFO_7 structure.
 ********************************************************************/  
 
-BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
+BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2763,7 +2451,7 @@ BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7
  Parse a PORT_INFO_1 structure.
 ********************************************************************/  
 
-BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
+BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2782,7 +2470,7 @@ BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info,
  Parse a PORT_INFO_2 structure.
 ********************************************************************/  
 
-BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
+BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2809,7 +2497,7 @@ BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info,
  Parse a DRIVER_INFO_1 structure.
 ********************************************************************/
 
-BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
+BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2828,7 +2516,7 @@ BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_I
  Parse a DRIVER_INFO_2 structure.
 ********************************************************************/
 
-BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
+BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2857,7 +2545,7 @@ BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_I
  Parse a DRIVER_INFO_3 structure.
 ********************************************************************/
 
-BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
+BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2896,7 +2584,7 @@ BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_I
  Parse a DRIVER_INFO_6 structure.
 ********************************************************************/
 
-BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
+BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -2961,7 +2649,7 @@ BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_I
  Parse a JOB_INFO_1 structure.
 ********************************************************************/  
 
-BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
+BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3004,7 +2692,7 @@ BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, i
  Parse a JOB_INFO_2 structure.
 ********************************************************************/  
 
-BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
+BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
 {      
        uint32 pipo=0;
        prs_struct *ps=&buffer->prs;
@@ -3071,7 +2759,7 @@ BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, i
 /*******************************************************************
 ********************************************************************/  
 
-BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
+BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
        
@@ -3102,123 +2790,13 @@ BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth
        return True;
 }
 
-/*******************************************************************
- Read/write a BUFFER struct.
-********************************************************************/  
 
-static BOOL spoolss_io_buffer(const char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
-{
-       NEW_BUFFER *buffer = *pp_buffer;
-
-       prs_debug(ps, depth, desc, "spoolss_io_buffer");
-       depth++;
-       
-       if (UNMARSHALLING(ps))
-               buffer = *pp_buffer = PRS_ALLOC_MEM(ps, NEW_BUFFER, 1);
-
-       if (buffer == NULL)
-               return False;
-
-       if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
-               return False;
-       
-       /* reading */
-       if (UNMARSHALLING(ps)) {
-               buffer->size=0;
-               buffer->string_at_end=0;
-               
-               if (buffer->ptr==0) {
-                       /*
-                        * JRA. I'm not sure if the data in here is in big-endian format if
-                        * the client is big-endian. Leave as default (little endian) for now.
-                        */
-
-                       if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
-                               return False;
-                       return True;
-               }
-               
-               if (!prs_uint32("size", ps, depth, &buffer->size))
-                       return False;
-                                       
-               /*
-                * JRA. I'm not sure if the data in here is in big-endian format if
-                * the client is big-endian. Leave as default (little endian) for now.
-                */
-
-               if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
-                       return False;
-
-               if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
-                       return False;
-
-               if (!prs_set_offset(&buffer->prs, 0))
-                       return False;
-
-               if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
-                       return False;
-
-               buffer->string_at_end=buffer->size;
-               
-               return True;
-       }
-       else {
-               BOOL ret = False;
-
-               /* writing */
-               if (buffer->ptr==0) {
-                       /* We have finished with the data in buffer->prs - free it. */
-                       prs_mem_free(&buffer->prs);
-                       return True;
-               }
-       
-               if (!prs_uint32("size", ps, depth, &buffer->size))
-                       goto out;
-
-               if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
-                       goto out;
-
-               ret = True;
-       out:
-
-               /* We have finished with the data in buffer->prs - free it. */
-               prs_mem_free(&buffer->prs);
-
-               return ret;
-       }
-}
-
-/*******************************************************************
- move a BUFFER from the query to the reply.
- As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
- this is ok. This is an OPTIMIZATION and is not strictly neccessary.
- Clears the memory to zero also.
-********************************************************************/  
-
-void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
-{
-       prs_switch_type(&src->prs, MARSHALL);
-       if(!prs_set_offset(&src->prs, 0))
-               return;
-       prs_force_dynamic(&src->prs);
-       prs_mem_clear(&src->prs);
-       *dest=src;
-}
-
-/*******************************************************************
- Get the size of a BUFFER struct.
-********************************************************************/  
-
-uint32 new_get_buffer_size(NEW_BUFFER *buffer)
-{
-       return (buffer->size);
-}
 
 /*******************************************************************
  Parse a DRIVER_DIRECTORY_1 structure.
 ********************************************************************/  
 
-BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
+BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3237,7 +2815,7 @@ BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1
  Parse a PORT_INFO_1 structure.
 ********************************************************************/  
 
-BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
+BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3256,7 +2834,7 @@ BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int
  Parse a PORT_INFO_2 structure.
 ********************************************************************/  
 
-BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
+BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3282,7 +2860,7 @@ BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int
 /*******************************************************************
 ********************************************************************/  
 
-BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
+BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3300,7 +2878,7 @@ BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPRO
 /*******************************************************************
 ********************************************************************/  
 
-BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
+BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3318,7 +2896,7 @@ BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINT
 /*******************************************************************
 ********************************************************************/  
 
-BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
+BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3336,7 +2914,7 @@ BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONIT
 /*******************************************************************
 ********************************************************************/  
 
-BOOL smb_io_printmonitor_info_2(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
+BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -3859,7 +3437,7 @@ BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
                               const POLICY_HND *hnd,
                               const fstring architecture,
                               uint32 level, uint32 clientmajor, uint32 clientminor,
-                              NEW_BUFFER *buffer, uint32 offered)
+                              RPC_BUFFER *buffer, uint32 offered)
 {      
        if (q_u == NULL)
                return False;
@@ -3903,7 +3481,7 @@ BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2
        if(!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if(!prs_align(ps))
@@ -3933,7 +3511,7 @@ BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -3959,7 +3537,7 @@ BOOL make_spoolss_q_enumprinters(
        uint32 flags, 
        char *servername, 
        uint32 level, 
-       NEW_BUFFER *buffer, 
+       RPC_BUFFER *buffer, 
        uint32 offered
 )
 {
@@ -3981,7 +3559,7 @@ BOOL make_spoolss_q_enumprinters(
 
 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
                                fstring servername, uint32 level, 
-                               NEW_BUFFER *buffer, uint32 offered)
+                               RPC_BUFFER *buffer, uint32 offered)
 {
        q_u->name_ptr = (servername != NULL) ? 1 : 0;
        init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
@@ -4019,7 +3597,7 @@ BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
 
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4042,7 +3620,7 @@ BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4074,7 +3652,7 @@ BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_stru
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4107,7 +3685,7 @@ BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
 
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4127,7 +3705,7 @@ BOOL make_spoolss_q_getprinter(
        SPOOL_Q_GETPRINTER *q_u, 
        const POLICY_HND *hnd, 
        uint32 level, 
-       NEW_BUFFER *buffer, 
+       RPC_BUFFER *buffer, 
        uint32 offered
 )
 {
@@ -4349,7 +3927,7 @@ BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps,
        if(!prs_align(ps))
                return False;
        
-       if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if(!prs_align(ps))
@@ -4380,7 +3958,7 @@ BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps,
        if(!prs_uint32("level", ps, depth, &q_u->level))
                return False;
        
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if(!prs_align(ps))
@@ -4403,7 +3981,7 @@ BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4428,7 +4006,7 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
                                uint32 firstjob,
                                uint32 numofjobs,
                                uint32 level,
-                               NEW_BUFFER *buffer,
+                               RPC_BUFFER *buffer,
                                uint32 offered)
 {
        if (q_u == NULL)
@@ -4465,7 +4043,7 @@ BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
 
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;   
 
        if(!prs_align(ps))
@@ -4569,7 +4147,7 @@ BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVER
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4595,7 +4173,7 @@ BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
                                 const char *name,
                                 const char *environment,
                                 uint32 level,
-                                NEW_BUFFER *buffer, uint32 offered)
+                                RPC_BUFFER *buffer, uint32 offered)
 {
         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
@@ -4637,7 +4215,7 @@ BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVER
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4665,7 +4243,7 @@ BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;   
        
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4687,7 +4265,7 @@ BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4727,7 +4305,7 @@ BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;   
        
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4749,7 +4327,7 @@ BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4776,7 +4354,7 @@ BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -4815,7 +4393,7 @@ BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -5065,9 +4643,10 @@ BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_
 
        if(!prs_align(ps))
                return False;
-       if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
+
+       if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
                return False;
-       if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
+       if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
                return False;
 
        if(!prs_align(ps))
@@ -5815,7 +5394,7 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
 
 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
                                 fstring servername, fstring env_name, uint32 level,
-                                NEW_BUFFER *buffer, uint32 offered)
+                                RPC_BUFFER *buffer, uint32 offered)
 {
        init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
        init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
@@ -5857,7 +5436,7 @@ BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVER
        if(!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
                
        if(!prs_align(ps))
@@ -5881,7 +5460,7 @@ BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVER
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -5907,7 +5486,7 @@ BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESS
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -5955,7 +5534,7 @@ BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESS
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6029,7 +5608,7 @@ BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROC
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6077,7 +5656,7 @@ BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROC
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6112,7 +5691,7 @@ BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS
        if (!prs_uint32("level", ps, depth, &q_u->level))
                return False;
                
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6135,7 +5714,7 @@ BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6578,7 +6157,7 @@ BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps,
        if (!prs_align(ps))
                return False;
                
-       if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
 
        if (!prs_align(ps))
@@ -6612,7 +6191,7 @@ BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps,
        if(!prs_uint32("level", ps, depth, &q_u->level))
                return False;
        
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
 
        if(!prs_align(ps))
@@ -7463,7 +7042,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
        [in] unistr2 *name,
        [in] unistr2 *environment,
        [in] uint32 level,
-       [in,out] NEW_BUFFER buffer,
+       [in,out] RPC_BUFFER buffer,
        [in] uint32 offered,
        [out] uint32 needed,
        [out] uint32 returned
@@ -7471,7 +7050,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
 
 */
 
-BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
 {
        DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
 
@@ -7522,7 +7101,7 @@ BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTP
        if(!prs_uint32("level",   ps, depth, &q_u->level))
                return False;
 
-       if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
                return False;
        
        if(!prs_align(ps))
@@ -7546,7 +7125,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP
        if(!prs_align(ps))
                return False;
 
-       if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+       if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
                return False;
        
        if(!prs_align(ps))
@@ -7561,7 +7140,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP
        return True;
 }
 
-BOOL smb_io_printprocessordirectory_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
+BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
 {
        prs_struct *ps=&buffer->prs;
 
@@ -7625,7 +7204,7 @@ BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle,
 
 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
                             const char *formname, uint32 level, 
-                           NEW_BUFFER *buffer, uint32 offered)
+                           RPC_BUFFER *buffer, uint32 offered)
 {
         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
         q_u->level = level;
@@ -7641,7 +7220,7 @@ BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
  ********************************************************************/
 
 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
-                             uint32 level, NEW_BUFFER *buffer,
+                             uint32 level, RPC_BUFFER *buffer,
                              uint32 offered)
 {
         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
@@ -7676,7 +7255,7 @@ BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
  ********************************************************************/
 
 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
-                          uint32 jobid, uint32 level, NEW_BUFFER *buffer,
+                          uint32 jobid, uint32 level, RPC_BUFFER *buffer,
                           uint32 offered)
 {
         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
index 84c45b59014a67fde2a560ca90a72fdf347bbccc..7d15eda630f908074d8e03717c5aa832215c21b3 100644 (file)
@@ -1995,6 +1995,79 @@ BOOL srv_io_r_net_sess_enum(const char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_stru
        return True;
 }
 
+/*******************************************************************
+ Inits a SRV_Q_NET_SESS_DEL structure.
+********************************************************************/
+
+void init_srv_q_net_sess_del(SRV_Q_NET_SESS_DEL *q_n, const char *srv_name,
+                             const char *cli_name, const char *user_name)
+{
+       DEBUG(5,("init_q_net_sess_enum\n"));
+
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_cli_name, &q_n->ptr_cli_name, cli_name);
+       init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name);
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+BOOL srv_io_q_net_sess_del(const char *desc, SRV_Q_NET_SESS_DEL *q_n, prs_struct *ps, int depth)
+{
+       if (q_n == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_q_net_sess_del");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_cli_name", ps, depth, &q_n->ptr_cli_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_cli_name, q_n->ptr_cli_name, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+BOOL srv_io_r_net_sess_del(const char *desc, SRV_R_NET_SESS_DEL *r_n, prs_struct *ps, int depth)
+{
+       if (r_n == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_r_net_sess_del");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_n->status))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  Inits a CONN_INFO_0 structure
 ********************************************************************/
diff --git a/source/rpc_parse/parse_svcctl.c b/source/rpc_parse/parse_svcctl.c
new file mode 100644 (file)
index 0000000..1c41a18
--- /dev/null
@@ -0,0 +1,660 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Gerald (Jerry) Carter             2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/*******************************************************************
+********************************************************************/
+
+static BOOL svcctl_io_service_status( const char *desc, SERVICE_STATUS *status, prs_struct *ps, int depth )
+{
+
+       prs_debug(ps, depth, desc, "svcctl_io_service_status");
+       depth++;
+
+       if(!prs_uint32("type", ps, depth, &status->type))
+               return False;
+
+       if(!prs_uint32("state", ps, depth, &status->state))
+               return False;
+
+       if(!prs_uint32("controls_accepted", ps, depth, &status->controls_accepted))
+               return False;
+
+       if(!prs_uint32("win32_exit_code", ps, depth, &status->win32_exit_code))
+               return False;
+
+       if(!prs_uint32("service_exit_code", ps, depth, &status->service_exit_code))
+               return False;
+
+       if(!prs_uint32("check_point", ps, depth, &status->check_point))
+               return False;
+
+       if(!prs_uint32("wait_hint", ps, depth, &status->wait_hint))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config, prs_struct *ps, int depth )
+{
+
+       prs_debug(ps, depth, desc, "svcctl_io_service_config");
+       depth++;
+
+       if(!prs_uint32("service_type", ps, depth, &config->service_type))
+               return False;
+       if(!prs_uint32("start_type", ps, depth, &config->start_type))
+               return False;
+       if(!prs_uint32("error_control", ps, depth, &config->error_control))
+               return False;
+
+       if (!prs_io_unistr2_p("", ps, depth, &config->executablepath))
+               return False;
+       if (!prs_io_unistr2_p("", ps, depth, &config->loadordergroup))
+               return False;
+
+       if(!prs_uint32("tag_id", ps, depth, &config->tag_id))
+               return False;
+
+       if (!prs_io_unistr2_p("", ps, depth, &config->dependencies))
+               return False;
+       if (!prs_io_unistr2_p("", ps, depth, &config->startname))
+               return False;
+       if (!prs_io_unistr2_p("", ps, depth, &config->displayname))
+               return False;
+
+       if (!prs_io_unistr2("", ps, depth, config->executablepath))
+               return False;
+       if (!prs_io_unistr2("", ps, depth, config->loadordergroup))
+               return False;
+       if (!prs_io_unistr2("", ps, depth, config->dependencies))
+               return False;
+       if (!prs_io_unistr2("", ps, depth, config->startname))
+               return False;
+       if (!prs_io_unistr2("", ps, depth, config->displayname))
+               return False;
+
+       return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth )
+{
+       prs_struct *ps=&buffer->prs;
+       
+       prs_debug(ps, depth, desc, "svcctl_io_enum_services_status");
+       depth++;
+       
+       if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) )
+               return False;
+       if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) )
+               return False;
+
+       if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) )
+               return False;
+       
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status )
+{
+       uint32 size = 0;
+       
+       size += size_of_relative_string( &status->servicename );
+       size += size_of_relative_string( &status->displayname );
+       size += sizeof(SERVICE_STATUS);
+
+       return size;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_close_service(const char *desc, SVCCTL_Q_CLOSE_SERVICE *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_close_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+               return False;
+
+       return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_close_service(const char *desc, SVCCTL_R_CLOSE_SERVICE *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_close_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_open_scmanager(const char *desc, SVCCTL_Q_OPEN_SCMANAGER *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_open_scmanager");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_pointer("servername", ps, depth, (void**)&q_u->servername, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_pointer("database", ps, depth, (void**)&q_u->database, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("access", ps, depth, &q_u->access))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_open_scmanager(const char *desc, SVCCTL_R_OPEN_SCMANAGER *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_open_scmanager");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("scm_pol", &r_u->handle, ps, depth))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_get_display_name(const char *desc, SVCCTL_Q_GET_DISPLAY_NAME *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_get_display_name");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("display_name_len", ps, depth, &q_u->display_name_len))
+               return False;
+       
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL init_svcctl_r_get_display_name( SVCCTL_R_GET_DISPLAY_NAME *r_u, const char *displayname )
+{
+       r_u->display_name_len = strlen(displayname);
+       init_unistr2( &r_u->displayname, displayname, UNI_STR_TERMINATE );
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_get_display_name(const char *desc, SVCCTL_R_GET_DISPLAY_NAME *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_get_display_name");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       
+       if(!smb_io_unistr2("displayname", &r_u->displayname, 1, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("display_name_len", ps, depth, &r_u->display_name_len))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_open_service(const char *desc, SVCCTL_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_open_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("access", ps, depth, &q_u->access))
+               return False;
+       
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_open_service(const char *desc, SVCCTL_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_open_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &r_u->handle, ps, depth))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_query_status(const char *desc, SVCCTL_Q_QUERY_STATUS *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_query_status");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+               return False;
+       
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_query_status(const char *desc, SVCCTL_R_QUERY_STATUS *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_query_status");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_enum_services_status(const char *desc, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_enum_services_status");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!prs_uint32("type", ps, depth, &q_u->type))
+               return False;
+       if(!prs_uint32("state", ps, depth, &q_u->state))
+               return False;
+       if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+               return False;
+
+       if(!prs_pointer("resume", ps, depth, (void**)&q_u->resume, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
+               return False;
+       
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_enum_services_status(const char *desc, SVCCTL_R_ENUM_SERVICES_STATUS *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_enum_services_status");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if (!prs_rpcbuffer("", ps, depth, &r_u->buffer))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
+       if(!prs_uint32("returned", ps, depth, &r_u->returned))
+               return False;
+
+       if(!prs_pointer("resume", ps, depth, (void**)&r_u->resume, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_start_service(const char *desc, SVCCTL_Q_START_SERVICE *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_start_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!prs_uint32("parmcount", ps, depth, &q_u->parmcount))
+               return False;
+
+       if ( !prs_pointer("rights", ps, depth, (void**)&q_u->parameters, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_start_service(const char *desc, SVCCTL_R_START_SERVICE *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_start_service");
+       depth++;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_enum_dependent_services(const char *desc, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_enum_dependent_services");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!prs_uint32("state", ps, depth, &q_u->state))
+               return False;
+       if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_enum_dependent_services(const char *desc, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_enum_dependent_services");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if (!prs_rpcbuffer("", ps, depth, &r_u->buffer))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
+       if(!prs_uint32("returned", ps, depth, &r_u->returned))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_control_service(const char *desc, SVCCTL_Q_CONTROL_SERVICE *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_control_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!prs_uint32("control", ps, depth, &q_u->control))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_control_service(const char *desc, SVCCTL_R_CONTROL_SERVICE *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_control_service");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_query_service_config(const char *desc, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_q_query_service_config");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+               return False;
+
+       if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_query_service_config(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u, prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!svcctl_io_service_config("config", &r_u->config, ps, depth))
+               return False;
+
+       if(!prs_uint32("needed", ps, depth, &r_u->needed))
+               return False;
+
+       if(!prs_werror("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
+
diff --git a/source/rpc_server/srv_eventlog.c b/source/rpc_server/srv_eventlog.c
new file mode 100644 (file)
index 0000000..07aebcd
--- /dev/null
@@ -0,0 +1,206 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+static BOOL api_eventlog_open_eventlog(pipes_struct *p)
+{
+       EVENTLOG_Q_OPEN_EVENTLOG q_u;
+       EVENTLOG_R_OPEN_EVENTLOG r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_open_eventlog("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_open_eventlog: unable to unmarshall EVENTLOG_Q_OPEN_EVENTLOG.\n"));
+               return False;
+       }
+       
+       r_u.status = _eventlog_open_eventlog(p, &q_u, &r_u);
+
+       if (!(eventlog_io_r_open_eventlog("", &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_r_open_eventlog: unable to marshall EVENTLOG_R_OPEN_EVENTLOG.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+static BOOL api_eventlog_close_eventlog(pipes_struct *p)
+{
+       EVENTLOG_Q_CLOSE_EVENTLOG q_u;
+       EVENTLOG_R_CLOSE_EVENTLOG r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_close_eventlog("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_close_eventlog: unable to unmarshall EVENTLOG_Q_CLOSE_EVENTLOG.\n"));
+               return False;
+       }
+
+       r_u.status = _eventlog_close_eventlog(p, &q_u, &r_u);
+
+       if (!(eventlog_io_r_close_eventlog("", &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_r_close_eventlog: unable to marshall EVENTLOG_R_CLOSE_EVENTLOG.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+static BOOL api_eventlog_get_num_records(pipes_struct *p)
+{
+       EVENTLOG_Q_GET_NUM_RECORDS q_u;
+       EVENTLOG_R_GET_NUM_RECORDS r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_get_num_records("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_get_num_records: unable to unmarshall EVENTLOG_Q_GET_NUM_RECORDS.\n"));
+               return False;
+       }
+    
+       r_u.status = _eventlog_get_num_records(p, &q_u, &r_u);
+    
+       if (!(eventlog_io_r_get_num_records("", &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_r_get_num_records: unable to marshall EVENTLOG_R_GET_NUM_RECORDS.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+static BOOL api_eventlog_get_oldest_entry(pipes_struct *p)
+{
+       EVENTLOG_Q_GET_OLDEST_ENTRY q_u;
+       EVENTLOG_R_GET_OLDEST_ENTRY r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_get_oldest_entry("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_get_oldest_entry: unable to unmarshall EVENTLOG_Q_GET_OLDEST_ENTRY.\n"));
+               return False;
+       }
+
+       r_u.status = _eventlog_get_oldest_entry(p, &q_u, &r_u);
+    
+       if (!(eventlog_io_r_get_oldest_entry("", &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_r_get_oldest_entry: unable to marshall EVENTLOG_R_GET_OLDEST_ENTRY.\n"));
+               return False;
+       }
+    
+       return True;
+}
+
+static BOOL api_eventlog_read_eventlog(pipes_struct *p)
+{
+       EVENTLOG_Q_READ_EVENTLOG q_u;
+       EVENTLOG_R_READ_EVENTLOG r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_read_eventlog("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_read_eventlog: unable to unmarshall EVENTLOG_Q_READ_EVENTLOG.\n"));
+               return False;
+       }
+
+       r_u.status = _eventlog_read_eventlog(p, &q_u, &r_u);
+
+       if (!(eventlog_io_r_read_eventlog("", &q_u, &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_r_read_eventlog: unable to marshall EVENTLOG_R_READ_EVENTLOG.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+static BOOL api_eventlog_clear_eventlog(pipes_struct *p)
+{
+       EVENTLOG_Q_CLEAR_EVENTLOG q_u;
+       EVENTLOG_R_CLEAR_EVENTLOG r_u;
+
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if (!(eventlog_io_q_clear_eventlog("", &q_u, data, 0))) {
+               DEBUG(0, ("eventlog_io_q_clear_eventlog: unable to unmarshall EVENTLOG_Q_CLEAR_EVENTLOG.\n"));
+               return False;
+       }
+
+       r_u.status = _eventlog_clear_eventlog(p, &q_u, &r_u);
+
+       if (!(eventlog_io_r_clear_eventlog("", &r_u, rdata, 0))) {
+               DEBUG(0, ("eventlog_io_q_clear_eventlog: unable to marshall EVENTLOG_Q_CLEAR_EVENTLOG.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+/*
+ \pipe\eventlog commands
+*/
+struct api_struct api_eventlog_cmds[] =
+{
+       {"EVENTLOG_OPENEVENTLOG",       EVENTLOG_OPENEVENTLOG,          api_eventlog_open_eventlog    },
+       {"EVENTLOG_CLOSEVENTLOG",       EVENTLOG_CLOSEEVENTLOG,         api_eventlog_close_eventlog   },
+       {"EVENTLOG_GETNUMRECORDS",      EVENTLOG_GETNUMRECORDS,         api_eventlog_get_num_records  },
+       {"EVENTLOG_GETOLDESTENTRY",     EVENTLOG_GETOLDESTENTRY,        api_eventlog_get_oldest_entry },
+       {"EVENTLOG_READEVENTLOG",       EVENTLOG_READEVENTLOG,          api_eventlog_read_eventlog    },
+       {"EVENTLOG_CLEAREVENTLOG",      EVENTLOG_CLEAREVENTLOG,         api_eventlog_clear_eventlog   }
+};
+
+NTSTATUS rpc_eventlog_init(void)
+{
+       return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, 
+               "eventlog", "eventlog", api_eventlog_cmds,
+               sizeof(api_eventlog_cmds)/sizeof(struct api_struct));
+}
+
+void eventlog_get_pipe_fns(struct api_struct **fns, int *n_fns)
+{
+       *fns = api_eventlog_cmds;
+       *n_fns = sizeof(api_eventlog_cmds) / sizeof(struct api_struct);
+}
diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c
new file mode 100644 (file)
index 0000000..7501434
--- /dev/null
@@ -0,0 +1,923 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+typedef struct eventlog_info
+{
+    /* for use by the \PIPE\eventlog policy */
+    fstring source_log_file_name;
+    fstring source_server_name;
+    fstring handle_string;
+    uint32 num_records;
+    uint32 oldest_entry;
+} Eventlog_info;
+
+static void free_eventlog_info(void *ptr)
+{
+    struct eventlog_info *info = (struct eventlog_info *)ptr;
+    memset(info->source_log_file_name, '0', sizeof(*(info->source_log_file_name)));
+    memset(info->source_server_name, '0', sizeof(*(info->source_server_name)));
+    memset(info->handle_string, '0', sizeof(*(info->handle_string)));
+    memset(info, 0, sizeof(*(info)));
+    SAFE_FREE(info);
+}
+
+static Eventlog_info *find_eventlog_info_by_hnd(pipes_struct *p,
+                                               POLICY_HND *handle)
+{
+    Eventlog_info *info = NULL;
+    
+    if(!(find_policy_by_hnd(p,handle,(void **)&info)))
+    {
+       DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
+    }
+
+    return info;
+}
+
+void policy_handle_to_string(POLICY_HND *handle, fstring *dest)
+{
+    memset(dest, 0, sizeof(*dest));
+    snprintf((char *)dest, sizeof(*dest), "%08X-%08X-%04X-%04X-%02X%02X%02X%02X%02X",
+            handle->data1,
+            handle->data2,
+            handle->data3,
+            handle->data4,
+            handle->data5[0],
+            handle->data5[1],
+            handle->data5[2],
+            handle->data5[3],
+            handle->data5[4]);
+}
+
+/**
+ * Callout to open the specified event log
+ * 
+ *   smbrun calling convention --
+ *     INPUT: <open_cmd> <log name> <policy handle>
+ *     OUTPUT: the string "SUCCESS" if the command succeeded
+ *             no such string if there was a failure.
+ */
+static BOOL _eventlog_open_eventlog_hook(Eventlog_info *info)
+{
+    char *cmd = lp_eventlog_open_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
+       return False;
+    }
+
+    memset(command, 0, sizeof(command));
+    slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+            cmd,
+            info->source_log_file_name,
+            info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+
+    if(numlines)
+    {
+       DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+       if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+       {
+           DEBUGADD(10, ("Able to open [%s].\n", info->source_log_file_name));
+           file_lines_free(qlines);
+           return True;
+       }
+    }
+
+    file_lines_free(qlines);
+    return False;
+}
+
+WERROR _eventlog_open_eventlog(pipes_struct *p,
+                              EVENTLOG_Q_OPEN_EVENTLOG *q_u,
+                              EVENTLOG_R_OPEN_EVENTLOG *r_u)
+{
+    Eventlog_info *info = NULL;
+    
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+    
+    if((info = SMB_MALLOC_P(Eventlog_info)) == NULL)
+       return WERR_NOMEM;
+    
+    ZERO_STRUCTP(info);
+
+    if(q_u->servername_ptr != 0)
+    {
+       unistr2_to_ascii(info->source_server_name, &(q_u->servername), sizeof(info->source_server_name));
+    }
+    else
+    {
+       /* if servername == NULL, use the local computer */
+       fstrcpy(info->source_server_name, global_myname());
+    }
+    DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info->source_server_name));
+
+    if(q_u->sourcename_ptr != 0)
+    {
+       unistr2_to_ascii(info->source_log_file_name, &(q_u->sourcename), sizeof(info->source_log_file_name));
+    }
+    else
+    {
+        /* if sourcename == NULL, default to "Application" log */
+       fstrcpy(info->source_log_file_name, "Application");
+    }
+    DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->source_log_file_name));
+
+    if(!create_policy_hnd(p, &(r_u->handle), free_eventlog_info, (void *)info))
+       return WERR_NOMEM;
+
+    policy_handle_to_string(&r_u->handle, &info->handle_string);
+
+    if(!(_eventlog_open_eventlog_hook(info)))
+       return WERR_BADFILE;
+
+    return WERR_OK;
+}
+/**
+ * Callout to get the number of records in the specified event log
+ * 
+ *   smbrun calling convention --
+ *     INPUT: <get_num_records_cmd> <log name> <policy handle>
+ *     OUTPUT: A single line with a single integer containing the number of
+ *             entries in the log. If there are no entries in the log, return 0.
+ */
+static BOOL _eventlog_get_num_records_hook(Eventlog_info *info)
+{
+    char *cmd = lp_eventlog_num_records_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
+       return False;
+    }
+
+    memset(command, 0, sizeof(command));
+    slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", 
+            cmd,
+            info->source_log_file_name,
+            info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+
+    if(numlines)
+    {
+       DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+       sscanf(qlines[0], "%d", &(info->num_records));
+       file_lines_free(qlines);
+       return True;
+    }
+
+    file_lines_free(qlines);
+    return False;
+}
+
+WERROR _eventlog_get_num_records(pipes_struct *p,
+                                EVENTLOG_Q_GET_NUM_RECORDS *q_u,
+                                EVENTLOG_R_GET_NUM_RECORDS *r_u)
+{
+    Eventlog_info *info = NULL;
+    POLICY_HND *handle = NULL;
+
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+
+    handle = &(q_u->handle);
+    info = find_eventlog_info_by_hnd(p, handle);
+
+    if(!(_eventlog_get_num_records_hook(info)))
+       return WERR_BADFILE;
+
+    r_u->num_records = info->num_records;
+
+    return WERR_OK;
+}
+/**
+ * Callout to find the oldest record in the log
+ * 
+ *   smbrun calling convention --
+ *     INPUT: <oldest_entry_cmd> <log name> <policy handle>
+ *     OUTPUT: If there are entries in the event log, the index of the
+ *             oldest entry. Must be 1 or greater.
+ *             If there are no entries in the log, returns a 0
+ */
+static BOOL _eventlog_get_oldest_entry_hook(Eventlog_info *info)
+{
+    char *cmd = lp_eventlog_oldest_record_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
+       return False;
+    }
+
+    memset(command, 0, sizeof(command));
+    slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", 
+            cmd,
+            info->source_log_file_name,
+            info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+
+    if(numlines)
+    {
+       DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+       sscanf(qlines[0], "%d", &(info->oldest_entry));
+       file_lines_free(qlines);
+       return True;
+    }
+
+    file_lines_free(qlines);
+    return False;
+}
+
+WERROR _eventlog_get_oldest_entry(pipes_struct *p,
+                                 EVENTLOG_Q_GET_OLDEST_ENTRY *q_u,
+                                 EVENTLOG_R_GET_OLDEST_ENTRY *r_u)
+{
+    Eventlog_info *info = NULL;
+    POLICY_HND *handle = NULL;
+
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+
+    handle = &(q_u->handle);
+    info = find_eventlog_info_by_hnd(p, handle);
+
+    if(!(_eventlog_get_oldest_entry_hook(info)))
+       return WERR_BADFILE;
+
+    r_u->oldest_entry = info->oldest_entry;
+
+    return WERR_OK;
+}
+
+/**
+ * Callout to close the specified event log
+ * 
+ *   smbrun calling convention --
+ *     INPUT: <close_cmd> <log name> <policy handle>
+ *     OUTPUT: the string "SUCCESS" if the command succeeded
+ *             no such string if there was a failure.
+ */
+static BOOL _eventlog_close_eventlog_hook(Eventlog_info *info)
+{
+    char *cmd = lp_eventlog_close_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
+       return False;
+    }
+
+    memset(command, 0, sizeof(command));
+    slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", 
+            cmd, 
+            info->source_log_file_name, 
+            info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+
+    if(numlines)
+    {
+       DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+       if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+       {
+           DEBUGADD(10, ("Able to close [%s].\n", info->source_log_file_name));
+           file_lines_free(qlines);
+           return True;
+       }
+    }
+
+    file_lines_free(qlines);
+    return False;
+}
+
+WERROR _eventlog_close_eventlog(pipes_struct *p,
+                               EVENTLOG_Q_CLOSE_EVENTLOG *q_u,
+                               EVENTLOG_R_CLOSE_EVENTLOG *r_u)
+{
+    Eventlog_info *info = NULL;
+    POLICY_HND *handle;
+
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+
+    handle = &(q_u->handle);
+    
+    info = find_eventlog_info_by_hnd(p, handle);
+    if(!(_eventlog_close_eventlog_hook(info)))
+       return WERR_BADFILE;
+
+    if(!(close_policy_hnd(p, handle)))
+    {
+       /* WERR_NOMEM is probably not the correct error, but until I figure out a better
+          one it will have to do */
+       return WERR_NOMEM;
+    }
+
+    return WERR_OK;
+}
+
+static BOOL _eventlog_read_parse_line(char *line, Eventlog_entry *entry)
+{
+    char *start = NULL, *stop = NULL;
+    pstring temp;
+    int temp_len = 0, i;
+    start = line;
+
+    if(start == NULL || strlen(start) == 0)
+       return False;
+    if(!(stop = strchr(line, ':')))
+       return False;
+    
+    DEBUG(6, ("_eventlog_read_parse_line: trying to parse [%s].\n", line));
+
+    if(0 == strncmp(start, "LEN", stop - start))
+    {
+       /* This will get recomputed later anyway -- probably not necessary */
+       entry->record.length = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "RS1", stop - start))
+    {
+       /* For now all these reserved entries seem to have the same value,
+          which can be hardcoded to int(1699505740) for now */
+       entry->record.reserved1 = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "RCN", stop - start))
+    {
+       entry->record.record_number = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "TMG", stop - start))
+    {
+       entry->record.time_generated = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "TMW", stop - start))
+    {
+       entry->record.time_written = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "EID", stop - start))
+    {
+       entry->record.event_id = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "ETP", stop - start))
+    {
+       if(strstr(start, "ERROR"))
+       {
+           entry->record.event_type = EVENTLOG_ERROR_TYPE;
+       }
+       else if(strstr(start, "WARNING"))
+       {
+           entry->record.event_type = EVENTLOG_WARNING_TYPE;
+       }
+       else if(strstr(start, "INFO"))
+       {
+           entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
+       }
+       else if(strstr(start, "AUDIT_SUCCESS"))
+       {
+           entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
+       }
+       else if(strstr(start, "AUDIT_FAILURE"))
+       {
+           entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
+       }
+       else if(strstr(start, "SUCCESS"))
+       {
+           entry->record.event_type = EVENTLOG_SUCCESS;
+       }
+       else
+       {
+           /* some other eventlog type -- currently not defined in MSDN docs, so error out */
+           return False;
+       }
+    }
+/*
+    else if(0 == strncmp(start, "NST", stop - start))
+    {
+       entry->record.num_strings = atoi(stop + 1);
+    }
+*/
+    else if(0 == strncmp(start, "ECT", stop - start))
+    {
+       entry->record.event_category = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "RS2", stop - start))
+    {
+       entry->record.reserved2 = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "CRN", stop - start))
+    {
+       entry->record.closing_record_number = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "USL", stop - start))
+    {
+       entry->record.user_sid_length = atoi(stop + 1);
+    }
+    else if(0 == strncmp(start, "SRC", stop - start))
+    {
+       memset(temp, 0, sizeof(temp));
+       sscanf(stop+1, "%s", temp);
+       temp_len = strlen(temp);
+       rpcstr_push((void *)(entry->data_record.source_name), temp, 
+                   sizeof(entry->data_record.source_name), STR_TERMINATE);
+       entry->data_record.source_name_len = (strlen_w(entry->data_record.source_name)* 2) + 2;
+    }
+    else if(0 == strncmp(start, "SRN", stop - start))
+    {
+       memset(temp, 0, sizeof(temp));
+       sscanf(stop+1, "%s", temp);
+       temp_len = strlen(temp);
+       rpcstr_push((void *)(entry->data_record.computer_name), temp,
+                   sizeof(entry->data_record.computer_name), STR_TERMINATE);
+       entry->data_record.computer_name_len = (strlen_w(entry->data_record.computer_name)* 2) + 2;
+    }
+    else if(0 == strncmp(start, "SID", stop - start))
+    {
+       memset(temp, 0, sizeof(temp));
+       sscanf(stop+1, "%s", temp);
+       temp_len = strlen(temp);
+       rpcstr_push((void *)(entry->data_record.sid), temp,
+                   sizeof(entry->data_record.sid), STR_TERMINATE);
+       entry->record.user_sid_length = (strlen_w(entry->data_record.sid) * 2) + 2;
+    }
+    else if(0 == strncmp(start, "STR", stop - start))
+    {
+       /* skip past initial ":" */
+       stop++;
+       /* now skip any other leading whitespace */
+       while(isspace(stop[0]))
+           stop++;
+       temp_len = strlen(stop);
+       memset(temp, 0, sizeof(temp));
+       strncpy(temp, stop, temp_len);
+       rpcstr_push((void *)(entry->data_record.strings + entry->data_record.strings_len),
+                   temp,
+                   sizeof(entry->data_record.strings) - entry->data_record.strings_len, 
+                   STR_TERMINATE);
+       entry->data_record.strings_len += temp_len + 1;
+       fprintf(stderr, "Dumping strings:\n");
+       for(i = 0; i < entry->data_record.strings_len; i++)
+       {
+           fputc((char)entry->data_record.strings[i], stderr);
+       }
+       fprintf(stderr, "\nDone\n");
+       entry->record.num_strings++;
+    }
+    else if(0 == strncmp(start, "DAT", stop - start))
+    {
+       /* Now that we're done processing the STR data, adjust the length to account for
+          unicode, then proceed with the DAT data. */
+       entry->data_record.strings_len *= 2;
+       /* skip past initial ":" */
+       stop++;
+       /* now skip any other leading whitespace */
+       while(isspace(stop[0]))
+           stop++;
+       memset(temp, 0, sizeof(temp));
+       temp_len = strlen(stop);
+       strncpy(temp, stop, temp_len);
+       rpcstr_push((void *)(entry->data_record.user_data), temp,
+                   sizeof(entry->data_record.user_data), STR_TERMINATE);
+       entry->data_record.user_data_len = (strlen_w((const smb_ucs2_t *)entry->data_record.user_data) * 2) + 2;
+    }
+    else
+    {
+       /* some other eventlog entry -- not implemented, so dropping on the floor */
+       DEBUG(10, ("Unknown entry [%s]. Ignoring.\n", line));
+       /* For now return true so that we can keep on parsing this mess. Eventually
+          we will return False here. */
+       return True;
+    }
+    return True;
+}
+/**
+ * Callout to read entries from the specified event log
+ *
+ *   smbrun calling convention --
+ *     INPUT: <read_cmd> <log name> <direction> <starting record> <buffer size> <policy handle>
+ *            where direction is either "forward" or "backward", the starting record is somewhere
+ *            between the oldest_record and oldest_record+num_records, and the buffer size is the
+ *            maximum size of the buffer that the client can accomodate.
+ *     OUTPUT: A buffer containing a set of entries, one to a line, of the format:
+ *               line type:line data
+ *             These are the allowed line types:
+ *               RS1:(uint32) - reserved. All M$ entries seem to have int(1699505740) for now
+ *               RCN:(uint32) - record number of the record, however it may be calculated by the script
+ *               TMG:(uint32) - time generated, seconds since January 1, 1970, 0000 UTC
+ *               TMW:(uint32) - time written, seconds since January 1, 1970, 0000 UTC
+ *               EID:(uint32) - eventlog source defined event identifier. If there's a stringfile for the event, it is an index into that
+ *               ETP:(uint16) - eventlog type - one of ERROR, WARNING, INFO, AUDIT_SUCCESS, AUDIT_FAILURE
+ *               ECT:(uint16) - event category - depends on the eventlog generator... 
+ *               RS2:(uint16) - reserved, make it 0000
+ *               CRN:(uint32) - reserved, make it 00000000 for now
+ *               USL:(uint32) - user SID length. No sid? Make this 0. Must match SID below
+ *               SRC:[(uint8)] - Name of the source, for example ccPwdSvc, in hex bytes. Can not be multiline.
+ *               SRN:[(uint8)] - Name of the computer on which this is generated, the short hostname usually.
+ *               SID:[(uint8)] - User sid if one exists. Must be present even if there is no SID.
+ *               STR:[(uint8)] - String data. One string per line. Multiple strings can be specified using consecutive "STR" lines,
+ *                               up to a total aggregate string length of 1024 characters.
+ *               DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
+ */
+static BOOL _eventlog_read_eventlog_hook(Eventlog_info *info, Eventlog_entry *entry, const char *direction, int starting_record, int buffer_size, BOOL *eof)
+{
+    char *cmd = lp_eventlog_read_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+    int i;
+
+    if(info == NULL)
+       return False;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
+       return False;
+    }
+
+    slprintf(command, sizeof(command)-1, "%s \"%s\" %s %d %d \"%s\"",
+            cmd,
+            info->source_log_file_name,
+            direction,
+            starting_record,
+            buffer_size,
+            info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+    
+    if(numlines)
+    {
+       for(i = 0; i < numlines; i++)
+       {
+           DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
+           _eventlog_read_parse_line(qlines[i], entry);
+       }
+       file_lines_free(qlines);
+       return True;
+    }
+    else
+       *eof = True;
+
+    file_lines_free(qlines);
+    return False;
+}
+       
+static BOOL _eventlog_read_prepare_data_buffer(prs_struct *ps,
+                                              EVENTLOG_Q_READ_EVENTLOG *q_u,
+                                              EVENTLOG_R_READ_EVENTLOG *r_u,
+                                              Eventlog_entry *entry)
+{
+    uint8 *offset;
+    Eventlog_entry *new = NULL, *insert_point = NULL;
+
+    new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
+    if(new == NULL)
+       return False;
+
+    entry->data_record.sid_padding = ((4 - ((entry->data_record.source_name_len 
+                                     + entry->data_record.computer_name_len) % 4)) %4);
+    entry->data_record.data_padding = (4 - ((entry->data_record.strings_len 
+                                          + entry->data_record.user_data_len) % 4)) % 4;
+    entry->record.length = sizeof(Eventlog_record);
+    entry->record.length += entry->data_record.source_name_len;
+    entry->record.length += entry->data_record.computer_name_len;
+    if(entry->record.user_sid_length == 0)
+    {
+       /* Should not pad to a DWORD boundary for writing out the sid if there is
+          no SID, so just propagate the padding to pad the data */
+       entry->data_record.data_padding += entry->data_record.sid_padding;
+       entry->data_record.sid_padding = 0;
+    }
+    DEBUG(10, ("sid_padding is [%d].\n", entry->data_record.sid_padding));
+    DEBUG(10, ("data_padding is [%d].\n", entry->data_record.data_padding));
+
+    entry->record.length += entry->data_record.sid_padding;
+    entry->record.length += entry->record.user_sid_length;
+    entry->record.length += entry->data_record.strings_len;
+    entry->record.length += entry->data_record.user_data_len;
+    entry->record.length += entry->data_record.data_padding;
+    /* need another copy of length at the end of the data */
+    entry->record.length += sizeof(entry->record.length);
+    DEBUG(10, ("entry->record.length is [%d].\n", entry->record.length));
+    entry->data = PRS_ALLOC_MEM(ps, uint8, entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length));
+    if(entry->data == NULL)
+       return False;
+    offset = entry->data;
+    memcpy(offset, &(entry->data_record.source_name), entry->data_record.source_name_len);
+    offset += entry->data_record.source_name_len;
+    memcpy(offset, &(entry->data_record.computer_name), entry->data_record.computer_name_len);
+    offset += entry->data_record.computer_name_len;
+    /* SID needs to be DWORD-aligned */
+    offset += entry->data_record.sid_padding;
+    entry->record.user_sid_offset = sizeof(Eventlog_record) + (offset - entry->data);
+    memcpy(offset, &(entry->data_record.sid), entry->record.user_sid_length);
+    offset += entry->record.user_sid_length;
+    /* Now do the strings */
+    entry->record.string_offset = sizeof(Eventlog_record) + (offset - entry->data);
+    memcpy(offset, &(entry->data_record.strings), entry->data_record.strings_len);
+    offset += entry->data_record.strings_len;
+    /* Now do the data */
+    entry->record.data_length = entry->data_record.user_data_len;
+    entry->record.data_offset = sizeof(Eventlog_record) + (offset - entry->data);
+    memcpy(offset, &(entry->data_record.user_data), entry->data_record.user_data_len);
+    offset += entry->data_record.user_data_len;
+    /* Now that we've massaged the current entry, copy it into the new entry and add it
+       to end of the list */
+    insert_point=r_u->entry;
+
+    if (NULL == insert_point) 
+    {
+       r_u->entry = new;
+       new->next = NULL;
+    } 
+    else
+    {
+       while ((NULL != insert_point->next)) 
+       {
+           insert_point=insert_point->next;
+       }
+       new->next = NULL;
+       insert_point->next = new;
+    }
+
+    memcpy(&(new->record), &entry->record, sizeof(Eventlog_record));
+    memcpy(&(new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
+    new->data = entry->data;
+
+    r_u->num_records++; 
+    r_u->num_bytes_in_resp += entry->record.length;
+
+    return True;
+}
+
+WERROR _eventlog_read_eventlog(pipes_struct *p,
+                              EVENTLOG_Q_READ_EVENTLOG *q_u,
+                              EVENTLOG_R_READ_EVENTLOG *r_u)
+{
+    Eventlog_info *info = NULL;
+    POLICY_HND *handle;
+    Eventlog_entry entry;
+    BOOL eof = False;
+    const char *direction = "";
+    int starting_record;
+    prs_struct *ps;
+
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+
+    handle = &(q_u->handle);
+    info = find_eventlog_info_by_hnd(p, handle);
+    ps = &p->out_data.rdata;
+    /* Rather than checking the EVENTLOG_SEQUENTIAL_READ/EVENTLOG_SEEK_READ flags,
+       we'll just go to the offset specified in the request, or the oldest entry
+       if no offset is specified */
+    if(q_u->offset > 0)
+       starting_record = q_u->offset;
+    else
+       starting_record = info->oldest_entry;
+    if(q_u->flags & EVENTLOG_FORWARDS_READ)
+       direction = "forward";
+    else if(q_u->flags & EVENTLOG_BACKWARDS_READ)
+       direction = "backward";
+
+    do
+    {
+       ZERO_STRUCT(entry);
+       if(!(_eventlog_read_eventlog_hook(info, &entry, direction, starting_record, q_u->max_read_size, &eof)))
+       {
+           if(eof == False)
+               return WERR_NOMEM;
+       }
+       if(eof == False)
+       {
+           /* only if the read hook returned data */
+           if(!(_eventlog_read_prepare_data_buffer(ps, q_u, r_u, &entry)))
+               return WERR_NOMEM;
+           DEBUG(10, ("_eventlog_read_eventlog: read [%d] bytes out of a max of [%d].\n",
+                      r_u->num_bytes_in_resp,
+                      q_u->max_read_size));
+       }
+    } while((r_u->num_bytes_in_resp <= q_u->max_read_size) && (eof != True));
+
+    return WERR_OK;
+}
+/**
+ * Callout to clear (and optionally backup) a specified event log
+ *
+ *   smbrun calling convention --
+ *     INPUT:  <clear_eventlog_cmd> <log name> <policy handle>
+ *     OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
+ *             Otherwise it is assumed to have failed
+ *
+ *     INPUT:  <clear_eventlog_cmd> <log name> <backup file> <policy handle>
+ *     OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
+ *             Otherwise it is assumed to have failed
+ *             The given log is copied to that location on the server. See comments for
+ *               eventlog_io_q_clear_eventlog for info about odd file name behavior
+ */
+static BOOL _eventlog_clear_eventlog_hook(Eventlog_info *info,
+                                         pstring backup_file_name)
+{
+    char *cmd = lp_eventlog_clear_cmd();
+    char **qlines;
+    pstring command;
+    int numlines = 0;
+    int ret;
+    int fd = -1;
+
+    if(cmd == NULL || strlen(cmd) == 0)
+    {
+       DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
+       return False;
+    }
+
+    memset(command, 0, sizeof(command));
+    if(strlen(backup_file_name) > 0)
+       slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\"",
+                cmd,
+                info->source_log_file_name,
+                backup_file_name,
+                info->handle_string);
+    else
+       slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", 
+                cmd, 
+                info->source_log_file_name, 
+                info->handle_string);
+
+    DEBUG(10, ("Running [%s]\n", command));
+    ret = smbrun(command, &fd);
+    DEBUGADD(10, ("returned [%d]\n", ret));
+
+    if(ret != 0)
+    {
+       if(fd != -1)
+           close(fd);
+       return False;
+    }
+
+    qlines = fd_lines_load(fd, &numlines);
+    DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+    close(fd);
+
+    if(numlines)
+    {
+       DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+       if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+       {
+           DEBUGADD(10, ("Able to clear [%s].\n", info->source_log_file_name));
+           file_lines_free(qlines);
+           return True;
+       }
+    }
+
+    file_lines_free(qlines);
+    return False;
+}
+
+WERROR _eventlog_clear_eventlog(pipes_struct *p,
+                               EVENTLOG_Q_CLEAR_EVENTLOG *q_u,
+                               EVENTLOG_R_CLEAR_EVENTLOG *r_u)
+{
+    Eventlog_info *info = NULL;
+    pstring backup_file_name;
+    POLICY_HND *handle = NULL;
+
+    if(!q_u || !r_u)
+       return WERR_NOMEM;
+
+    handle = &(q_u->handle);
+    info = find_eventlog_info_by_hnd(p, handle);
+    memset(backup_file_name, 0, sizeof(backup_file_name));
+
+    if(q_u->backup_file_ptr != 0)
+    {
+       unistr2_to_ascii(backup_file_name, &(q_u->backup_file), sizeof(backup_file_name));
+       DEBUG(10, ("_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
+                  backup_file_name,
+                  info->source_log_file_name));
+    }
+    else
+    {
+       /* if backup_file == NULL, do not back up the log before clearing it */
+       DEBUG(10, ("_eventlog_clear_eventlog: clearing [%s] log without making a backup.",
+                  info->source_log_file_name));
+    }
+
+    if(!(_eventlog_clear_eventlog_hook(info, backup_file_name)))
+       return WERR_BADFILE;
+
+    return WERR_OK;
+}
index d0b7a299be36391629e3ee12af4840c0a7c09da0..b410af8dedf9e44e317df10a7dccec24a8c4a133 100644 (file)
@@ -46,6 +46,9 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN
                return NT_STATUS_NO_MEMORY;
        }
 
+       get_mydnsdomname(dnsdomain);
+       strlower_m(dnsdomain);
+
        switch ( lp_server_role() ) {
                case ROLE_STANDALONE:
                        basic->machine_role = DSROLE_STANDALONE_SRV;
@@ -58,16 +61,12 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN
                        basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
                        if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
                                basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
-                       get_mydnsdomname(dnsdomain);
-                       strlower_m(dnsdomain);
                        break;
                case ROLE_DOMAIN_PDC:
                        basic->machine_role = DSROLE_PDC;
                        basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
                        if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
                                basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
-                       get_mydnsdomname(dnsdomain);
-                       strlower_m(dnsdomain);
                        break;
        }
 
index 7ea35a91faf35845f552a9ff73fd2b1fe8872d1b..5e949f0e63ff9db778b9ec215d6ef064a40d65d8 100644 (file)
@@ -314,8 +314,6 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
 
 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
 {
-       extern DOM_SID global_sid_World;
-       extern DOM_SID global_sid_Builtin;
        DOM_SID local_adm_sid;
        DOM_SID adm_sid;
 
@@ -523,6 +521,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
        }
 
        /* set up the lsa_enum_trust_dom response */
+
        init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms);
 
        return r_u->status;
@@ -1337,7 +1336,7 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
        int i = 0;
        DOM_SID sid;
        fstring privname;
-       UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+       UNISTR4_ARRAY *uni_privnames = q_u->rights;
        struct current_user user;
        
 
@@ -1368,11 +1367,16 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
        }
                
        for ( i=0; i<q_u->count; i++ ) {
-               unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
-               
+               UNISTR4 *uni4_str = &uni_privnames->strings[i];
+
                /* only try to add non-null strings */
+
+               if ( !uni4_str->string )
+                       continue;
+
+               rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
                
-               if ( *privname && !grant_privilege_by_name( &sid, privname ) ) {
+               if ( !grant_privilege_by_name( &sid, privname ) ) {
                        DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
                        return NT_STATUS_NO_SUCH_PRIVILEGE;
                }
@@ -1390,7 +1394,7 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
        int i = 0;
        DOM_SID sid;
        fstring privname;
-       UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+       UNISTR4_ARRAY *uni_privnames = q_u->rights;
        struct current_user user;
        
 
@@ -1425,11 +1429,16 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
        }
                
        for ( i=0; i<q_u->count; i++ ) {
-               unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
-               
+               UNISTR4 *uni4_str = &uni_privnames->strings[i];
+
                /* only try to add non-null strings */
+
+               if ( !uni4_str->string )
+                       continue;
+
+               rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
                
-               if ( *privname && !revoke_privilege_by_name( &sid, privname ) ) {
+               if ( !revoke_privilege_by_name( &sid, privname ) ) {
                        DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
                        return NT_STATUS_NO_SUCH_PRIVILEGE;
                }
@@ -1439,6 +1448,9 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
 }
 
 
+/***************************************************************************
+ ***************************************************************************/
+
 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
 {
        struct lsa_info *info = NULL;
@@ -1478,6 +1490,9 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA
 }
 
 
+/***************************************************************************
+ ***************************************************************************/
+
 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
 {
        struct lsa_info *info = NULL;
index 705b629732a5f729e1fe10a92063f029ed757899..a45a7eebf6a1022b29af7405d35939bd5fbd0e6c 100644 (file)
@@ -299,7 +299,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p)
        r_u.status = _net_logon_ctrl(p, &q_u, &r_u);
 
        if(!net_io_r_logon_ctrl("", &r_u, rdata, 0)) {
-               DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
+               DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL.\n"));
                return False;
        }
 
index 2bc0cf301e56c419a28d646f7eb4661e9840186a..c8ffa18c5a7475eab434424a214017a839caec36 100644 (file)
@@ -26,6 +26,9 @@
 
 #include "includes.h"
 
+extern struct dcinfo last_dcinfo;
+extern userdom_struct current_user_info;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -424,7 +427,6 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
        init_net_r_auth_2(r_u, &srv_cred, &srv_flgs, status);
 
        if (NT_STATUS_IS_OK(status)) {
-               extern struct dcinfo last_dcinfo;
                last_dcinfo = p->dc;
        }
 
@@ -575,7 +577,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        fstring nt_username, nt_domain, nt_workstation;
        auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
-       extern userdom_struct current_user_info;
        SAM_ACCOUNT *sampw;
        struct auth_context *auth_context = NULL;
                
index 01e91ce6c50e950c4a0ec15182c47de2de91d2c5..ee6c42bd88fdf7a23ea59def0ca5cff693e54d47 100644 (file)
@@ -40,6 +40,9 @@
 
 #include "includes.h"
 
+extern struct pipe_id_info pipe_names[];
+extern struct current_user current_user;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -751,7 +754,6 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
 BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
                     RPC_IFACE* transfer, uint32 context_id)
 {
-       extern struct pipe_id_info pipe_names[];
        char *pipe_name = p->name;
        int i=0;
        fstring pname;
@@ -765,6 +767,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
                
        for ( i=0; pipe_names[i].client_pipe; i++ ) 
        {
+               DEBUG(10,("checking %s\n", pipe_names[i].client_pipe));
                if ( strequal(pipe_names[i].client_pipe, pname)
                        && (abstract->version == pipe_names[i].abstr_syntax.version) 
                        && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0)
@@ -1426,7 +1429,6 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
        if (p->ntlmssp_auth_validated) {
                memcpy(user, &p->pipe_user, sizeof(struct current_user));
        } else {
-               extern struct current_user current_user;
                memcpy(user, &current_user, sizeof(struct current_user));
        }
 
@@ -1631,6 +1633,12 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
                case PI_NETDFS:
                        netdfs_get_pipe_fns( &cmds, &n_cmds );
                        break;
+               case PI_SVCCTL:
+                       svcctl_get_pipe_fns( &cmds, &n_cmds );
+                       break;
+               case PI_EVENTLOG:
+                       eventlog_get_pipe_fns( &cmds, &n_cmds );
+                       break;
 #ifdef DEVELOPER
                case PI_ECHO:
                        echo_get_pipe_fns( &cmds, &n_cmds );
index b780be0aff3c16677989128ed5bfd23539fb9f2d..a90650c536d950e6b9dfa8277621130e6853d739 100644 (file)
@@ -63,8 +63,8 @@ static BOOL api_reg_close(pipes_struct *p)
 
 static BOOL api_reg_open_hklm(pipes_struct *p)
 {
-       REG_Q_OPEN_HKLM q_u;
-       REG_R_OPEN_HKLM r_u;
+       REG_Q_OPEN_HIVE q_u;
+       REG_R_OPEN_HIVE r_u;
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
 
@@ -72,12 +72,12 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
        ZERO_STRUCT(r_u);
 
        /* grab the reg open */
-       if(!reg_io_q_open_hklm("", &q_u, data, 0))
+       if(!reg_io_q_open_hive("", &q_u, data, 0))
                return False;
 
        r_u.status = _reg_open_hklm(p, &q_u, &r_u);
 
-       if(!reg_io_r_open_hklm("", &r_u, rdata, 0))
+       if(!reg_io_r_open_hive("", &r_u, rdata, 0))
                return False;
 
        return True;
@@ -89,8 +89,8 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
 
 static BOOL api_reg_open_hku(pipes_struct *p)
 {
-       REG_Q_OPEN_HKU q_u;
-       REG_R_OPEN_HKU r_u;
+       REG_Q_OPEN_HIVE q_u;
+       REG_R_OPEN_HIVE r_u;
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
 
@@ -98,12 +98,12 @@ static BOOL api_reg_open_hku(pipes_struct *p)
        ZERO_STRUCT(r_u);
 
        /* grab the reg open */
-       if(!reg_io_q_open_hku("", &q_u, data, 0))
+       if(!reg_io_q_open_hive("", &q_u, data, 0))
                return False;
 
        r_u.status = _reg_open_hku(p, &q_u, &r_u);
 
-       if(!reg_io_r_open_hku("", &r_u, rdata, 0))
+       if(!reg_io_r_open_hive("", &r_u, rdata, 0))
                return False;
 
        return True;
@@ -115,8 +115,8 @@ static BOOL api_reg_open_hku(pipes_struct *p)
 
 static BOOL api_reg_open_hkcr(pipes_struct *p)
 {
-       REG_Q_OPEN_HKCR q_u;
-       REG_R_OPEN_HKCR r_u;
+       REG_Q_OPEN_HIVE q_u;
+       REG_R_OPEN_HIVE r_u;
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
 
@@ -124,12 +124,12 @@ static BOOL api_reg_open_hkcr(pipes_struct *p)
        ZERO_STRUCT(r_u);
 
        /* grab the reg open */
-       if(!reg_io_q_open_hkcr("", &q_u, data, 0))
+       if(!reg_io_q_open_hive("", &q_u, data, 0))
                return False;
 
        r_u.status = _reg_open_hkcr(p, &q_u, &r_u);
 
-       if(!reg_io_r_open_hkcr("", &r_u, rdata, 0))
+       if(!reg_io_r_open_hive("", &r_u, rdata, 0))
                return False;
 
        return True;
@@ -215,6 +215,32 @@ static BOOL api_reg_shutdown(pipes_struct *p)
        return True;
 }
 
+/*******************************************************************
+ api_reg_shutdown_ex
+ ********************************************************************/
+
+static BOOL api_reg_shutdown_ex(pipes_struct *p)
+{
+       REG_Q_SHUTDOWN_EX q_u;
+       REG_R_SHUTDOWN_EX r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       /* grab the reg shutdown ex */
+       if(!reg_io_q_shutdown_ex("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _reg_shutdown_ex(p, &q_u, &r_u);
+
+       if(!reg_io_r_shutdown_ex("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  api_reg_abort_shutdown
  ********************************************************************/
@@ -268,25 +294,25 @@ static BOOL api_reg_query_key(pipes_struct *p)
 }
 
 /*******************************************************************
- api_reg_unknown_1a
+ api_reg_getversion
  ********************************************************************/
 
-static BOOL api_reg_unknown_1a(pipes_struct *p)
+static BOOL api_reg_getversion(pipes_struct *p)
 {
-       REG_Q_UNKNOWN_1A q_u;
-       REG_R_UNKNOWN_1A r_u;
+       REG_Q_GETVERSION q_u;
+       REG_R_GETVERSION r_u;
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
 
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
-       if(!reg_io_q_unknown_1a("", &q_u, data, 0))
+       if(!reg_io_q_getversion("", &q_u, data, 0))
                return False;
 
-       r_u.status = _reg_unknown_1a(p, &q_u, &r_u);
+       r_u.status = _reg_getversion(p, &q_u, &r_u);
 
-       if(!reg_io_r_unknown_1a("", &r_u, rdata, 0))
+       if(!reg_io_r_getversion("", &r_u, rdata, 0))
                return False;
 
        return True;
@@ -343,8 +369,31 @@ static BOOL api_reg_enum_value(pipes_struct *p)
 }
 
 /*******************************************************************
- api_reg_save_key
- ********************************************************************/
+ ******************************************************************/
+
+static BOOL api_reg_restore_key(pipes_struct *p)
+{
+       REG_Q_RESTORE_KEY q_u;
+       REG_R_RESTORE_KEY r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!reg_io_q_restore_key("", &q_u, data, 0))
+               return False;
+               
+       r_u.status = _reg_restore_key(p, &q_u, &r_u);
+
+       if(!reg_io_r_restore_key("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ******************************************************************/
 
 static BOOL api_reg_save_key(pipes_struct *p)
 {
@@ -383,9 +432,11 @@ static struct api_struct api_reg_cmds[] =
       { "REG_QUERY_KEY"          , REG_QUERY_KEY          , api_reg_query_key        },
       { "REG_INFO"               , REG_INFO               , api_reg_info             },
       { "REG_SHUTDOWN"           , REG_SHUTDOWN           , api_reg_shutdown         },
+      { "REG_SHUTDOWN_EX"        , REG_SHUTDOWN_EX        , api_reg_shutdown_ex      },
       { "REG_ABORT_SHUTDOWN"     , REG_ABORT_SHUTDOWN     , api_reg_abort_shutdown   },
-      { "REG_UNKNOWN_1A"         , REG_UNKNOWN_1A         , api_reg_unknown_1a       },
-      { "REG_SAVE_KEY"           , REG_SAVE_KEY           , api_reg_save_key         }
+      { "REG_GETVERSION"         , REG_GETVERSION         , api_reg_getversion       },
+      { "REG_SAVE_KEY"           , REG_SAVE_KEY           , api_reg_save_key         },
+      { "REG_RESTORE_KEY"        , REG_RESTORE_KEY        , api_reg_restore_key      }
 };
 
 void reg_get_pipe_fns( struct api_struct **fns, int *n_fns )
index c11e0d59a056915253dd83b54e35a33fda704125..f031a3213f2a167f6970d68cefddcf5ab4805fd0 100644 (file)
@@ -5,7 +5,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton  1996-1997.
  *  Copyright (C) Paul Ashton                        1997.
  *  Copyright (C) Jeremy Allison                     2001.
- *  Copyright (C) Gerald Carter                      2002.
+ *  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
@@ -291,7 +291,7 @@ WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
 /*******************************************************************
  ********************************************************************/
 
-WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
+WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
 {
        return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 );
 }
@@ -299,7 +299,7 @@ WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_
 /*******************************************************************
  ********************************************************************/
 
-WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
+WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
 {
        return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
 }
@@ -307,7 +307,7 @@ WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_
 /*******************************************************************
  ********************************************************************/
 
-WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
+WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
 {
        return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 );
 }
@@ -328,7 +328,7 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
        if ( !key )
                return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
 
-       rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
+       rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
        
        result = open_registry_key( p, &pol, key, name, 0x0 );
        
@@ -362,7 +362,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
                
        DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
        
-       rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
+       rpcstr_pull(name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0);
 
        DEBUG(5,("reg_info: looking up value: [%s]\n", name));
 
@@ -439,7 +439,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
 
   
 out:
-       new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
+       init_reg_r_info(q_u->ptr_buf, r_u, val, status);
        
        regval_ctr_destroy( &regvals );
        free_registry_value( val );
@@ -485,22 +485,22 @@ WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_
 
 
 /*****************************************************************************
- Implementation of REG_UNKNOWN_1A
+ Implementation of REG_GETVERSION
  ****************************************************************************/
  
-WERROR _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
+WERROR _reg_getversion(pipes_struct *p, REG_Q_GETVERSION *q_u, REG_R_GETVERSION *r_u)
 {
        WERROR  status = WERR_OK;
        REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
        
-       DEBUG(5,("_reg_unknown_1a: Enter\n"));
+       DEBUG(5,("_reg_getversion: Enter\n"));
        
        if ( !regkey )
                return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
        
        r_u->unknown = 0x00000005;      /* seems to be consistent...no idea what it means */
        
-       DEBUG(5,("_reg_unknown_1a: Exit\n"));
+       DEBUG(5,("_reg_getversion: Exit\n"));
        
        return status;
 }
@@ -561,8 +561,7 @@ WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE
 
        DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
 
-       if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
-       {
+       if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) ) {
                status = WERR_NO_MORE_ITEMS;
                goto done;
        }
@@ -587,110 +586,190 @@ done:
  reg_shutdwon
  ********************************************************************/
 
+WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
+{
+       REG_Q_SHUTDOWN_EX q_u_ex;
+       REG_R_SHUTDOWN_EX r_u_ex;
+       
+       /* copy fields (including stealing memory) */
+       
+       q_u_ex.server  = q_u->server;
+       q_u_ex.message = q_u->message;
+       q_u_ex.timeout = q_u->timeout;
+       q_u_ex.force   = q_u->force;
+       q_u_ex.reboot  = q_u->reboot;
+       q_u_ex.reason  = 0x0;   /* don't care for now */
+       
+       /* thunk down to _reg_shutdown_ex() (just returns a status) */
+       
+       return _reg_shutdown_ex( p, &q_u_ex, &r_u_ex );
+}
+
+/*******************************************************************
+ reg_shutdown_ex
+ ********************************************************************/
+
 #define SHUTDOWN_R_STRING "-r"
 #define SHUTDOWN_F_STRING "-f"
 
 
-WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
+WERROR _reg_shutdown_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_EX *r_u)
 {
-       WERROR status = WERR_OK;
        pstring shutdown_script;
-       UNISTR2 unimsg = q_u->uni_msg;
        pstring message;
        pstring chkmsg;
        fstring timeout;
+       fstring reason;
        fstring r;
        fstring f;
+       int ret;
+       BOOL can_shutdown;
+       
+       pstrcpy(shutdown_script, lp_shutdown_script());
        
-       /* message */
-       rpcstr_pull (message, unimsg.buffer, sizeof(message), unimsg.uni_str_len*2,0);
-       /* security check */
+       if ( !*shutdown_script )
+               return WERR_ACCESS_DENIED;
+
+       /* pull the message string and perform necessary sanity checks on it */
+
+       pstrcpy( message, "" );
+       if ( q_u->message ) {
+               UNISTR2 *msg_string = q_u->message->string;
+       
+               rpcstr_pull( message, msg_string->buffer, sizeof(message), msg_string->uni_str_len*2, 0 );
+       }
        alpha_strcpy (chkmsg, message, NULL, sizeof(message));
-       /* timeout */
+               
        fstr_sprintf(timeout, "%d", q_u->timeout);
-       /* reboot */
        fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
-       /* force */
        fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
+       fstr_sprintf( reason, "%d", q_u->reason );
 
-       pstrcpy(shutdown_script, lp_shutdown_script());
+       all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
+       all_string_sub( shutdown_script, "%t", timeout, sizeof(shutdown_script) );
+       all_string_sub( shutdown_script, "%r", r, sizeof(shutdown_script) );
+       all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
+       all_string_sub( shutdown_script, "%x", reason, sizeof(shutdown_script) );
+               
+       can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
+               
+       /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
+          Take the error return from the script and provide it as the Windows return code. */
+          
+       /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+       
+       if ( can_shutdown ) 
+               become_root();
 
-       if(*shutdown_script) {
-               int shutdown_ret;
-               SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
-               BOOL can_shutdown;
+       ret = smbrun( shutdown_script, NULL );
                
-               can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+       if ( can_shutdown )
+               unbecome_root();
+
+       /********** END SeRemoteShutdownPrivilege BLOCK **********/
+
+       DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
+               shutdown_script, ret));
                
-               /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
-               if ( can_shutdown )
-                       become_root();
-               all_string_sub(shutdown_script, "%m", chkmsg, sizeof(shutdown_script));
-               all_string_sub(shutdown_script, "%t", timeout, sizeof(shutdown_script));
-               all_string_sub(shutdown_script, "%r", r, sizeof(shutdown_script));
-               all_string_sub(shutdown_script, "%f", f, sizeof(shutdown_script));
-               shutdown_ret = smbrun(shutdown_script,NULL);
-               DEBUG(3,("_reg_shutdown: Running the command `%s' gave %d\n",shutdown_script,shutdown_ret));
-               if ( can_shutdown )
-                       unbecome_root();
-               /********** END SeRemoteShutdownPrivilege BLOCK **********/
-       }
 
-       return status;
+       return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 }
 
+
+
+
 /*******************************************************************
  reg_abort_shutdwon
  ********************************************************************/
 
 WERROR _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
 {
-       WERROR status = WERR_OK;
        pstring abort_shutdown_script;
+       int ret;
+       BOOL can_shutdown;
 
        pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
 
-       if(*abort_shutdown_script) {
-               int abort_shutdown_ret;
-               SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
-               BOOL can_shutdown;
+       if ( !*abort_shutdown_script )
+               return WERR_ACCESS_DENIED;
                
-               can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+       can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
                
-               /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
-               if ( can_shutdown )
-                       become_root();
-               abort_shutdown_ret = smbrun(abort_shutdown_script,NULL);
-               DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",abort_shutdown_script,abort_shutdown_ret));
-               if ( can_shutdown )
-                       unbecome_root();
-               /********** END SeRemoteShutdownPrivilege BLOCK **********/
+       /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+       
+       if ( can_shutdown )
+               become_root();
                
-       }
+       ret = smbrun( abort_shutdown_script, NULL );
+       
+       if ( can_shutdown )
+               unbecome_root();
+               
+       /********** END SeRemoteShutdownPrivilege BLOCK **********/
 
-       return status;
+       DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
+               abort_shutdown_script, ret));
+               
+
+       return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY  *q_u, REG_R_RESTORE_KEY *r_u)
+{
+       REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+       pstring         filename;
+       
+       DEBUG(5,("_reg_restore_key: Enter\n"));
+       
+       /* 
+        * basically this is a no op function which just verifies 
+        * that the client gave us a valid registry key handle 
+        */
+        
+       if ( !regkey )
+               return WERR_BADFID; 
+
+       rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
+
+       DEBUG(8,("_reg_restore_key: verifying restore of key [%s] from \"%s\"\n", regkey->name, filename));
+
+#if 0
+       validate_reg_filemame( filename );
+       return restore_registry_key( regkey, filename );
+#endif
+
+       return WERR_OK;
 }
 
 /*******************************************************************
- REG_SAVE_KEY (0x14)
  ********************************************************************/
 
 WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY  *q_u, REG_R_SAVE_KEY *r_u)
 {
        REGISTRY_KEY    *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+       pstring         filename;
        
        DEBUG(5,("_reg_save_key: Enter\n"));
        
        /* 
-        * basically this is a no op function which just gverifies 
+        * basically this is a no op function which just verifies 
         * that the client gave us a valid registry key handle 
         */
         
        if ( !regkey )
-               return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
+               return WERR_BADFID; 
 
-       DEBUG(8,("_reg_save_key: berifying backup of key [%s]\n", regkey->name));
-       
+       rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
+
+       DEBUG(8,("_reg_save_key: verifying backup of key [%s] to \"%s\"\n", regkey->name, filename));
+
+#if 0
+       validate_reg_filemame( filename );
+       return backup_registry_key( regkey, filename );
+#endif
 
        return WERR_OK;
 }
index 139960f661316728438133698ff94fe94481a792..fe54476cc954447020d6d19ab0c0fb9045247ba5 100644 (file)
                  SA_RIGHT_USER_CHANGE_PASSWORD | \
                  SA_RIGHT_USER_SET_LOC_COM )
 
-extern DOM_SID global_sid_Builtin;
-
 extern rid_name domain_group_rids[];
 extern rid_name domain_alias_rids[];
 extern rid_name builtin_alias_rids[];
 
-
-typedef struct _disp_info {
-       BOOL user_dbloaded;
-       uint32 num_user_account;
-       SAM_ACCOUNT *disp_user_info;
-       BOOL group_dbloaded;
-       uint32 num_group_account;
-       DOMAIN_GRP *disp_group_info;
+typedef struct disp_info {
+       struct pdb_search *users;
+       struct pdb_search *machines;
+       struct pdb_search *groups;
+       struct pdb_search *aliases;
+       struct pdb_search *builtins;
 } DISP_INFO;
 
 struct samr_info {
@@ -80,7 +76,6 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
                                      struct generic_mapping *map,
                                     DOM_SID *sid, uint32 sid_access )
 {
-       extern DOM_SID global_sid_World;
        DOM_SID adm_sid, act_sid, domadmin_sid;
        SEC_ACE ace[5];         /* at most 5 entries */
        SEC_ACCESS mask;
@@ -241,10 +236,9 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
 
        mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
 
-       if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
+       if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
                return NULL;
 
-       ZERO_STRUCTP(info);
        DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
        if (psid) {
                sid_copy( &info->sid, psid);
@@ -259,33 +253,22 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
  Function to free the per handle data.
  ********************************************************************/
 
-static void free_samr_users(struct samr_info *info) 
-{
-       int i;
-
-       if (info->disp_info.user_dbloaded){
-               for (i=0; i<info->disp_info.num_user_account; i++) {
-                       SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
-                       /* Not really a free, actually a 'clear' */
-                       pdb_free_sam(&sam);
-               }
-       }
-       info->disp_info.user_dbloaded=False;
-       info->disp_info.num_user_account=0;
-}
-
 /*******************************************************************
  Function to free the per handle data.
  ********************************************************************/
 
 static void free_samr_db(struct samr_info *info)
 {
-       /* Groups are talloced */
-
-       free_samr_users(info);
-
-       info->disp_info.group_dbloaded=False;
-       info->disp_info.num_group_account=0;
+       pdb_search_destroy(info->disp_info.users);
+       info->disp_info.users = NULL;
+       pdb_search_destroy(info->disp_info.machines);
+       info->disp_info.machines = NULL;
+       pdb_search_destroy(info->disp_info.groups);
+       info->disp_info.groups = NULL;
+       pdb_search_destroy(info->disp_info.aliases);
+       info->disp_info.aliases = NULL;
+       pdb_search_destroy(info->disp_info.builtins);
+       info->disp_info.builtins = NULL;
 }
 
 static void free_samr_info(void *ptr)
@@ -312,154 +295,30 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
        pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
 }
 
-
-static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
+static uint32 count_sam_users(struct disp_info *info, uint16 acct_flags)
 {
-       SAM_ACCOUNT *pwd = NULL;
-       SAM_ACCOUNT *pwd_array = NULL;
-       NTSTATUS nt_status = NT_STATUS_OK;
-       TALLOC_CTX *mem_ctx = info->mem_ctx;
-       uint16 query_acb_mask = acb_mask;
-
-       DEBUG(10,("load_sampwd_entries\n"));
-
-       /* if the snapshoot is already loaded, return */
-       if ((info->disp_info.user_dbloaded==True) 
-           && (info->acb_mask == acb_mask) 
-           && (info->only_machines == only_machines)) {
-               DEBUG(10,("load_sampwd_entries: already in memory\n"));
-               return NT_STATUS_OK;
-       }
-
-       free_samr_users(info);
-       
-       if (only_machines) {
-               query_acb_mask |= ACB_WSTRUST;
-               query_acb_mask |= ACB_SVRTRUST;
-       }
-
-       if (!pdb_setsampwent(False, query_acb_mask)) {
-               DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
-                    && pdb_getsampwent(pwd) == True; pwd=NULL) {
-       
-               if (only_machines) {
-                       if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
-                             || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
-                               DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
-                               pdb_free_sam(&pwd);
-                               continue;
-                       }
-               } else {
-                       if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
-                               pdb_free_sam(&pwd);
-                               DEBUG(5,(" acb_mask %x reject\n", acb_mask));
-                               continue;
-                       }
-               }
-
-               /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
-               if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
-               
-                       DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
-                       pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
-                                         info->disp_info.num_user_account+MAX_SAM_ENTRIES);
-
-                       if (pwd_array==NULL)
-                               return NT_STATUS_NO_MEMORY;
-
-                       info->disp_info.disp_user_info=pwd_array;
-               }
-       
-               /* Copy the SAM_ACCOUNT into the array */
-               info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
-
-               DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
-
-               info->disp_info.num_user_account++;     
-       }
-
-       pdb_endsampwent();
-
-       /* the snapshoot is in memory, we're ready to enumerate fast */
-
-       info->acb_mask = acb_mask;
-       info->only_machines = only_machines;
-       info->disp_info.user_dbloaded=True;
-
-       DEBUG(10,("load_sampwd_entries: done\n"));
-
-       return nt_status;
+       struct samr_displayentry *entry;
+       if (info->users == NULL)
+               info->users = pdb_search_users(acct_flags);
+       if (info->users == NULL)
+               return 0;
+       /* Fetch the last possible entry, thus trigger an enumeration */
+       pdb_search_entries(info->users, 0xffffffff, 1, &entry);
+       return info->users->num_entries;
 }
 
-static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
+static uint32 count_sam_groups(struct disp_info *info)
 {
-       GROUP_MAP *map=NULL;
-       DOMAIN_GRP *grp_array = NULL;
-       uint32 group_entries = 0;
-       uint32 i;
-       TALLOC_CTX *mem_ctx = info->mem_ctx;
-       BOOL ret;
-
-       DEBUG(10,("load_group_domain_entries\n"));
-
-       /* if the snapshoot is already loaded, return */
-       if (info->disp_info.group_dbloaded==True) {
-               DEBUG(10,("load_group_domain_entries: already in memory\n"));
-               return NT_STATUS_OK;
-       }
-       
-       if (sid_equal(sid, &global_sid_Builtin)) {
-               /* No domain groups for now in the BUILTIN domain */
-               info->disp_info.num_group_account=0;
-               info->disp_info.disp_group_info=NULL;
-               info->disp_info.group_dbloaded=True;
-               return NT_STATUS_OK;
-       }
-
-       become_root();
-       ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); 
-       unbecome_root();
-       
-       if ( !ret ) {
-               DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-       
-
-       info->disp_info.num_group_account=group_entries;
-
-       grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
-       if (group_entries!=0 && grp_array==NULL) {
-               DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
-               SAFE_FREE(map);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       info->disp_info.disp_group_info=grp_array;
-
-       for (i=0; i<group_entries; i++) {
-               fstrcpy(grp_array[i].name, map[i].nt_name);
-               fstrcpy(grp_array[i].comment, map[i].comment);
-               sid_split_rid(&map[i].sid, &grp_array[i].rid);
-               grp_array[i].attr=SID_NAME_DOM_GRP;
-       }
-
-       SAFE_FREE(map);
-
-       /* the snapshoot is in memory, we're ready to enumerate fast */
-
-       info->disp_info.group_dbloaded=True;
-
-       DEBUG(10,("load_group_domain_entries: done\n"));
-
-       return NT_STATUS_OK;
+       struct samr_displayentry *entry;
+       if (info->groups == NULL)
+               info->groups = pdb_search_groups();
+       if (info->groups == NULL)
+               return 0;
+       /* Fetch the last possible entry, thus trigger an enumeration */
+       pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
+       return info->groups->num_entries;
 }
 
-
 /*******************************************************************
  _samr_close_hnd
  ********************************************************************/
@@ -659,20 +518,14 @@ NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_
 makes a SAM_ENTRY / UNISTR2* structure from a user list.
 ********************************************************************/
 
-static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
-                                        uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
-                                        DOM_SID *domain_sid)
+static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
+                                        UNISTR2 **uni_name_pp,
+                                        uint32 num_entries, uint32 start_idx,
+                                        struct samr_displayentry *entries)
 {
        uint32 i;
        SAM_ENTRY *sam;
        UNISTR2 *uni_name;
-       SAM_ACCOUNT *pwd = NULL;
-       UNISTR2 uni_temp_name;
-       const char *temp_name;
-       const DOM_SID *user_sid;
-       uint32 user_rid;
-       fstring user_sid_string;
-       fstring domain_sid_string;
        
        *sam_pp = NULL;
        *uni_name_pp = NULL;
@@ -690,31 +543,20 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UN
        }
 
        for (i = 0; i < num_entries; i++) {
-               pwd = &disp_user_info[i+start_idx];
-               temp_name = pdb_get_username(pwd);
-
+               UNISTR2 uni_temp_name;
                /*
                 * usrmgr expects a non-NULL terminated string with
                 * trust relationships
                 */
-               if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
-                       init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
+               if (entries[i].acct_flags & ACB_DOMTRUST) {
+                       init_unistr2(&uni_temp_name, entries[i].account_name,
+                                    UNI_FLAGS_NONE);
                } else {
-                       init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
-               }
-
-               user_sid = pdb_get_user_sid(pwd);
-
-               if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
-                       DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
-                                 "the domain sid %s.  Failing operation.\n", 
-                                 temp_name, 
-                                 sid_to_string(user_sid_string, user_sid),
-                                 sid_to_string(domain_sid_string, domain_sid)));
-                       return NT_STATUS_UNSUCCESSFUL;
+                       init_unistr2(&uni_temp_name, entries[i].account_name,
+                                    UNI_STR_TERMINATE);
                }
 
-               init_sam_entry(&sam[i], &uni_temp_name, user_rid);
+               init_sam_entry(&sam[i], &uni_temp_name, entries[i].rid);
                copy_unistr2(&uni_name[i], &uni_temp_name);
        }
 
@@ -731,15 +573,12 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
                              SAMR_R_ENUM_DOM_USERS *r_u)
 {
        struct samr_info *info = NULL;
-       uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
        int num_account;
        uint32 enum_context=q_u->start_idx;
-       uint32 max_size=q_u->max_size;
-       uint32 temp_size;
        enum remote_arch_types ra_type = get_remote_arch();
        int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
        uint32 max_entries = max_sam_entries;
-       DOM_SID domain_sid;
+       struct samr_displayentry *entries = NULL;
        
        r_u->status = NT_STATUS_OK;
 
@@ -747,8 +586,6 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
        if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
                return NT_STATUS_INVALID_HANDLE;
 
-       domain_sid = info->sid;
-
        if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
                                        SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
                                        "_samr_enum_dom_users"))) {
@@ -758,60 +595,36 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
        DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
        become_root();
-       r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
+       if (info->disp_info.users == NULL)
+               info->disp_info.users = pdb_search_users(q_u->acb_mask);
+       if (info->disp_info.users == NULL)
+               return NT_STATUS_ACCESS_DENIED;
+       num_account = pdb_search_entries(info->disp_info.users,
+                                        enum_context, max_entries,
+                                        &entries);
        unbecome_root();
-       
-       if (!NT_STATUS_IS_OK(r_u->status))
-               return r_u->status;
-
-       num_account = info->disp_info.num_user_account;
 
-       if (enum_context > num_account) {
-               DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
+       if (num_account == 0) {
+               DEBUG(5, ("_samr_enum_dom_users: enumeration handle over "
+                         "total entries\n"));
                return NT_STATUS_OK;
        }
 
-       /* verify we won't overflow */
-       if (max_entries > num_account-enum_context) {
-               max_entries = num_account-enum_context;
-               DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
-       }
-
-       /* calculate the size and limit on the number of entries we will return */
-       temp_size=max_entries*struct_size;
-       
-       if (temp_size>max_size) {
-               max_entries=MIN((max_size/struct_size),max_entries);;
-               DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
-       }
-
-       /* 
-        * Note from JRA. total_entries is not being used here. Currently if there is a
-        * large user base then it looks like NT will enumerate until get_sampwd_entries
-        * returns False due to num_entries being zero. This will cause an access denied
-        * return. I don't think this is right and needs further investigation. Note that
-        * this is also the same in the TNG code (I don't think that has been tested with
-        * a very large user list as MAX_SAM_ENTRIES is set to 600).
-        * 
-        * I also think that one of the 'num_entries' return parameters is probably
-        * the "max entries" parameter - but in the TNG code they're all currently set to the same
-        * value (again I think this is wrong).
-        */
-
-       r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
-                                              max_entries, enum_context, 
-                                              info->disp_info.disp_user_info,
-                                              &domain_sid);
+       r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam,
+                                              &r_u->uni_acct_name, 
+                                              num_account, enum_context,
+                                              entries);
 
        if (!NT_STATUS_IS_OK(r_u->status))
                return r_u->status;
 
-       if (enum_context+max_entries < num_account)
+       if (max_entries <= num_account)
                r_u->status = STATUS_MORE_ENTRIES;
 
        DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
 
-       init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
+       init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_account,
+                                  num_account);
 
        DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
 
@@ -822,8 +635,10 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
 makes a SAM_ENTRY / UNISTR2* structure from a group list.
 ********************************************************************/
 
-static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
-                uint32 num_sam_entries, DOMAIN_GRP *grp)
+static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
+                                     UNISTR2 **uni_name_pp,
+                                     uint32 num_sam_entries,
+                                     struct samr_displayentry *entries)
 {
        uint32 i;
        SAM_ENTRY *sam;
@@ -847,180 +662,117 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
                /*
                 * JRA. I think this should include the null. TNG does not.
                 */
-               init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
-               init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
+               init_unistr2(&uni_name[i], entries[i].account_name,
+                            UNI_STR_TERMINATE);
+               init_sam_entry(&sam[i], &uni_name[i], entries[i].rid);
        }
 
        *sam_pp = sam;
        *uni_name_pp = uni_name;
 }
 
-/*******************************************************************
- Get the group entries - similar to get_sampwd_entries().
- ******************************************************************/
-
-static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, 
-                                   DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
-                                   uint32 *p_num_entries, uint32 max_entries )
-{
-       GROUP_MAP *map=NULL;
-       int i;
-       uint32 group_entries = 0;
-       uint32 num_entries = 0;
-
-       *p_num_entries = 0;
-
-       /* access checks for the users were performed higher up.  become/unbecome_root()
-          needed for some passdb backends to enumerate groups */
-          
-       become_root();
-       pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
-                              ENUM_ONLY_MAPPED);
-       unbecome_root();
-       
-       num_entries=group_entries-start_idx;
-
-       /* limit the number of entries */
-       if (num_entries>max_entries) {
-               DEBUG(5,("Limiting to %d entries\n", max_entries));
-               num_entries=max_entries;
-       }
-
-       *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
-       if (num_entries!=0 && *d_grp==NULL){
-               SAFE_FREE(map);
-               return NT_STATUS_NO_MEMORY;
-       }
-       
-       for (i=0; i<num_entries; i++) {
-               fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
-               fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
-               sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
-               (*d_grp)[i].attr=SID_NAME_DOM_GRP;
-       }
-
-       SAFE_FREE(map);
-
-       *p_num_entries = num_entries;
-
-       DEBUG(10,("get_group_domain_entries: returning %d entries\n",
-                 *p_num_entries));
-
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Wrapper for enumerating local groups
- ******************************************************************/
-
-static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
-                                  const DOM_SID *sid, uint32 start_idx,
-                                   uint32 *p_num_entries, uint32 max_entries )
-{
-       struct acct_info *info;
-       int i;
-       BOOL res;
-
-       become_root();
-       res = pdb_enum_aliases(sid, start_idx, max_entries,
-                              p_num_entries, &info);
-       unbecome_root();
-
-       if (!res)
-               return NT_STATUS_ACCESS_DENIED;
-
-       if (*p_num_entries == 0)
-               return NT_STATUS_OK;
-
-       *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
-
-       if (*d_grp == NULL) {
-               SAFE_FREE(info);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i=0; i<*p_num_entries; i++) {
-               fstrcpy((*d_grp)[i].name, info[i].acct_name);
-               fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
-               (*d_grp)[i].rid = info[i].rid;
-               (*d_grp)[i].attr = SID_NAME_ALIAS;
-       }
-
-       SAFE_FREE(info);
-       return NT_STATUS_OK;
-}
-
 /*******************************************************************
  samr_reply_enum_dom_groups
  ********************************************************************/
 
 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
 {
-       DOMAIN_GRP *grp=NULL;
-       uint32 num_entries;
-       DOM_SID sid;
-       uint32 acc_granted;
+       struct samr_info *info = NULL;
+       struct samr_displayentry *groups;
+       uint32 num_groups;
 
        r_u->status = NT_STATUS_OK;
 
-       if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+       /* find the policy handle.  open a policy on it. */
+       if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
                return NT_STATUS_INVALID_HANDLE;
-               
-       if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
+
+       r_u->status = access_check_samr_function(info->acc_granted,
+                                                SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+                                                "_samr_enum_dom_groups");
+       if (!NT_STATUS_IS_OK(r_u->status))
                return r_u->status;
-       }
 
        DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
 
        /* the domain group array is being allocated in the function below */
-       if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
-               return r_u->status;
-       }
 
-       make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
+       become_root();
+       if (info->disp_info.groups == NULL)
+               info->disp_info.groups = pdb_search_groups();
+       unbecome_root();
+
+       if (info->disp_info.groups == NULL)
+               return NT_STATUS_ACCESS_DENIED;
+
+       become_root();
+       num_groups = pdb_search_entries(info->disp_info.groups, q_u->start_idx,
+                                       MAX_SAM_ENTRIES, &groups);
+       unbecome_root();
+       
+       make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
+                                 num_groups, groups);
 
-       init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
+       init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_groups);
 
        DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
 
        return r_u->status;
 }
 
-
 /*******************************************************************
  samr_reply_enum_dom_aliases
  ********************************************************************/
 
 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
 {
-       DOMAIN_GRP *grp=NULL;
-       uint32 num_entries = 0;
-       fstring sid_str;
-       DOM_SID sid;
+       struct samr_info *info;
+       struct samr_displayentry *aliases;
+       struct pdb_search **search = NULL;
+       uint32 num_aliases = 0;
        NTSTATUS status;
-       uint32  acc_granted;
-       
+
        r_u->status = NT_STATUS_OK;
 
-       if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
+       /* find the policy handle.  open a policy on it. */
+       if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
                return NT_STATUS_INVALID_HANDLE;
 
-       if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
+       r_u->status = access_check_samr_function(info->acc_granted,
+                                                SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+                                                "_samr_enum_dom_aliases");
+       if (!NT_STATUS_IS_OK(r_u->status))
                return r_u->status;
-       }
-       
-       sid_to_string(sid_str, &sid);
-       DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
 
-       status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
-                                  &num_entries, MAX_SAM_ENTRIES);
-       if (!NT_STATUS_IS_OK(status)) return status;
+       DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
+                sid_string_static(&info->sid)));
+
+       if (sid_check_is_domain(&info->sid))
+               search = &info->disp_info.aliases;
+       if (sid_check_is_builtin(&info->sid))
+               search = &info->disp_info.builtins;
 
-       make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
+       if (search == NULL) return NT_STATUS_INVALID_HANDLE;
 
-       /*safe_free(grp);*/
+       become_root();
+       if (*search == NULL)
+               *search = pdb_search_aliases(&info->sid);
+       unbecome_root();
 
-       init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
+       if (*search == NULL) return NT_STATUS_ACCESS_DENIED;
+
+       become_root();
+       num_aliases = pdb_search_entries(*search, q_u->start_idx,
+                                        MAX_SAM_ENTRIES, &aliases);
+       unbecome_root();
+       
+       make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
+                                 num_aliases, aliases);
+
+       if (!NT_STATUS_IS_OK(status)) return status;
+
+       init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_aliases,
+                                    num_aliases);
 
        DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
 
@@ -1048,6 +800,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
        enum remote_arch_types ra_type = get_remote_arch();
        int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
        DOM_SID domain_sid;
+       struct samr_displayentry *entries = NULL;
 
        DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
        r_u->status = NT_STATUS_OK;
@@ -1086,68 +839,29 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
         * JFM, 12/20/2001
         */
 
-       /* Get what we need from the password database */
-       switch (q_u->switch_level) {
-               case 0x1:
-                       /* When playing with usrmgr, this is necessary
-                           if you want immediate refresh after editing
-                           a user. I would like to do this after the
-                           setuserinfo2, but we do not have access to
-                           the domain handle in that call, only to the
-                           user handle. Where else does this hurt?
-                          -- Volker
-                       */
-#if 0
-                       /* We cannot do this here - it kills performace. JRA. */
-                       free_samr_users(info);
-#endif
-               case 0x2:
-               case 0x4:
-                       become_root();          
-                       /* Level 2 is for all machines, otherwise only 'normal' users */
-                       r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
-                       unbecome_root();
-                       if (!NT_STATUS_IS_OK(r_u->status)) {
-                               DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
-                               return r_u->status;
-                       }
-                       num_account = info->disp_info.num_user_account;
-                       break;
-               case 0x3:
-               case 0x5:
-                       r_u->status = load_group_domain_entries(info, &info->sid);
-                       if (!NT_STATUS_IS_OK(r_u->status))
-                               return r_u->status;
-                       num_account = info->disp_info.num_group_account;
-                       break;
-               default:
-                       DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
-                       return NT_STATUS_INVALID_INFO_CLASS;
+       if ((q_u->switch_level < 1) || (q_u->switch_level > 5)) {
+               DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n",
+                        (unsigned int)q_u->switch_level ));
+               return NT_STATUS_INVALID_INFO_CLASS;
        }
 
        /* first limit the number of entries we will return */
        if(max_entries > max_sam_entries) {
-               DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
+               DEBUG(5, ("samr_reply_query_dispinfo: client requested %d "
+                         "entries, limiting to %d\n", max_entries,
+                         max_sam_entries));
                max_entries = max_sam_entries;
        }
 
-       if (enum_context > num_account) {
-               DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
-               return NT_STATUS_NO_MORE_ENTRIES;
-       }
+       /* calculate the size and limit on the number of entries we will
+        * return */
 
-       /* verify we won't overflow */
-       if (max_entries > num_account-enum_context) {
-               max_entries = num_account-enum_context;
-               DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
-       }
-
-       /* calculate the size and limit on the number of entries we will return */
        temp_size=max_entries*struct_size;
        
        if (temp_size>max_size) {
                max_entries=MIN((max_size/struct_size),max_entries);;
-               DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
+               DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to "
+                         "only %d entries\n", max_entries));
        }
 
        if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
@@ -1155,61 +869,80 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
 
        ZERO_STRUCTP(ctr);
 
+       become_root();
+
+       switch (q_u->switch_level) {
+       case 0x1:
+       case 0x4:
+               if (info->disp_info.users == NULL)
+                       info->disp_info.users = pdb_search_users(ACB_NORMAL);
+               if (info->disp_info.users == NULL)
+                       return NT_STATUS_ACCESS_DENIED;
+               num_account = pdb_search_entries(info->disp_info.users,
+                                                enum_context, max_entries,
+                                                &entries);
+               break;
+       case 0x2:
+               if (info->disp_info.machines == NULL)
+                       info->disp_info.machines =
+                               pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
+               if (info->disp_info.machines == NULL)
+                       return NT_STATUS_ACCESS_DENIED;
+               num_account = pdb_search_entries(info->disp_info.machines,
+                                                enum_context, max_entries,
+                                                &entries);
+               break;
+       case 0x3:
+       case 0x5:
+               if (info->disp_info.groups == NULL)
+                       info->disp_info.groups = pdb_search_groups();
+               if (info->disp_info.groups == NULL)
+                       return NT_STATUS_ACCESS_DENIED;
+               num_account = pdb_search_entries(info->disp_info.groups,
+                                                enum_context, max_entries,
+                                                &entries);
+               break;
+       default:
+               smb_panic("info class changed");
+               break;
+       }
+       unbecome_root();
+
        /* Now create reply structure */
        switch (q_u->switch_level) {
        case 0x1:
-               if (max_entries) {
-                       if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
-                               return NT_STATUS_NO_MEMORY;
-               }
-               disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
-                                              info->disp_info.disp_user_info, &domain_sid);
-               if (!NT_STATUS_IS_OK(disp_ret))
-                       return disp_ret;
+               disp_ret = init_sam_dispinfo_1(p->mem_ctx, &ctr->sam.info1,
+                                              num_account, enum_context,
+                                              entries);
                break;
        case 0x2:
-               if (max_entries) {
-                       if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
-                               return NT_STATUS_NO_MEMORY;
-               }
-               disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
-                                              info->disp_info.disp_user_info, &domain_sid);
-               if (!NT_STATUS_IS_OK(disp_ret))
-                       return disp_ret;
+               disp_ret = init_sam_dispinfo_2(p->mem_ctx, &ctr->sam.info2,
+                                              num_account, enum_context,
+                                              entries);
                break;
        case 0x3:
-               if (max_entries) {
-                       if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
-                               return NT_STATUS_NO_MEMORY;
-               }
-               disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
-               if (!NT_STATUS_IS_OK(disp_ret))
-                       return disp_ret;
+               disp_ret = init_sam_dispinfo_3(p->mem_ctx, &ctr->sam.info3,
+                                              num_account, enum_context,
+                                              entries);
                break;
        case 0x4:
-               if (max_entries) {
-                       if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
-                               return NT_STATUS_NO_MEMORY;
-               }
-               disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
-               if (!NT_STATUS_IS_OK(disp_ret))
-                       return disp_ret;
+               disp_ret = init_sam_dispinfo_4(p->mem_ctx, &ctr->sam.info4,
+                                              num_account, enum_context,
+                                              entries);
                break;
        case 0x5:
-               if (max_entries) {
-                       if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
-                               return NT_STATUS_NO_MEMORY;
-               }
-               disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
-               if (!NT_STATUS_IS_OK(disp_ret))
-                       return disp_ret;
+               disp_ret = init_sam_dispinfo_5(p->mem_ctx, &ctr->sam.info5,
+                                              num_account, enum_context,
+                                              entries);
                break;
-
        default:
-               ctr->sam.info = NULL;
-               return NT_STATUS_INVALID_INFO_CLASS;
+               smb_panic("info class changed");
+               break;
        }
 
+       if (!NT_STATUS_IS_OK(disp_ret))
+               return disp_ret;
+
        /* calculate the total size */
        total_data_size=num_account*struct_size;
 
@@ -1218,7 +951,9 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
 
        DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
 
-       init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
+       init_samr_r_query_dispinfo(r_u, num_account, total_data_size,
+                                  temp_size, q_u->switch_level, ctr,
+                                  r_u->status);
 
        return r_u->status;
 
@@ -1464,8 +1199,9 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
 makes a SAMR_R_LOOKUP_RIDS structure.
 ********************************************************************/
 
-static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
-           UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
+static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
+                                 const char **names, UNIHDR **pp_hdr_name,
+                                 UNISTR2 **pp_uni_name)
 {
        uint32 i;
        UNIHDR *hdr_name=NULL;
@@ -1485,7 +1221,7 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
        }
 
        for (i = 0; i < num_names; i++) {
-               DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
+               DEBUG(10, ("names[%d]:%s\n", i, *names[i] ? names[i] : ""));
                init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
                init_uni_hdr(&hdr_name[i], &uni_name[i]);
        }
@@ -1502,16 +1238,13 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
 
 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
 {
-       fstring group_names[MAX_SAM_ENTRIES];
-       uint32 *group_attrs = NULL;
+       const char **names;
+       uint32 *attrs = NULL;
        UNIHDR *hdr_name = NULL;
        UNISTR2 *uni_name = NULL;
        DOM_SID pol_sid;
        int num_rids = q_u->num_rids1;
-       int i;
        uint32 acc_granted;
-       BOOL have_mapped = False;
-       BOOL have_unmapped = False;
        
        r_u->status = NT_STATUS_OK;
 
@@ -1527,11 +1260,12 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (num_rids) {
-               if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
-                       return NT_STATUS_NO_MEMORY;
-       }
+       names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
+       attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
+
+       if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
+               return NT_STATUS_NO_MEMORY;
+
        if (!sid_equal(&pol_sid, get_global_sam_sid())) {
                /* TODO: Sooner or later we need to look up BUILTIN rids as
                 * well. -- vl */
@@ -1539,44 +1273,17 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
        }
 
        become_root();  /* lookup_sid can require root privs */
-
-       for (i = 0; i < num_rids; i++) {
-               fstring tmpname;
-               fstring domname;
-               DOM_SID sid;
-               enum SID_NAME_USE type;
-
-               group_attrs[i] = SID_NAME_UNKNOWN;
-               *group_names[i] = '\0';
-
-               sid_copy(&sid, &pol_sid);
-               sid_append_rid(&sid, q_u->rid[i]);
-
-               if (lookup_sid(&sid, domname, tmpname, &type)) {
-                       group_attrs[i] = (uint32)type;
-                       fstrcpy(group_names[i],tmpname);
-                       DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i],
-                                group_attrs[i]));
-                       have_mapped = True;
-               } else {
-                       have_unmapped = True;
-               }
-       }
-
+       r_u->status = pdb_lookup_rids(p->mem_ctx, &pol_sid, num_rids, q_u->rid,
+                                     &names, &attrs);
        unbecome_root();
 
  done:
 
-       r_u->status = NT_STATUS_NONE_MAPPED;
-
-       if (have_mapped)
-               r_u->status =
-                       have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
-
-       if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
+       if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
+                                 &hdr_name, &uni_name))
                return NT_STATUS_NO_MEMORY;
 
-       init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
+       init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs);
 
        DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
 
@@ -1977,7 +1684,7 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S
        DOM_GID *gids = NULL;
        int num_groups = 0;
        gid_t *unix_gids;
-       int i, num_gids, num_sids;
+       int i, num_gids;
        uint32 acc_granted;
        BOOL ret;
        NTSTATUS result;
@@ -2027,7 +1734,6 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S
        }
 
        sids = NULL;
-       num_sids = 0;
 
        become_root();
        result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
@@ -2130,23 +1836,11 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
                                       flag, nt_expire, nt_min_age);
                        break;
                case 0x02:
-                       become_root();          
-                       r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
+                       become_root();
+                       num_users=count_sam_users(&info->disp_info,
+                                                 ACB_NORMAL);
+                       num_groups=count_sam_groups(&info->disp_info);
                        unbecome_root();
-                       if (!NT_STATUS_IS_OK(r_u->status)) {
-                               DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
-                               return r_u->status;
-                       }
-                       num_users=info->disp_info.num_user_account;
-                       free_samr_db(info);
-                       
-                       r_u->status=load_group_domain_entries(info, get_global_sam_sid());
-                       if (!NT_STATUS_IS_OK(r_u->status)) {
-                               DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
-                               return r_u->status;
-                       }
-                       num_groups=info->disp_info.num_group_account;
-                       free_samr_db(info);
 
                        account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
                        u_logout = account_policy_temp;
@@ -2900,7 +2594,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
 
        acct_ctrl = pdb_get_acct_ctrl(pwd);
 
-       if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
+       if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2951,7 +2645,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
  set_user_info_pw
  ********************************************************************/
 
-static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
+static BOOL set_user_info_pw(uint8 *pass, SAM_ACCOUNT *pwd)
 {
        uint32 len;
        pstring plaintext_buf;
@@ -3097,7 +2791,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
 
                        dump_data(100, (char *)ctr->info.id24->pass, 516);
 
-                       if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
+                       if (!set_user_info_pw(ctr->info.id24->pass, pwd))
                                r_u->status = NT_STATUS_ACCESS_DENIED;
                        break;
 
@@ -3259,8 +2953,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
 
 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
 {
-       int num_groups = 0;
-       uint32 *rids=NULL;
+       int num_alias_rids;
+       uint32 *alias_rids;
        struct samr_info *info = NULL;
        int i;
                
@@ -3268,8 +2962,6 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
        NTSTATUS ntstatus2;
 
        DOM_SID *members;
-       DOM_SID *aliases;
-       int num_aliases;
        BOOL res;
 
        r_u->status = NT_STATUS_OK;
@@ -3302,35 +2994,20 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
        for (i=0; i<q_u->num_sids1; i++)
                sid_copy(&members[i], &q_u->sid[i].sid);
 
+       alias_rids = NULL;
+       num_alias_rids = 0;
+
        become_root();
-       res = pdb_enum_alias_memberships(members,
-                                        q_u->num_sids1, &aliases,
-                                        &num_aliases);
+       res = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
+                                        q_u->num_sids1,
+                                        &alias_rids, &num_alias_rids);
        unbecome_root();
 
        if (!res)
                return NT_STATUS_UNSUCCESSFUL;
 
-       rids = NULL;
-       num_groups = 0;
-
-       for (i=0; i<num_aliases; i++) {
-               uint32 rid;
-
-               if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
-                       continue;
-
-               rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
-
-               if (rids == NULL)
-                       return NT_STATUS_NO_MEMORY;
-
-               rids[num_groups] = rid;
-               num_groups += 1;
-       }
-       SAFE_FREE(aliases);
-
-       init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
+       init_samr_r_query_useraliases(r_u, num_alias_rids, alias_rids,
+                                     NT_STATUS_OK);
        return NT_STATUS_OK;
 }
 
@@ -3821,7 +3498,6 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
        DOM_SID user_sid;
        SAM_ACCOUNT *sam_pass=NULL;
        uint32 acc_granted;
-       SE_PRIV se_rights;
        BOOL can_add_accounts;
        BOOL ret;
 
@@ -3847,8 +3523,7 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
                return NT_STATUS_NO_SUCH_USER;
        }
        
-       se_priv_copy( &se_rights, &se_add_users );
-       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+       can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
 
        /******** BEGIN SeAddUsers BLOCK *********/
        
@@ -4121,7 +3796,6 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
        DOM_SID dom_sid;
        DOM_SID info_sid;
        fstring name;
-       struct group *grp;
        struct samr_info *info;
        uint32 acc_granted;
        gid_t gid;
@@ -4168,7 +3842,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
                return NT_STATUS_ACCESS_DENIED;
 
        /* check if the group has been successfully created */
-       if ((grp=getgrgid(gid)) == NULL)
+       if ( getgrgid(gid) == NULL )
                return NT_STATUS_ACCESS_DENIED;
 
        if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
@@ -4424,13 +4098,9 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
 {
-       DOM_SID                 delete_sid, alias_sid;
-       SAM_ACCOUNT             *sam_pass=NULL;
+       DOM_SID                 delete_sid, domain_sid;
        uint32                  acc_granted;
-       GROUP_MAP               map;
-       BOOL                    is_user = False;
        NTSTATUS                result;
-       enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
        
        sid_copy( &delete_sid, &q_u->sid.sid );
        
@@ -4439,7 +4109,8 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
                
        /* Find the policy handle. Open a policy on it. */
        
-       if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
+       if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &domain_sid,
+                                    &acc_granted)) 
                return NT_STATUS_INVALID_HANDLE;
        
        result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
@@ -4449,80 +4120,33 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
                return result;
                        
        DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
-               sid_string_static(&alias_sid)));
-               
-       /* make sure we can handle this */
-       
-       if ( sid_check_is_domain(&alias_sid) )
-               type = SID_NAME_DOM_GRP;
-       else if ( sid_check_is_builtin(&alias_sid) )
-               type = SID_NAME_ALIAS;
-       
-       if ( type == SID_NAME_UNKNOWN ) {
-               DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
-               return NT_STATUS_OK;
-       }
+               sid_string_static(&domain_sid)));
 
-       /* check if the user exists before trying to delete */
-       
-       pdb_init_sam(&sam_pass);
-       
-       if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
-               is_user = True;
-       } else {
-               /* maybe it is a group */
-               if( !pdb_getgrsid(&map, delete_sid) ) {
-                       DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
-                               sid_string_static(&delete_sid)));
-                       result = NT_STATUS_INVALID_SID;
-                       goto done;
-               }
-       }
-       
        /* we can only delete a user from a group since we don't have 
           nested groups anyways.  So in the latter case, just say OK */
-          
-       if ( is_user ) {
-               GROUP_MAP       *mappings = NULL;
-               int             num_groups, i;
-               struct group    *grp2;
-               
-               if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
-               
-                       /* interate over the groups */
-                       for ( i=0; i<num_groups; i++ ) {
 
-                               grp2 = getgrgid(mappings[i].gid);
-
-                               if ( !grp2 ) {
-                                       DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
-                                       continue;
-                               }
-                       
-                               if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
-                                       continue;
-                               
-                               smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
-                               
-                               if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
-                                       /* should we fail here ? */
-                                       DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
-                                               pdb_get_username(sam_pass), grp2->gr_name ));
-                                       continue;
-                               }
-                                       
-                               DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
-                                       pdb_get_username(sam_pass), grp2->gr_name ));
-                       }
-                       
-                       SAFE_FREE(mappings);
-               }
+       /* TODO: The above comment nowadays is bogus. Since we have nested
+        * groups now, and aliases members are never reported out of the unix
+        * group membership, the "just say OK" makes this call a no-op. For
+        * us. This needs fixing however. */
+
+       /* I've only ever seen this in the wild when deleting a user from
+        * usrmgr.exe. domain_sid is the builtin domain, and the sid to delete
+        * is the user about to be deleted. I very much suspect this is the
+        * only application of this call. To verify this, let people report
+        * other cases. */
+
+       if (!sid_check_is_builtin(&domain_sid)) {
+               DEBUG(1,("_samr_remove_sid_foreign_domain: domain_sid = %s, "
+                        "global_sam_sid() = %s\n",
+                        sid_string_static(&domain_sid),
+                        sid_string_static(get_global_sam_sid())));
+               DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
+               return NT_STATUS_OK;
        }
-       
-       result = NT_STATUS_OK;
-done:
 
-       pdb_free_sam(&sam_pass);
+
+       result = NT_STATUS_OK;
 
        return result;
 }
@@ -4589,21 +4213,11 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
                        break;
                case 0x02:
                        become_root();          
-                       r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
+                       num_users = count_sam_users(&info->disp_info,
+                                                   ACB_NORMAL);
+                       num_groups = count_sam_groups(&info->disp_info);
                        unbecome_root();
-                       if (!NT_STATUS_IS_OK(r_u->status)) {
-                               DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
-                               return r_u->status;
-                       }
-                       num_users=info->disp_info.num_user_account;
-                       free_samr_db(info);
-                       
-                       r_u->status=load_group_domain_entries(info, get_global_sam_sid());
-                       if (NT_STATUS_IS_ERR(r_u->status)) {
-                               DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
-                               return r_u->status;
-                       }
-                       num_groups=info->disp_info.num_group_account;
+
                        free_samr_db(info);
 
                        account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
index 6797730be97abb50f32e4c3ddbc75306b6d3c911..61160ccaa02c009364e33675d8d0014607a1454f 100644 (file)
@@ -264,7 +264,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
 
                DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
                pdb_sethexhours(old, pdb_get_hours(to));
-               pdb_sethexhours(new, (const char *)from->logon_hrs.hours);
+               pdb_sethexhours(new, from->logon_hrs.hours);
                if (!strequal(old, new)) {
                        pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
                }
index f846813a40b86be85dc653b428e60ae4f316fc47..b3a67dd6cfd540eb309179339af70c81c6f4b9c9 100755 (executable)
@@ -1244,6 +1244,9 @@ static BOOL api_spoolss_getjob(pipes_struct *p)
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
        
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+       
        if(!spoolss_io_q_getjob("", &q_u, data, 0)) {
                DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n"));
                return False;
index ffeeb0af9a9da1ed6c1d7924e089f2dcf68ba6af..0f33fd7dec87c113b6167ae8069982652dca5979 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "includes.h"
 
+extern userdom_struct current_user_info;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -644,41 +646,6 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
        return True;
 }
 
-/****************************************************************************
- Allocate more memory for a BUFFER.
-****************************************************************************/
-
-static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
-{
-       prs_struct *ps;
-       uint32 extra_space;
-       uint32 old_offset;
-       
-       ps= &buffer->prs;
-
-       /* damn, I'm doing the reverse operation of prs_grow() :) */
-       if (buffer_size < prs_data_size(ps))
-               extra_space=0;
-       else    
-               extra_space = buffer_size - prs_data_size(ps);
-
-       /*
-        * save the offset and move to the end of the buffer
-        * prs_grow() checks the extra_space against the offset
-        */
-       old_offset=prs_offset(ps);      
-       prs_set_offset(ps, prs_data_size(ps));
-       
-       if (!prs_grow(ps, extra_space))
-               return False;
-
-       prs_set_offset(ps, old_offset);
-
-       buffer->string_at_end=prs_data_size(ps);
-
-       return True;
-}
-
 /***************************************************************************
  check to see if the client motify handle is monitoring the notification
  given by (notify_type, notify_field).
@@ -1526,10 +1493,10 @@ static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q
 
        DEBUG(8,("convert_to_openprinterex\n"));
                                
-       q_u_ex->printername_ptr = q_u->printername_ptr;
-       
-       if (q_u->printername_ptr)
-               copy_unistr2(&q_u_ex->printername, &q_u->printername);
+       if ( q_u->printername ) {
+               q_u_ex->printername = TALLOC_P( ctx, UNISTR2 );
+               copy_unistr2(q_u_ex->printername, q_u->printername);
+       }
        
        copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
 }
@@ -1623,7 +1590,6 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R
 
 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
 {
-       UNISTR2                 *printername = NULL;
        PRINTER_DEFAULT         *printer_default = &q_u->printer_default;
        POLICY_HND              *handle = &r_u->handle;
 
@@ -1632,15 +1598,13 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
        struct current_user user;
        Printer_entry *Printer=NULL;
 
-       if (q_u->printername_ptr != 0)
-               printername = &q_u->printername;
-
-       if (printername == NULL)
+       if ( !q_u->printername )
                return WERR_INVALID_PRINTER_NAME;
 
        /* some sanity check because you can open a printer or a print server */
        /* aka: \\server\printer or \\server */
-       unistr2_to_ascii(name, printername, sizeof(name)-1);
+
+       unistr2_to_ascii(name, q_u->printername, sizeof(name)-1);
 
        DEBUGADD(3,("checking name: %s\n",name));
 
@@ -4121,7 +4085,7 @@ static void free_dev_mode(DEVICEMODE *dev)
        if (dev == NULL)
                return;
 
-               SAFE_FREE(dev->private);
+       SAFE_FREE(dev->private);
        SAFE_FREE(dev); 
 }
 
@@ -4404,13 +4368,14 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
  Spoolss_enumprinters.
 ********************************************************************/
 
-static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
        PRINTER_INFO_1 *tp, *printers=NULL;
        PRINTER_INFO_1 current_prt;
+       WERROR result = WERR_OK;
        
        DEBUG(4,("enum_all_printers_info_1\n"));        
 
@@ -4438,29 +4403,36 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_printer_info_1(&printers[i]);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_printer_info_1("", buffer, &printers[i], 0);     
 
+out:
        /* clear memory */
+
        SAFE_FREE(printers);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
 /********************************************************************
  enum_all_printers_info_1_local.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        DEBUG(4,("enum_all_printers_info_1_local\n"));  
        
@@ -4471,7 +4443,7 @@ static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered,
  enum_all_printers_info_1_name.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        char *s = name;
        
@@ -4492,13 +4464,14 @@ static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, ui
  enum_all_printers_info_1_remote.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTER_INFO_1 *printer;
        fstring printername;
        fstring desc;
        fstring comment;
        DEBUG(4,("enum_all_printers_info_1_remote\n")); 
+       WERROR result = WERR_OK;
 
        /* JFM: currently it's more a place holder than anything else.
         * In the spooler world there is a notion of server registration.
@@ -4525,23 +4498,27 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_1("", buffer, printer, 0);  
 
+out:
        /* clear memory */
        SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
 #endif
@@ -4550,7 +4527,7 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
  enum_all_printers_info_1_network.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        char *s = name;
 
@@ -4579,13 +4556,14 @@ static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer,
  * called from api_spoolss_enumprinters (see this to understand)
  ********************************************************************/
 
-static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
        PRINTER_INFO_2 *tp, *printers=NULL;
        PRINTER_INFO_2 current_prt;
+       WERROR result = WERR_OK;
 
        for (snum=0; snum<n_services; snum++) {
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
@@ -4610,30 +4588,31 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
        for (i=0; i<*returned; i++) 
                (*needed) += spoolss_size_printer_info_2(&printers[i]);
        
-       if (!alloc_buffer_size(buffer, *needed)) {
-               for (i=0; i<*returned; i++) {
-                       free_devmode(printers[i].devmode);
-               }
-               SAFE_FREE(printers);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_printer_info_2("", buffer, &(printers[i]), 0);   
        
+out:
        /* clear memory */
        for (i=0; i<*returned; i++) {
                free_devmode(printers[i].devmode);
        }
        SAFE_FREE(printers);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
 /********************************************************************
@@ -4641,7 +4620,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
  ********************************************************************/
 
 static WERROR enumprinters_level1( uint32 flags, fstring name,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
        /* Not all the flags are equals */
@@ -4668,7 +4647,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
  ********************************************************************/
 
 static WERROR enumprinters_level2( uint32 flags, fstring servername,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
        char *s = servername;
@@ -4697,7 +4676,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername,
  ********************************************************************/
 
 static WERROR enumprinters_level5( uint32 flags, fstring servername,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
 /*     return enum_all_printers_info_5(buffer, offered, needed, returned);*/
@@ -4715,7 +4694,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
        uint32 flags = q_u->flags;
        UNISTR2 *servername = &q_u->servername;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
@@ -4723,8 +4702,11 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
        fstring name;
        
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumprinters\n"));
 
@@ -4764,9 +4746,10 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_0 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
                return WERR_NOMEM;
@@ -4776,30 +4759,34 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_0(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_0("", buffer, printer, 0);  
        
+out:
        /* clear memory */
-       SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       SAFE_FREE(printer);
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_1 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
                return WERR_NOMEM;
@@ -4809,30 +4796,33 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_1("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_2 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
                return WERR_NOMEM;
@@ -4842,33 +4832,34 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_2(printer);
        
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_2(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
        }
 
-       /* fill the buffer with the structures */
-       if (!smb_io_printer_info_2("", buffer, printer, 0)) {
-               free_printer_info_2(printer);
-               return WERR_NOMEM;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
+
+       /* fill the buffer with the structures */
+       if (!smb_io_printer_info_2("", buffer, printer, 0)) 
+               result = WERR_NOMEM;
        
+out:
        /* clear memory */
        free_printer_info_2(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_3 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if (!construct_printer_info_3(print_hnd, &printer, snum))
                return WERR_NOMEM;
@@ -4876,30 +4867,33 @@ static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_3(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_3(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_3("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_3(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_4 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
                return WERR_NOMEM;
@@ -4910,30 +4904,33 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_4(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_4(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_4("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_4(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_5 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
                return WERR_NOMEM;
@@ -4944,27 +4941,30 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_5(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_5(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_5("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_5(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_7 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
                return WERR_NOMEM;
@@ -4975,22 +4975,25 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_7(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_7(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_7("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_7(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
@@ -5000,7 +5003,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
 {
        POLICY_HND *handle = &q_u->handle;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
@@ -5008,8 +5011,11 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
        int snum;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        *needed=0;
 
@@ -5433,149 +5439,154 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
 {
        SAFE_FREE(info->dependentfiles);
-       
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_1 *info=NULL;
-       WERROR status;
+       WERROR result;
        
        if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
                return WERR_NOMEM;
        
-       status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               SAFE_FREE(info);
-               return status;
-       }
+       result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_1("", buffer, info, 0);      
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_2 *info=NULL;
-       WERROR status;
+       WERROR result;
        
        if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
                return WERR_NOMEM;
        
-       status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               SAFE_FREE(info);
-               return status;
-       }
+       result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_2(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+       
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_2("", buffer, info, 0);      
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_3 info;
-       WERROR status;
+       WERROR result;
 
        ZERO_STRUCT(info);
 
-       status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               return status;
-       }
+       result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result))
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_3(&info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_driver_info_3(&info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_3("", buffer, &info, 0);
 
+out:
        free_printer_driver_info_3(&info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_6 info;
-       WERROR status;
+       WERROR result;
 
        ZERO_STRUCT(info);
 
-       status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               return status;
-       }
+       result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_6(&info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_driver_info_6(&info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+       
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_6("", buffer, &info, 0);
 
+out:
        free_printer_driver_info_6(&info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -5587,7 +5598,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
        UNISTR2 *uni_arch = &q_u->architecture;
        uint32 level = q_u->level;
        uint32 clientmajorversion = q_u->clientmajorversion;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *servermajorversion = &r_u->servermajorversion;
@@ -5599,8 +5610,11 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
        int snum;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_getprinterdriver2\n"));
 
@@ -6015,7 +6029,6 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 
 static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 {
-       extern userdom_struct current_user_info;
        char *cmd = lp_addprinter_cmd();
        char **qlines;
        pstring command;
@@ -6389,8 +6402,10 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
 
 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
 {
-       /* that's an [in out] buffer (despite appearences to the contrary) */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+       /* that's an [in out] buffer */
+
+       if ( q_u->buffer ) 
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
 
        r_u->needed = 0;
        return WERR_INVALID_PARAM; /* this is what a NT server
@@ -6476,11 +6491,12 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
 
 static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
                               NT_PRINTER_INFO_LEVEL *ntprinter,
-                             NEW_BUFFER *buffer, uint32 offered,
+                             RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
        JOB_INFO_1 *info;
        int i;
+       WERROR result = WERR_OK;
        
        info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
        if (info==NULL) {
@@ -6498,24 +6514,28 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_job_info_1(&info[i]);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_job_info_1("", buffer, &info[i], 0);     
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -6524,19 +6544,17 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
 
 static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
                               NT_PRINTER_INFO_LEVEL *ntprinter,
-                             NEW_BUFFER *buffer, uint32 offered,
+                             RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
        JOB_INFO_2 *info = NULL;
        int i;
-       WERROR result;
+       WERROR result = WERR_OK;
        DEVICEMODE *devmode = NULL;
        
-       info=SMB_MALLOC_ARRAY(JOB_INFO_2,*returned);
-       if (info==NULL) {
+       if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
                *returned=0;
-               result = WERR_NOMEM;
-               goto done;
+               return WERR_NOMEM;
        }
                
        /* this should not be a failure condition if the devmode is NULL */
@@ -6544,8 +6562,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
        devmode = construct_dev_mode(snum);
 
        for (i=0; i<*returned; i++)
-               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter,
-                               devmode);
+               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
 
        free_a_printer(&ntprinter, 2);
        SAFE_FREE(queue);
@@ -6555,29 +6572,26 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
                (*needed) += spoolss_size_job_info_2(&info[i]);
 
        if (*needed > offered) {
-               *returned=0;
                result = WERR_INSUFFICIENT_BUFFER;
-               goto done;
+               goto out;
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto done;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_job_info_2("", buffer, &info[i], 0);     
 
-       result = WERR_OK;
-
- done:
-       free_a_printer(&ntprinter, 2);
+out:
        free_devmode(devmode);
-       SAFE_FREE(queue);
        SAFE_FREE(info);
 
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
        return result;
 
 }
@@ -6590,7 +6604,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
 {      
        POLICY_HND *handle = &q_u->handle;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
@@ -6601,8 +6615,11 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
        print_queue_struct *queue=NULL;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumjobs\n"));
 
@@ -6703,15 +6720,15 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
  Enumerates all printer drivers at level 1.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6757,9 +6774,14 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_1);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
        }
 
        /* fill the buffer with the driver structures */
@@ -6768,29 +6790,28 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
        }
 
+out:
        SAFE_FREE(driver_info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 2.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6837,9 +6858,14 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_2);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
        }
 
        /* fill the buffer with the form structures */
@@ -6848,29 +6874,28 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
        }
 
+out:
        SAFE_FREE(driver_info_2);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 3.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6917,28 +6942,32 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_3);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
        }
-       
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
+       }
+
        /* fill the buffer with the driver structures */
        for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d] to buffer\n",i));
                smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
        }
 
+out:
        for (i=0; i<*returned; i++)
                SAFE_FREE(driver_info_3[i].dependentfiles);
-       
+
        SAFE_FREE(driver_info_3);
        
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -6948,22 +6977,25 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
-       fstring *list = NULL;
        fstring servername;
        fstring architecture;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumprinterdrivers\n"));
-       *needed=0;
-       *returned=0;
+       
+       *needed   = 0;
+       *returned = 0;
 
        unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1);
        unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1);
@@ -6979,8 +7011,6 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
        case 3:
                return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
        default:
-               *returned=0;
-               SAFE_FREE(list);
                return WERR_UNKNOWN_LEVEL;
        }
 }
@@ -7006,7 +7036,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *numofforms = &r_u->numofforms;
@@ -7019,8 +7049,11 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
        int i;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumforms\n"));
        DEBUGADD(5,("Offered buffer size [%d]\n", offered));
@@ -7032,7 +7065,8 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
        DEBUGADD(5,("Number of user forms [%d]\n",     *numofforms));
        *numofforms += numbuiltinforms;
 
-       if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
+       if (*numofforms == 0) 
+               return WERR_NO_MORE_ITEMS;
 
        switch (level) {
        case 1:
@@ -7068,10 +7102,17 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
 
                *needed=buffer_size;            
                
-               if (!alloc_buffer_size(buffer, buffer_size)){
+               if (*needed > offered) {
                        SAFE_FREE(forms_1);
+                       *numofforms=0;
                        return WERR_INSUFFICIENT_BUFFER;
                }
+       
+               if (!rpcbuf_alloc_size(buffer, buffer_size)){
+                       SAFE_FREE(forms_1);
+                       *numofforms=0;
+                       return WERR_NOMEM;
+               }
 
                /* fill the buffer with the form structures */
                for (i=0; i<numbuiltinforms; i++) {
@@ -7085,12 +7126,7 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
 
                SAFE_FREE(forms_1);
 
-               if (*needed > offered) {
-                       *numofforms=0;
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
-               else
-                       return WERR_OK;
+               return WERR_OK;
                        
        default:
                SAFE_FREE(list);
@@ -7107,7 +7143,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
 {
        uint32 level = q_u->level;
        UNISTR2 *uni_formname = &q_u->formname;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
 
@@ -7120,8 +7156,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
        int numofforms=0, i=0;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
 
@@ -7165,13 +7204,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
 
                *needed=spoolss_size_form_1(&form_1);
                
-               if (!alloc_buffer_size(buffer, buffer_size)){
+               if (*needed > offered) 
                        return WERR_INSUFFICIENT_BUFFER;
-               }
 
-               if (*needed > offered) {
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
+               if (!rpcbuf_alloc_size(buffer, buffer_size))
+                       return WERR_NOMEM;
 
                /* fill the buffer with the form structures */
                DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
@@ -7209,10 +7246,11 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
  enumports level 1.
 ****************************************************************************/
 
-static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PORT_INFO_1 *ports=NULL;
        int i=0;
+       WERROR result = WERR_OK;
 
        if (*lp_enumports_cmd()) {
                char *cmd = lp_enumports_cmd();
@@ -7274,9 +7312,14 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                *needed += spoolss_size_port_info_1(&ports[i]);
        }
                
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(ports);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the ports structures */
@@ -7285,24 +7328,24 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                smb_io_port_1("", buffer, &ports[i], 0);
        }
 
+out:
        SAFE_FREE(ports);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  enumports level 2.
 ****************************************************************************/
 
-static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PORT_INFO_2 *ports=NULL;
        int i=0;
+       WERROR result = WERR_OK;
 
        if (*lp_enumports_cmd()) {
                char *cmd = lp_enumports_cmd();
@@ -7372,9 +7415,14 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                *needed += spoolss_size_port_info_2(&ports[i]);
        }
                
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(ports);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the ports structures */
@@ -7383,14 +7431,13 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                smb_io_port_2("", buffer, &ports[i], 0);
        }
 
+out:
        SAFE_FREE(ports);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -7400,14 +7447,17 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumports\n"));
        
@@ -7543,7 +7593,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
 
 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
 {
-       UNISTR2 *uni_srv_name = &q_u->server_name;
+       UNISTR2 *uni_srv_name = q_u->server_name;
        uint32 level = q_u->level;
        SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
        DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
@@ -7741,7 +7791,7 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        pstring path;
        pstring long_archi;
@@ -7749,6 +7799,7 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
        char *pservername; 
        const char *short_archi;
        DRIVER_DIRECTORY_1 *info=NULL;
+       WERROR result = WERR_OK;
 
        unistr2_to_ascii(servername, name, sizeof(servername)-1);
        unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
@@ -7778,19 +7829,22 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
        
        *needed += spoolss_size_driverdir_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        smb_io_driverdir_1("", buffer, info, 0);
 
+out:
        SAFE_FREE(info);
        
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -7801,13 +7855,16 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
        UNISTR2 *name = &q_u->name;
        UNISTR2 *uni_environment = &q_u->environment;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
 
@@ -8367,9 +8424,10 @@ done:
  enumprintprocessors level 1.
 ****************************************************************************/
 
-static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTPROCESSOR_1 *info_1=NULL;
+       WERROR result = WERR_OK;
        
        if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
                return WERR_NOMEM;
@@ -8380,19 +8438,25 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
 
        *needed += spoolss_size_printprocessor_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printprocessor_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -8401,14 +8465,17 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_enumprintprocessors\n"));
 
@@ -8434,9 +8501,10 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
  enumprintprocdatatypes level 1.
 ****************************************************************************/
 
-static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTPROCDATATYPE_1 *info_1=NULL;
+       WERROR result = WERR_NOMEM;
        
        if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
                return WERR_NOMEM;
@@ -8447,19 +8515,25 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
 
        *needed += spoolss_size_printprocdatatype_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -8468,14 +8542,17 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
        
@@ -8494,9 +8571,10 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
  enumprintmonitors level 1.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTMONITOR_1 *info_1=NULL;
+       WERROR result = WERR_OK;
        
        if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL)
                return WERR_NOMEM;
@@ -8507,28 +8585,35 @@ static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
 
        *needed += spoolss_size_printmonitor_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printmonitor_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  enumprintmonitors level 2.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTMONITOR_2 *info_2=NULL;
+       WERROR result = WERR_OK;
        
        if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL)
                return WERR_NOMEM;
@@ -8541,19 +8626,25 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
 
        *needed += spoolss_size_printmonitor_info_2(info_2);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printmonitor_info_2("", buffer, info_2, 0);
 
+out:
        SAFE_FREE(info_2);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+       
+       return result;
 }
 
 /****************************************************************************
@@ -8562,14 +8653,17 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_enumprintmonitors\n"));
 
@@ -8598,12 +8692,13 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
 
 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
                              NT_PRINTER_INFO_LEVEL *ntprinter,
-                             uint32 jobid, NEW_BUFFER *buffer, uint32 offered, 
+                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 
                             uint32 *needed)
 {
        int i=0;
        BOOL found=False;
        JOB_INFO_1 *info_1=NULL;
+       WERROR result = WERR_OK;
 
        info_1=SMB_MALLOC_P(JOB_INFO_1);
 
@@ -8626,19 +8721,22 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
        
        *needed += spoolss_size_job_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info_1);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        smb_io_job_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -8646,36 +8744,31 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
 
 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, 
                              NT_PRINTER_INFO_LEVEL *ntprinter,
-                             uint32 jobid, NEW_BUFFER *buffer, uint32 offered, 
+                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 
                             uint32 *needed)
 {
        int             i = 0;
        BOOL            found = False;
        JOB_INFO_2      *info_2;
-       WERROR          ret;
+       WERROR          result;
        DEVICEMODE      *devmode = NULL;
        NT_DEVICEMODE   *nt_devmode = NULL;
 
-       info_2=SMB_MALLOC_P(JOB_INFO_2);
+       if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
+               return WERR_NOMEM;
 
        ZERO_STRUCTP(info_2);
 
-       if (info_2 == NULL) {
-               ret = WERR_NOMEM;
-               goto done;
-       }
-
        for ( i=0; i<count && found==False; i++ ) 
        {
                if ((*queue)[i].job == (int)jobid)
                        found = True;
        }
        
-       if ( !found ) 
-       {
+       if ( !found ) {
                /* NT treats not found as bad param... yet another bad
                   choice */
-               ret = WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
                goto done;
        }
        
@@ -8698,19 +8791,19 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
        
        *needed += spoolss_size_job_info_2(info_2);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               ret = WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
                goto done;
        }
 
-       smb_io_job_info_2("", buffer, info_2, 0);
-
-       if (*needed > offered) {
-               ret = WERR_INSUFFICIENT_BUFFER;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
                goto done;
        }
 
-       ret = WERR_OK;
+       smb_io_job_info_2("", buffer, info_2, 0);
+
+       result = WERR_OK;
        
  done:
        /* Cleanup allocated memory */
@@ -8718,7 +8811,7 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
        free_job_info_2(info_2);        /* Also frees devmode */
        SAFE_FREE(info_2);
 
-       return ret;
+       return result;
 }
 
 /****************************************************************************
@@ -8729,7 +8822,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        POLICY_HND *handle = &q_u->handle;
        uint32 jobid = q_u->jobid;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        WERROR          wstatus = WERR_OK;
@@ -8740,8 +8833,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        print_status_struct prt_status;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_getjob\n"));
        
@@ -9307,13 +9403,14 @@ static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, cha
 
 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, 
                                                 UNISTR2 *environment, 
-                                                NEW_BUFFER *buffer, 
+                                                RPC_BUFFER *buffer, 
                                                 uint32 offered, 
                                                 uint32 *needed)
 {
        pstring path;
        pstring long_archi;
        PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+       WERROR result = WERR_OK;
 
        unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
 
@@ -9329,32 +9426,38 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
        
        *needed += spoolss_size_printprocessordirectory_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               safe_free(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
        }
 
        smb_io_printprocessordirectory_1("", buffer, info, 0);
 
-       safe_free(info);
+out:
+       SAFE_FREE(info);
        
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       else
-               return WERR_OK;
+       return result;
 }
 
 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        WERROR result;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
        
index 9d85088e568beff3a1a6eecac2a0fb5d44b5007a..0b4eac5cc7304310857e6fa70dac9985a80d7c3e 100644 (file)
@@ -165,6 +165,34 @@ static BOOL api_srv_net_sess_enum(pipes_struct *p)
        return True;
 }
 
+/*******************************************************************
+ Delete session.
+********************************************************************/
+
+static BOOL api_srv_net_sess_del(pipes_struct *p)
+{
+       SRV_Q_NET_SESS_DEL q_u;
+       SRV_R_NET_SESS_DEL r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       /* grab the net server get enum */
+       if (!srv_io_q_net_sess_del("", &q_u, data, 0))
+               return False;
+
+       /* construct reply.  always indicate success */
+       r_u.status = _srv_net_sess_del(p, &q_u, &r_u);
+
+       /* store the response in the SMB stream */
+       if (!srv_io_r_net_sess_del("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  RPC to enumerate shares.
 ********************************************************************/
@@ -530,6 +558,7 @@ static struct api_struct api_srv_cmds[] =
 {
       { "SRV_NET_CONN_ENUM"         , SRV_NET_CONN_ENUM         , api_srv_net_conn_enum          },
       { "SRV_NET_SESS_ENUM"         , SRV_NET_SESS_ENUM         , api_srv_net_sess_enum          },
+      { "SRV_NET_SESS_DEL"          , SRV_NET_SESS_DEL          , api_srv_net_sess_del           },
       { "SRV_NET_SHARE_ENUM_ALL"    , SRV_NET_SHARE_ENUM_ALL    , api_srv_net_share_enum_all     },
       { "SRV_NET_SHARE_ENUM"        , SRV_NET_SHARE_ENUM        , api_srv_net_share_enum         },
       { "SRV_NET_SHARE_ADD"         , SRV_NET_SHARE_ADD         , api_srv_net_share_add          },
index 13e1971925aa818904a5c14a6aa0e820ad02641c..b5768a09af038f914bde2a68881daf09bea8ff02 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "includes.h"
 
+extern struct generic_mapping file_generic_mapping;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -170,8 +172,6 @@ BOOL share_info_db_init(void)
 
 static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
 {
-       extern DOM_SID global_sid_World;
-       extern struct generic_mapping file_generic_mapping;
        SEC_ACCESS sa;
        SEC_ACE ace;
        SEC_ACL *psa = NULL;
@@ -293,7 +293,6 @@ static BOOL delete_share_security(int snum)
 
 void map_generic_share_sd_bits(SEC_DESC *psd)
 {
-       extern struct generic_mapping file_generic_mapping;
        int i;
        SEC_ACL *ps_dacl = NULL;
 
@@ -1348,6 +1347,70 @@ WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_S
        return r_u->status;
 }
 
+/*******************************************************************
+net sess del
+********************************************************************/
+
+WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
+{
+       struct sessionid *session_list;
+       struct current_user user;
+       int num_sessions, snum, ret;
+       fstring username;
+       fstring machine;
+       BOOL not_root = False;
+
+       rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
+       rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
+
+       /* strip leading backslashes if any */
+       while (machine[0] == '\\') {
+               memmove(machine, &machine[1], strlen(machine));
+       }
+
+       num_sessions = list_sessions(&session_list);
+
+       DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
+
+       r_u->status = WERR_ACCESS_DENIED;
+
+       get_current_user(&user, p);
+
+       /* fail out now if you are not root or not a domain admin */
+
+       if ((user.uid != sec_initial_uid()) && 
+               ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
+
+               goto done;
+       }
+
+       for (snum = 0; snum < num_sessions; snum++) {
+
+               if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
+                   strequal(session_list[snum].remote_machine, machine)) {
+               
+                       if (user.uid != sec_initial_uid()) {
+                               not_root = True;
+                               become_root();
+                       }
+
+                       if ((ret = message_send_pid(session_list[snum].pid, MSG_SHUTDOWN, NULL, 0, False))) 
+                               r_u->status = WERR_OK;
+
+                       if (not_root) 
+                               unbecome_root();
+               }
+       }
+
+       DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
+
+
+done:
+       SAFE_FREE(session_list);
+
+       return r_u->status;
+}
+
 /*******************************************************************
  Net share enum all.
 ********************************************************************/
@@ -1454,7 +1517,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
        char *path;
        SEC_DESC *psd = NULL;
        SE_PRIV se_diskop = SE_DISK_OPERATOR;
-       BOOL is_disk_op;
+       BOOL is_disk_op = False;
 
        DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
 
diff --git a/source/rpc_server/srv_svcctl.c b/source/rpc_server/srv_svcctl.c
new file mode 100644 (file)
index 0000000..85fb9f9
--- /dev/null
@@ -0,0 +1,294 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Gerald Carter                   2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_close_service(pipes_struct *p)
+{
+       SVCCTL_Q_CLOSE_SERVICE q_u;
+       SVCCTL_R_CLOSE_SERVICE r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_close_service("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_close_service(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_close_service("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_open_scmanager(pipes_struct *p)
+{
+       SVCCTL_Q_OPEN_SCMANAGER q_u;
+       SVCCTL_R_OPEN_SCMANAGER r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_open_scmanager("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_open_scmanager(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_open_scmanager("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_open_service(pipes_struct *p)
+{
+       SVCCTL_Q_OPEN_SERVICE q_u;
+       SVCCTL_R_OPEN_SERVICE r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_open_service("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_open_service(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_open_service("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_get_display_name(pipes_struct *p)
+{
+       SVCCTL_Q_GET_DISPLAY_NAME q_u;
+       SVCCTL_R_GET_DISPLAY_NAME r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_get_display_name("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_get_display_name(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_get_display_name("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_query_status(pipes_struct *p)
+{
+       SVCCTL_Q_QUERY_STATUS q_u;
+       SVCCTL_R_QUERY_STATUS r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_query_status("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_query_status(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_query_status("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_enum_services_status(pipes_struct *p)
+{
+       SVCCTL_Q_ENUM_SERVICES_STATUS q_u;
+       SVCCTL_R_ENUM_SERVICES_STATUS r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_enum_services_status("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_enum_services_status(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_enum_services_status("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_enum_dependent_services(pipes_struct *p)
+{
+       SVCCTL_Q_ENUM_DEPENDENT_SERVICES q_u;
+       SVCCTL_R_ENUM_DEPENDENT_SERVICES r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_enum_dependent_services("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_enum_dependent_services(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_enum_dependent_services("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_start_service(pipes_struct *p)
+{
+       SVCCTL_Q_START_SERVICE q_u;
+       SVCCTL_R_START_SERVICE r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_start_service("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_start_service(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_start_service("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_control_service(pipes_struct *p)
+{
+       SVCCTL_Q_CONTROL_SERVICE q_u;
+       SVCCTL_R_CONTROL_SERVICE r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_control_service("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_control_service(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_control_service("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_query_service_config(pipes_struct *p)
+{
+       SVCCTL_Q_QUERY_SERVICE_CONFIG q_u;
+       SVCCTL_R_QUERY_SERVICE_CONFIG r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       if(!svcctl_io_q_query_service_config("", &q_u, data, 0))
+               return False;
+
+       r_u.status = _svcctl_query_service_config(p, &q_u, &r_u);
+
+       if(!svcctl_io_r_query_service_config("", &r_u, rdata, 0))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ \PIPE\svcctl commands
+ ********************************************************************/
+
+static struct api_struct api_svcctl_cmds[] =
+{
+      { "SVCCTL_CLOSE_SERVICE"         , SVCCTL_CLOSE_SERVICE         , api_svcctl_close_service },
+      { "SVCCTL_OPEN_SCMANAGER_W"      , SVCCTL_OPEN_SCMANAGER_W      , api_svcctl_open_scmanager },
+      { "SVCCTL_OPEN_SERVICE_W"        , SVCCTL_OPEN_SERVICE_W        , api_svcctl_open_service },
+      { "SVCCTL_GET_DISPLAY_NAME"      , SVCCTL_GET_DISPLAY_NAME      , api_svcctl_get_display_name },
+      { "SVCCTL_QUERY_STATUS"          , SVCCTL_QUERY_STATUS          , api_svcctl_query_status },
+      { "SVCCTL_QUERY_SERVICE_CONFIG_W", SVCCTL_QUERY_SERVICE_CONFIG_W, api_svcctl_query_service_config },
+      { "SVCCTL_ENUM_SERVICES_STATUS_W", SVCCTL_ENUM_SERVICES_STATUS_W, api_svcctl_enum_services_status },
+      { "SVCCTL_ENUM_DEPENDENT_SERVICES_W", SVCCTL_ENUM_DEPENDENT_SERVICES_W, api_svcctl_enum_dependent_services },
+      { "SVCCTL_START_SERVICE_W"       , SVCCTL_START_SERVICE_W       , api_svcctl_start_service },
+      { "SVCCTL_CONTROL_SERVICE"       , SVCCTL_CONTROL_SERVICE       , api_svcctl_control_service }
+};
+
+void svcctl_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+       *fns = api_svcctl_cmds;
+       *n_fns = sizeof(api_svcctl_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_svcctl_init(void)
+{
+  return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "svcctl", "ntsvcs", api_svcctl_cmds,
+                                   sizeof(api_svcctl_cmds) / sizeof(struct api_struct));
+}
diff --git a/source/rpc_server/srv_svcctl_nt.c b/source/rpc_server/srv_svcctl_nt.c
new file mode 100644 (file)
index 0000000..a76e68a
--- /dev/null
@@ -0,0 +1,295 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  RPC Pipe client / server routines
+ *  Copyright (C) Gerald (Jerry) Carter             2005
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*
+ * sertup the \PIPE\svcctl db API
+ */
+#define SCVCTL_DATABASE_VERSION_V1 1
+
+/********************************************************************
+********************************************************************/
+
+#if 0 /* unused static function and static variable*/
+
+static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */
+
+static BOOL init_svcctl_db( void )
+{
+       static pid_t local_pid;
+       const char *vstring = "INFO/version";
+       /* see if we've already opened the tdb */
+       
+       if (svcctl_tdb && local_pid == sys_getpid())
+               return True;
+       
+       /* so open it */        
+       if ( !(svcctl_tdb = tdb_open_log(lock_path("svcctl.tdb"), 0, TDB_DEFAULT, 
+               O_RDWR|O_CREAT, 0600))) 
+       {
+               DEBUG(0,("Failed to open svcctl database %s (%s)\n", 
+                       lock_path("svcctl.tdb"), strerror(errno) ));
+               return False;
+       }
+       local_pid = sys_getpid();
+       /***** BEGIN Check the tdb version ******/
+       
+       tdb_lock_bystring(svcctl_tdb, vstring, 0);
+       
+       if ( tdb_fetch_int32(svcctl_tdb, vstring) != SCVCTL_DATABASE_VERSION_V1 )
+               tdb_store_int32(svcctl_tdb, vstring, SCVCTL_DATABASE_VERSION_V1);
+
+       tdb_unlock_bystring(svcctl_tdb, vstring);
+       
+       /***** END Check the tdb version ******/
+
+       return True;
+}
+
+#endif
+
+/********************************************************************
+ TODO
+ (a) get and set security descriptors on services
+ (b) read and write QUERY_SERVICE_CONFIG structures
+ (c) create default secdesc objects for services and SCM
+ (d) check access control masks with se_access_check()
+ (e) implement SERVICE * for associating with open handles
+********************************************************************/
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
+{
+       /* just fake it for now */
+       
+       if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
+               return WERR_ACCESS_DENIED;
+       
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
+{
+       fstring service;
+
+       rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
+       
+       /* can only be called on service name (not displayname) */
+
+       if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) )
+               return WERR_NO_SUCH_SERVICE;
+
+       if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
+               return WERR_ACCESS_DENIED;
+
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u)
+{
+       if ( !close_policy_hnd( p, &q_u->handle ) )
+               return WERR_BADFID;
+       
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u)
+{
+       fstring service;
+       fstring displayname;
+
+       rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
+
+       DEBUG(10,("_svcctl_get_display_name: service name [%s]\n", service));
+
+       if ( !strequal( service, "NETLOGON" ) )
+               return WERR_ACCESS_DENIED;
+
+       fstrcpy( displayname, "Net Logon");
+       init_svcctl_r_get_display_name( r_u, displayname );
+
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u)
+{
+
+       r_u->svc_status.type = 0x0110;
+       r_u->svc_status.state = 0x0004;
+       r_u->svc_status.controls_accepted = 0x0005;
+
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u)
+{
+       ENUM_SERVICES_STATUS *services = NULL;
+       uint32 num_services = 0;
+       int i = 0;
+       size_t buffer_size;
+       WERROR result = WERR_OK;
+               
+       /* num_services = str_list_count( lp_enable_svcctl() ); */
+       num_services = 2;
+       
+       if ( !(services = TALLOC_ARRAY( p->mem_ctx, ENUM_SERVICES_STATUS, num_services )) )
+               return WERR_NOMEM;
+               
+       DEBUG(8,("_svcctl_enum_services_status: Enumerating %d services\n", num_services));
+                               
+       init_unistr( &services[i].servicename, "Spooler" );
+       init_unistr( &services[i].displayname, "Spooler" );
+       
+       services[i].status.type               = 0x110;
+       services[i].status.controls_accepted  = 0x0;
+       services[i].status.win32_exit_code    = 0x0;
+       services[i].status.service_exit_code  = 0x0;
+       services[i].status.check_point        = 0x0;
+       services[i].status.wait_hint          = 0x0;
+       if ( !lp_disable_spoolss() ) 
+               services[i].status.state              = SVCCTL_RUNNING;
+       else
+               services[i].status.state              = SVCCTL_STOPPED;
+
+       i++;            
+       
+       init_unistr( &services[i].servicename, "Netlogon" );
+       init_unistr( &services[i].displayname, "Net Logon" );
+       
+       services[i].status.type               = 0x20;   
+       services[i].status.controls_accepted  = 0x0;
+       services[i].status.win32_exit_code    = 0x0;
+       services[i].status.service_exit_code  = 0x0;
+       services[i].status.check_point        = 0x0;
+       services[i].status.wait_hint          = 0x0;
+       if ( lp_servicenumber("NETLOGON") != -1 ) 
+               services[i].status.state              = SVCCTL_RUNNING;
+       else
+               services[i].status.state              = SVCCTL_STOPPED;
+       
+       buffer_size = 0;
+       for (i=0; i<num_services; i++ )
+               buffer_size += svcctl_sizeof_enum_services_status( &services[i] );
+               
+       buffer_size += buffer_size % 4;
+       
+       if ( buffer_size > q_u->buffer_size ) {
+               num_services = 0;
+               result = WERR_MORE_DATA;
+       }
+               
+       /* we have to set the outgoing buffer size to the same as the 
+          incoming buffer size (even in the case of failure */
+
+       rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
+               
+       if ( W_ERROR_IS_OK(result) ) {
+               for ( i=0; i<num_services; i++ )
+                       svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 );
+       }
+               
+       r_u->needed      = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
+       r_u->returned    = num_services;
+
+       if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
+               return WERR_NOMEM;
+
+       *r_u->resume = 0x0;
+
+       return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u)
+{
+       return WERR_ACCESS_DENIED;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u)
+{
+       return WERR_ACCESS_DENIED;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u )
+{
+       
+       /* we have to set the outgoing buffer size to the same as the 
+          incoming buffer size (even in the case of failure */
+
+       rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
+                               
+       r_u->needed      = q_u->buffer_size;
+       
+       /* no dependent services...basically a stub function */
+       r_u->returned    = 0;
+
+       return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u )
+{
+       
+       /* we have to set the outgoing buffer size to the same as the 
+          incoming buffer size (even in the case of failure */
+
+       r_u->needed      = q_u->buffer_size;
+       
+       /* no dependent services...basically a stub function */
+
+       return WERR_ACCESS_DENIED;
+}
+
+
index 802e7673a40b0d04ce1700fcc63c59cdcde8c0bf..79d5d06d23adfe9c10463a2d5f5df058e0487a9d 100644 (file)
@@ -42,6 +42,7 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
+#if 0  /* these aren't used currently but are here if you need them */
 /*
  * A list of the rids of well known BUILTIN and Domain users
  * and groups.
@@ -78,7 +79,7 @@ static const rid_name domain_group_rids[] =
     { DOMAIN_GROUP_RID_GUESTS       , "Domain Guests" },
     { 0                             , NULL }
 };
-
+#endif
 
 /*******************************************************************
  gets a domain user's groups from their already-calculated NT_USER_TOKEN
index 7b9bb9b39e55c75d4044dcb917683eda8c5f42bb..fcc18cd9f526fa5b69efd45c8d0ba7ceae660b78 100644 (file)
@@ -57,6 +57,7 @@ static void cmd_reg_enum(struct client_info *info)
        POLICY_HND key_pol;
        fstring full_keyname;
        fstring key_name;
+       uint32 reg_type;
 
        /*
         * query key info
@@ -87,6 +88,11 @@ static void cmd_reg_enum(struct client_info *info)
                return;
        }
 
+       if (!reg_split_key(full_keyname, &reg_type, key_name)) {
+               fprintf(out_hnd, "Unknown registry hive '%s'\n", key_name);
+               return;
+       }
+
        /* open WINREG session. */
        res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
 
@@ -130,7 +136,7 @@ static void cmd_reg_enum(struct client_info *info)
                time_t key_mod_time;
 
                /* unknown 1a it */
-               res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+               res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
                                        &unk_1a_response) : False;
 
                if (res2 && unk_1a_response != 5)
@@ -166,11 +172,11 @@ static void cmd_reg_enum(struct client_info *info)
                 */
 
                uint32 val_type;
-               BUFFER2 value;
+               REGVAL_BUFFER value;
                fstring val_name;
 
                /* unknown 1a it */
-               res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+               res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
                                        &unk_1a_response) : False;
 
                if (res2 && unk_1a_response != 5)
@@ -314,7 +320,7 @@ static void cmd_reg_query_key(struct client_info *info)
 /****************************************************************************
 nt registry create value
 ****************************************************************************/
-static void cmd_reg_create_val(struct client_info *info)
+static void cmd_reg_set_val(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
@@ -327,7 +333,7 @@ static void cmd_reg_create_val(struct client_info *info)
        fstring val_name;
        fstring tmp;
        uint32 val_type;
-       BUFFER3 value;
+       RPC_DATA_BLOB value;
 
 #if 0
        uint32 unk_0;
@@ -337,7 +343,7 @@ static void cmd_reg_create_val(struct client_info *info)
                                val_name, *val_type) : False;
 #endif
 
-       DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli->fd));
+       DEBUG(5, ("cmd_reg_set_val: smb_cli->fd:%d\n", smb_cli->fd));
 
        if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
@@ -377,12 +383,12 @@ static void cmd_reg_create_val(struct client_info *info)
        {
                case 0x01: /* UNISTR */
                {
-                       init_buffer3_str(&value, tmp, strlen(tmp)+1);
+                       init_rpc_blob_str(&value, tmp, strlen(tmp)+1);
                        break;
                }
                case 0x03: /* BYTES */
                {
-                       init_buffer3_hex(&value, tmp);
+                       init_rpc_blob_hex(&value, tmp);
                        break;
                }
                case 0x04: /* DWORD */
@@ -396,7 +402,7 @@ static void cmd_reg_create_val(struct client_info *info)
                        {
                                tmp_val = strtol(tmp, (char**)NULL, 10);
                        }
-                       init_buffer3_uint32(&value, tmp_val);
+                       init_rpc_blob_uint32(&value, tmp_val);
                        break;
                }
                default:
@@ -428,7 +434,7 @@ static void cmd_reg_create_val(struct client_info *info)
        }
 
        /* create an entry */
-       res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
+       res4 = res3 ? do_reg_set_val(smb_cli, &parent_pol,
                                 val_name, val_type, &value) : False;
 
        /* flush the modified key */
@@ -448,12 +454,12 @@ static void cmd_reg_create_val(struct client_info *info)
 
        if (res && res3 && res4)
        {
-               DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
+               DEBUG(5,("cmd_reg_set_val: query succeeded\n"));
                fprintf(out_hnd,"OK\n");
        }
        else
        {
-               DEBUG(5,("cmd_reg_create_val: query failed\n"));
+               DEBUG(5,("cmd_reg_set_val: query failed\n"));
        }
 }
 
@@ -982,7 +988,7 @@ struct cmd_set reg_commands[] = {
        { "regqueryval",        cmd_reg_query_info,             "Registry Value Query", "<valname>" },
        { "regquerykey",        cmd_reg_query_key,              "Registry Key Query", "<keyname>" },
        { "regdeleteval",       cmd_reg_delete_val,             "Registry Value Delete", "<valname>" },
-       { "regcreateval",       cmd_reg_create_val,             "Registry Key Create", "<valname> <valtype> <value>" },
+       { "regsetval",          cmd_reg_set_val,                "Registry Key Create", "<valname> <valtype> <value>" },
        { "reggetsec",          cmd_reg_get_key_sec,            "Registry Key Security", "<keyname>" },
        { "regtestsec",         cmd_reg_test_key_sec,           "Test Registry Key Security", "<keyname>" },
 #endif
index d3f8954050201430a0e047c5080d34699faf59c1..53019dc1b2335c663c2f7534f74b637a2dda2fbe 100644 (file)
@@ -568,25 +568,39 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
 {
        POLICY_HND              connect_pol, domain_pol;
        NTSTATUS                result = NT_STATUS_UNSUCCESSFUL;
-       uint32                  user_rid, num_aliases, *alias_rids;
+       DOM_SID                *sids;
+       int                     num_sids;
+       uint32                  num_aliases, *alias_rids;
        uint32                  access_mask = MAXIMUM_ALLOWED_ACCESS;
        int                     i;
        fstring                 server;
-       DOM_SID                 tmp_sid;
-       DOM_SID2                sid;
-       DOM_SID global_sid_Builtin;
+       DOM_SID2               *sid2;
 
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
+       if (argc < 3) {
+               printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
-       if ((argc < 3) || (argc > 4)) {
-               printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
-               return NT_STATUS_OK;
+       sids = NULL;
+       num_sids = 0;
+
+       for (i=2; i<argc; i++) {
+               DOM_SID tmp_sid;
+               if (!string_to_sid(&tmp_sid, argv[i])) {
+                       printf("%s is not a legal SID\n", argv[i]);
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
        }
 
-       sscanf(argv[2], "%i", &user_rid);
-       
-       if (argc > 3)
-               sscanf(argv[3], "%x", &access_mask);
+       sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+       if (sid2 == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       for (i=0; i<num_sids; i++) {
+               sid_copy(&sid2[i].sid, &sids[i]);
+               sid2[i].num_auths = sid2[i].sid.num_auths;
+       }
 
        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
        strupper_m(server);
@@ -604,18 +618,19 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
        else if (StrCaseCmp(argv[1], "builtin")==0)
                result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
                                              access_mask,
-                                             &global_sid_Builtin, &domain_pol);
-       else
-               return NT_STATUS_OK;
+                                             &global_sid_Builtin,
+                                             &domain_pol);
+       else {
+               printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
-       sid_copy(&tmp_sid, &domain_sid);
-       sid_append_rid(&tmp_sid, user_rid);
-       init_dom_sid2(&sid, &tmp_sid);
-
-       result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol, 1, &sid, &num_aliases, &alias_rids);
+       result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
+                                           num_sids, sid2,
+                                           &num_aliases, &alias_rids);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -851,11 +866,8 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
        uint32 start_idx, size, num_als_groups, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        struct acct_info *als_groups;
-       DOM_SID global_sid_Builtin;
        BOOL got_connect_pol = False, got_domain_pol = False;
 
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
        if ((argc < 2) || (argc > 3)) {
                printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
                return NT_STATUS_OK;
@@ -933,9 +945,6 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
        uint32 alias_rid, num_members, i;
        uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
        DOM_SID *alias_sids;
-       DOM_SID global_sid_Builtin;
-       
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
 
        if ((argc < 3) || (argc > 4)) {
                printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
@@ -1261,6 +1270,15 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
+       result = cli_samr_close(cli, mem_ctx, &user_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+       result = cli_samr_close(cli, mem_ctx, &domain_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+       result = cli_samr_close(cli, mem_ctx, &connect_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
  done:
        return result;
 }
@@ -1312,6 +1330,15 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
+       result = cli_samr_close(cli, mem_ctx, &group_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+       result = cli_samr_close(cli, mem_ctx, &domain_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
+       result = cli_samr_close(cli, mem_ctx, &connect_pol);
+       if (!NT_STATUS_IS_OK(result)) goto done;
+
  done:
        return result;
 }
@@ -1328,9 +1355,6 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
        uint32 num_rids, num_names, *name_types, *rids;
        const char **names;
        int i;
-       DOM_SID global_sid_Builtin;
-
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
 
        if (argc < 3) {
                printf("Usage: %s  domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
index e42ec30ac13103d742771b1294e577cea0f9bba9..b0b92949c2a91254dd84fbadbc967fcff30fe7ba 100644 (file)
@@ -24,6 +24,9 @@
 #include "includes.h"
 #include "rpcclient.h"
 
+#if 0  /* don't uncomment this unless you remove the getopt() calls */
+       /* use net rpc shutdown instead */
+
 /****************************************************************************
 nt shutdown init
 ****************************************************************************/
@@ -96,6 +99,7 @@ static NTSTATUS cmd_shutdown_abort(struct cli_state *cli,
 
        return result;
 }
+#endif
 
 
 /* List of commands exported by this module */
@@ -103,10 +107,12 @@ struct cmd_set shutdown_commands[] = {
 
        { "SHUTDOWN"  },
 
+#if 0
        { "shutdowninit", RPC_RTYPE_NTSTATUS, cmd_shutdown_init, NULL, PI_SHUTDOWN, "Remote Shutdown (over shutdown pipe)",
                                "syntax: shutdown [-m message] [-t timeout] [-r] [-h] [-f] (-r == reboot, -h == halt, -f == force)" },
                                
        { "shutdownabort", RPC_RTYPE_NTSTATUS, cmd_shutdown_abort, NULL, PI_SHUTDOWN, "Abort Shutdown (over shutdown pipe)",
                                "syntax: shutdownabort" },
+#endif
        { NULL }
 };
index 49f22b3654647bf8b2ce0f7395959a3910002459..ec9d30488221562e029bf84dd6f812e50079c819 100644 (file)
@@ -1283,7 +1283,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
  wrapper for strtok to get the next parameter from a delimited list.
  Needed to handle the empty parameter string denoted by "NULL"
  *************************************************************************/
-static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
+static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
 {
        char    *ptr;
 
@@ -1310,11 +1310,8 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des
             <Config File Name>:<Help File Name>:<Language Monitor Name>:\
             <Default Data Type>:<Comma Separated list of Files> 
  *******************************************************************************/
-static BOOL init_drv_info_3_members (
-       TALLOC_CTX *mem_ctx, 
-       DRIVER_INFO_3 *info, 
-       const char *args
-)
+static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info, 
+                                      char *args )
 {
        char    *str, *str2;
        uint32  len, i;
@@ -1370,6 +1367,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
        DRIVER_INFO_3           info3;
        const char              *arch;
        fstring                 driver_name;
+       char                    *driver_args;
 
        /* parse the command arguements */
        if (argc != 3 && argc != 4)
@@ -1393,7 +1391,8 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
        else
                set_drv_info_3_env(&info3, arch);
 
-       if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
+       driver_args = talloc_strdup( mem_ctx, argv[2] );
+       if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
        {
                printf ("Error Invalid parameter list - %s.\n", argv[2]);
                return WERR_INVALID_PARAM;
@@ -1813,6 +1812,38 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        return werror;
 }
 
+static const char *get_form_flag(int form_flag)
+{
+       switch (form_flag) {
+       case FORM_USER:
+               return "FORM_USER";
+       case FORM_BUILTIN:
+               return "FORM_BUILTIN";
+       case FORM_PRINTER:
+               return "FORM_PRINTER";
+       default:
+               return "unknown";
+       }
+}
+
+static void display_form(FORM_1 *form)
+{
+       fstring form_name = "";
+
+       if (form->name.buffer)
+               rpcstr_pull(form_name, form->name.buffer,
+                           sizeof(form_name), -1, STR_TERMINATE);
+
+       printf("%s\n" \
+               "\tflag: %s (%d)\n" \
+               "\twidth: %d, length: %d\n" \
+               "\tleft: %d, right: %d, top: %d, bottom: %d\n\n", 
+               form_name, get_form_flag(form->flag), form->flag,
+               form->width, form->length, 
+               form->left, form->right, 
+               form->top, form->bottom);
+}
+
 /* Get a form */
 
 static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -1847,7 +1878,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        got_handle = True;
 
-       /* Set the form */
+       /* Get the form */
 
        werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
                                     &handle, argv[2], 1, &form);
@@ -1859,12 +1890,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        if (!W_ERROR_IS_OK(werror))
                goto done;
 
-       printf("width: %d\n", form.width);
-       printf("length: %d\n", form.length);
-       printf("left: %d\n", form.left);
-       printf("top: %d\n", form.top);
-       printf("right: %d\n", form.right);
-       printf("bottom: %d\n", form.bottom);
+       display_form(&form);
 
  done:
        if (got_handle)
@@ -1925,20 +1951,6 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
 
 /* Enumerate forms */
 
-static const char *get_form_flag(int form_flag)
-{
-       switch (form_flag) {
-       case FORM_USER:
-               return "FORM_USER";
-       case FORM_BUILTIN:
-               return "FORM_BUILTIN";
-       case FORM_PRINTER:
-               return "FORM_PRINTER";
-       default:
-               return "unknown";
-       }
-}
-
 static WERROR cmd_spoolss_enum_forms(struct cli_state *cli, 
                                       TALLOC_CTX *mem_ctx, int argc, 
                                       const char **argv)
@@ -1988,20 +2000,9 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
        /* Display output */
 
        for (i = 0; i < num_forms; i++) {
-               fstring form_name;
-
-               if (forms[i].name.buffer)
-                       rpcstr_pull(form_name, forms[i].name.buffer,
-                                   sizeof(form_name), -1, STR_TERMINATE);
-
-               printf("%s\n" \
-                       "\tflag: %s (%d)\n" \
-                       "\twidth: %d, length: %d\n" \
-                       "\tleft: %d, right: %d, top: %d, bottom: %d\n\n", 
-                       form_name, get_form_flag(forms[i].flag), forms[i].flag,
-                       forms[i].width, forms[i].length, 
-                       forms[i].left, forms[i].right, 
-                       forms[i].top, forms[i].bottom);
+
+               display_form(&forms[i]);
+
        }
 
  done:
index acb65b7f7ceb8e1afd98c236f8c4490c8b89fdd3..c02a279db9ebd8fe7f909965fcce3bf48fec2699 100644 (file)
@@ -24,7 +24,6 @@
 #include "rpcclient.h"
 
 DOM_SID domain_sid;
-static int pipe_idx;
 
 
 /* List to hold groups of commands.
@@ -559,7 +558,6 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 
      /* Run command */
 
-       pipe_idx = cmd_entry->pipe_idx;
      if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
           ntresult = cmd_entry->ntfn(cli, mem_ctx, argc, (const char **) argv);
           if (!NT_STATUS_IS_OK(ntresult)) {
index f28e11cde745a9b04a4a723b11580ed7b7aca809..41689f413b91302e1b8f986d87fd96b9c6d3a40f 100644 (file)
@@ -190,106 +190,3 @@ NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags)
 
        return ret;
 }
-
-
-/***************************************************************************
- Check first, call set_mapping if it doesn't already exist.
-***************************************************************************/
-
-static NTSTATUS wellknown_id_init(DOM_SID *sid, unid_t id, int flags)
-{
-       unid_t storedid;
-       int qflags = flags | ID_QUERY_ONLY;
-
-       if (!NT_STATUS_IS_OK(idmap_get_id_from_sid(&storedid, &qflags, sid))) {
-               return idmap_set_mapping(sid, id, flags);
-       } else {
-               if (flags == ID_USERID && id.uid != storedid.uid) {
-                       DEBUG(0,("wellknown_id_init: WARNING ! Stored uid %u for SID %s is not the same as the requested uid %u\n",
-                               (unsigned int)storedid.uid, sid_string_static(sid), (unsigned int)id.uid ));
-                       DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
-                       return idmap_set_mapping(sid, id, flags);
-               } else if (flags == ID_GROUPID && id.gid != storedid.gid) {
-                       DEBUG(0,("wellknown_id_init: WARNING ! Stored gid %u for SID %s is not the same as the requested gid %u\n",
-                               (unsigned int)storedid.gid, sid_string_static(sid), (unsigned int)id.gid ));
-                       DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
-                       return idmap_set_mapping(sid, id, flags);
-               }
-       }
-       return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Initialize idmap withWellknown SIDs like Guest, that are necessary
- to make samba run properly.
-***************************************************************************/
-
-BOOL idmap_init_wellknown_sids(void)
-{
-       const char *guest_account = lp_guestaccount();
-       struct passwd *pass;
-       GROUP_MAP *map=NULL;
-       int num_entries=0;
-       DOM_SID sid;
-       unid_t id;
-       fstring sid_string;
-
-       if (!(guest_account && *guest_account)) {
-               DEBUG(1, ("NULL guest account!?!?\n"));
-               return False;
-       }
-
-       pass = getpwnam_alloc(guest_account);
-       if (!pass) {
-               return False;
-       }
-
-       /* Fill in the SID for the guest account. */
-       id.uid = pass->pw_uid;
-       sid_copy(&sid, get_global_sam_sid());
-       sid_append_rid(&sid, DOMAIN_USER_RID_GUEST);
-
-       if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
-               DEBUG(0, ("Failed to setup UID mapping for GUEST (%s) to (%u)\n", 
-                         sid_to_string(sid_string, &sid), (unsigned int)id.uid));
-               passwd_free(&pass);
-               return False;
-       }
-
-       /* check if DOMAIN_GROUP_RID_GUESTS SID is set, if not store the
-        * guest account gid as mapping */
-       id.gid = pass->pw_gid;
-       sid_copy(&sid, get_global_sam_sid());
-       sid_append_rid(&sid, DOMAIN_GROUP_RID_GUESTS);
-       if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_GROUPID))) {
-               DEBUG(0, ("Failed to setup GID mapping for Group DOMAIN GUESTS (%s) to (%u)\n", 
-                         sid_to_string(sid_string, &sid), (unsigned int)id.gid));
-               passwd_free(&pass);
-               return False;
-       }
-
-       passwd_free(&pass);
-       /* now fill in group mappings */
-       if(pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) {
-               int i;
-
-               for (i = 0; i < num_entries; i++) {
-                       id.gid = map[i].gid;
-                       wellknown_id_init(&map[i].sid, id, ID_GROUPID);
-               }
-               SAFE_FREE(map);
-       }
-
-       /* Fill in the SID for the administrator account. */
-       id.uid = 0;
-       sid_copy(&sid, get_global_sam_sid());
-       sid_append_rid(&sid, DOMAIN_USER_RID_ADMIN);
-
-       if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
-               DEBUG(0, ("Failed to setup UID mapping for ADMINISTRATOR (%s) to (%u)\n", 
-                         sid_to_string(sid_string, &sid), (unsigned int)id.uid));
-               return False;
-       }
-
-       return True;
-}
index c7a8f45095144cc3b04e6a0f4fde543b45464ea4..d30429d50a0800bc9893fa571a35e1108ba51a2e 100755 (executable)
@@ -15,7 +15,7 @@ fi
 
 
 for lang in $langs; do
-    if [ "X$lang" = Xen ]; then
+    if [ "X$lang" = XC ]; then
        echo Installing default man pages in $MANDIR/
        lang=.
     else
index 492ecaade2a25520503e2976669a1f70de64e923..6f49108aba0f03c8af6e120d7f00216620eb07c6 100755 (executable)
@@ -46,6 +46,8 @@ fi
 
 
 if test x"${SAMBA_VERSION_IS_SVN_SNAPSHOT}" = x"yes";then
+    _SAVE_LANG=${LANG}
+    LANG=""
     HAVESVN=no
     svn info ${SOURCE_DIR} >/dev/null 2>&1 && HAVESVN=yes
     TMP_REVISION=`(svn info ${SOURCE_DIR} 2>/dev/null || svk info ${SOURCE_DIR} 2>/dev/null) |grep 'Last Changed Rev.*:' |sed -e 's/Last Changed Rev.*: \([0-9]*\).*/\1/'`
@@ -63,6 +65,7 @@ if test x"${SAMBA_VERSION_IS_SVN_SNAPSHOT}" = x"yes";then
     else
            SAMBA_VERSION_STRING="${SAMBA_VERSION_STRING}-SVN-build-UNKNOWN"
     fi
+    LANG=${_SAVE_LANG}
 fi
 
 if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then
index 540acfc22509629214626cca3d68f6fa60e20aba..d0e0f6e143a7ac083d50359c26c97e125a59db79 100644 (file)
@@ -747,8 +747,8 @@ static NTSTATUS check_oem_password(const char *user,
        static uchar null_pw[16];
        static uchar null_ntpw[16];
        SAM_ACCOUNT *sampass = NULL;
-       char *password_encrypted;
-       const char *encryption_key;
+       uint8 *password_encrypted;
+       const uint8 *encryption_key;
        const uint8 *lanman_pw, *nt_pw;
        uint16 acct_ctrl;
        uint32 new_pw_len;
@@ -943,7 +943,8 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext)
        const uint8 *nt_pw;
        const uint8 *pwhistory;
        BOOL found = False;
-       int i, pwHisLen, curr_pwHisLen;
+       int i;
+       uint32 pwHisLen, curr_pwHisLen;
 
        account_policy_get(AP_PASSWORD_HISTORY, &pwHisLen);
        if (pwHisLen == 0) {
index 309f4adf478a10fa1fa747273818d556b29cad83..0f32dddd2d765a79c9b06db96a7892fc8cbc5be1 100644 (file)
@@ -24,6 +24,8 @@
    This module implements directory related functions for Samba.
 */
 
+extern struct current_user current_user;
+
 /* Make directory handle internals available. */
 
 #define NAME_CACHE_SIZE 100
@@ -697,7 +699,7 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype)
 static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
 {
        mangle_map(filename,True,False,SNUM(conn));
-       return mask_match(filename,mask,False);
+       return mask_match_search(filename,mask,False);
 }
 
 /****************************************************************************
@@ -712,16 +714,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
        SMB_STRUCT_STAT sbuf;
        pstring path;
        pstring pathreal;
-       BOOL isrootdir;
        pstring filename;
        BOOL needslash;
 
        *path = *pathreal = *filename = 0;
 
-       isrootdir = (strequal(conn->dirpath,"./") ||
-                       strequal(conn->dirpath,".") ||
-                       strequal(conn->dirpath,"/"));
-  
        needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
 
        if (!conn->dirptr)
@@ -744,10 +741,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
                        see masktest for a demo
                */
                if ((strcmp(mask,"*.*") == 0) ||
-                   mask_match(filename,mask,False) ||
+                   mask_match_search(filename,mask,False) ||
                    mangle_mask_match(conn,filename,mask)) {
-                       if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
-                               continue;
 
                        if (!mangle_is_8_3(filename, False))
                                mangle_map(filename,True,False,SNUM(conn));
@@ -792,7 +787,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
 
 static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
 {
-       extern struct current_user current_user;
        SEC_DESC *psd = NULL;
        size_t sd_size;
        files_struct *fsp;
@@ -845,7 +839,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
 
 static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
 {
-       extern struct current_user current_user;
        SEC_DESC *psd = NULL;
        size_t sd_size;
        files_struct *fsp;
index ff00b5dc6b10b2d00f96aeb5eb861a187f5ab590..3a0e81e5feffc51c712b607e44ff11d20ee03c34 100644 (file)
@@ -431,7 +431,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
  than POSIX.
 *******************************************************************/
 
-int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
+int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times)
 {
        int ret = -1;
 
@@ -467,7 +467,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
  Change a filetime - possibly allowing DOS semantics.
 *******************************************************************/
 
-BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
+BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime)
 {
        struct utimbuf times;
 
index d611e0ef873af4812b3b52439612d8d975720761..090a2f6d813c93621d6822db91d61c5cfc81ebc9 100644 (file)
 
 #include "includes.h"
 
-/* these can be set by some functions to override the error codes */
-int unix_ERR_class=SMB_SUCCESS;
-int unix_ERR_code=0;
-NTSTATUS unix_ERR_ntstatus = NT_STATUS_OK;
-
 /* From lib/error.c */
 extern struct unix_error_map unix_dos_nt_errmap[];
 
+extern uint32 global_client_caps;
+/* these can be set by some functions to override the error codes */
+static int override_ERR_class;
+static int override_ERR_code;
+static NTSTATUS override_ERR_ntstatus;
+
 /****************************************************************************
- Ensure we don't have any errors cached.
+ Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors.
+ Setting status only and eclass and ecode to -1 forces NT errors.
 ****************************************************************************/
  
-void clear_cached_errors(void)
+void set_saved_error_triple(int eclass, int ecode, NTSTATUS status)
+{
+       override_ERR_class = eclass;
+       override_ERR_code = ecode;
+       override_ERR_ntstatus = status;
+}
+
+/****************************************************************************
+ Return the current settings of the error triple. Return True if any are set.
+****************************************************************************/
+
+BOOL get_saved_error_triple(int *peclass, int *pecode, NTSTATUS *pstatus)
 {
-       unix_ERR_class = SMB_SUCCESS;
-       unix_ERR_code = 0;
-       unix_ERR_ntstatus = NT_STATUS_OK;
+       if (peclass) {
+               *peclass = override_ERR_class;
+       }
+       if (pecode) {
+               *pecode = override_ERR_code;
+       }
+       if (pstatus) {
+               *pstatus = override_ERR_ntstatus;
+       }
+
+       return (override_ERR_class || !NT_STATUS_IS_OK(override_ERR_ntstatus));
 }
 
 /****************************************************************************
@@ -46,36 +67,29 @@ void clear_cached_errors(void)
 int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file)
 {
        write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
        int32 eclass = wbmpx->wr_errclass;
        int32 err = wbmpx->wr_error;
+       NTSTATUS ntstatus = wbmpx->wr_status;
  
        /* We can now delete the auxiliary struct */
-       free((char *)wbmpx);
-       fsp->wbmpx_ptr = NULL;
-       return error_packet(outbuf,NT_STATUS_OK,eclass,err,False,line,file);
+       SAFE_FREE(fsp->wbmpx_ptr);
+       return error_packet(outbuf,eclass,err,ntstatus,line,file);
 }
 
 /****************************************************************************
  Create an error packet from errno.
 ****************************************************************************/
 
-int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
-                     int line, const char *file)
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_status, int line, const char *file)
 {
        int eclass=def_class;
        int ecode=def_code;
-       NTSTATUS ntstatus = NT_STATUS_OK;
+       NTSTATUS ntstatus = def_status;
        int i=0;
 
-       if (unix_ERR_class != SMB_SUCCESS) {
-               eclass = unix_ERR_class;
-               ecode = unix_ERR_code;
-               ntstatus = unix_ERR_ntstatus;
-               unix_ERR_class = SMB_SUCCESS;
-               unix_ERR_code = 0;
-               unix_ERR_ntstatus = NT_STATUS_OK;
-       } else {
+       if (errno != 0) {
+               DEBUG(3,("unix_error_packet: error string = %s\n",strerror(errno)));
+  
                while (unix_dos_nt_errmap[i].dos_class != 0) {
                        if (unix_dos_nt_errmap[i].unix_error == errno) {
                                eclass = unix_dos_nt_errmap[i].dos_class;
@@ -87,39 +101,43 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
                }
        }
 
-       return error_packet(outbuf,ntstatus,eclass,ecode,False,line,file);
+       return error_packet(outbuf,eclass,ecode,ntstatus,line,file);
 }
 
 
 /****************************************************************************
  Create an error packet. Normally called using the ERROR() macro.
+ Setting eclass and ecode only and status to NT_STATUS_OK forces DOS errors.
+ Setting status only and eclass and ecode to zero forces NT errors.
+ If the override errors are set they take precedence over any passed in values.
 ****************************************************************************/
 
-int error_packet(char *outbuf,NTSTATUS ntstatus,
-                uint8 eclass,uint32 ecode,BOOL force_dos, int line, const char *file)
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
 {
        int outsize = set_message(outbuf,0,0,True);
-       extern uint32 global_client_caps;
+       BOOL force_nt_status = False;
+       BOOL force_dos_status = False;
+
+       if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) {
+               eclass = override_ERR_class;
+               ecode = override_ERR_code;
+               ntstatus = override_ERR_ntstatus;
+               override_ERR_class = SMB_SUCCESS;
+               override_ERR_code = 0;
+               override_ERR_ntstatus = NT_STATUS_OK;
+       }
 
-       if (errno != 0)
-               DEBUG(3,("error string = %s\n",strerror(errno)));
-  
-#if defined(DEVELOPER)
-       if (unix_ERR_class != SMB_SUCCESS || unix_ERR_code != 0 || !NT_STATUS_IS_OK(unix_ERR_ntstatus))
-               smb_panic("logic error in error processing");
-#endif
-
-       /*
-        * We can explicitly force 32 bit error codes even when the
-        * parameter "nt status" is set to no by pre-setting the
-        * FLAGS2_32_BIT_ERROR_CODES bit in the smb_flg2 outbuf.
-        * This is to allow work arounds for client bugs that are needed
-        * when talking with clients that normally expect nt status codes. JRA.
-        */
-
-       if ((lp_nt_status_support() || (SVAL(outbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) && (global_client_caps & CAP_STATUS32) && (!force_dos)) {
-               if (NT_STATUS_V(ntstatus) == 0 && eclass)
+       if (eclass == (uint8)-1) {
+               force_nt_status = True;
+       } else if (NT_STATUS_IS_INVALID(ntstatus)) {
+               force_dos_status = True;
+       }
+
+       if (force_nt_status || (!force_dos_status && lp_nt_status_support() && (global_client_caps & CAP_STATUS32))) {
+               /* We're returning an NT error. */
+               if (NT_STATUS_V(ntstatus) == 0 && eclass) {
                        ntstatus = dos_to_ntstatus(eclass, ecode);
+               }
                SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus));
                SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES);
                DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n",
@@ -127,22 +145,23 @@ int error_packet(char *outbuf,NTSTATUS ntstatus,
                         (int)CVAL(outbuf,smb_com),
                         smb_fn_name(CVAL(outbuf,smb_com)),
                         nt_errstr(ntstatus)));
-               return outsize;
-       } 
-
-       if (eclass == 0 && NT_STATUS_V(ntstatus))
-               ntstatus_to_dos(ntstatus, &eclass, &ecode);
-
-       SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES);
-       SSVAL(outbuf,smb_rcls,eclass);
-       SSVAL(outbuf,smb_err,ecode);  
-
-       DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
-                 file, line,
-                 (int)CVAL(outbuf,smb_com),
-                 smb_fn_name(CVAL(outbuf,smb_com)),
-                 eclass,
-                 ecode));
+       } else {
+               /* We're returning a DOS error only. */
+               if (eclass == 0 && NT_STATUS_V(ntstatus)) {
+                       ntstatus_to_dos(ntstatus, &eclass, &ecode);
+               }
+
+               SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES);
+               SSVAL(outbuf,smb_rcls,eclass);
+               SSVAL(outbuf,smb_err,ecode);  
+
+               DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
+                         file, line,
+                         (int)CVAL(outbuf,smb_com),
+                         smb_fn_name(CVAL(outbuf,smb_com)),
+                         eclass,
+                         ecode));
+       }
 
        return outsize;
 }
index 53aac1e0364773808863b7d2acf379ccc03ae2b2..ee510eb003f2add7a970cece65e0836a20868f9a 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+
 /****************************************************************************
  Open a file with a share mode.
 ****************************************************************************/
@@ -29,7 +31,6 @@ files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connect
                                int share_mode,int ofun, uint32 new_dos_attr, int oplock_request, 
                                int *Access,int *action)
 {
-       extern struct current_user current_user;
        int flags=0;
        files_struct *fsp = NULL;
 
index 8c484dd232af19279198e55be77703ccdbddbe36..9ca2c0efae9ed6aaa1cce6c4c76ef5eeab0b346b 100644 (file)
@@ -397,7 +397,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
  a valid one for the user to access.
 ****************************************************************************/
 
-BOOL check_name(pstring name,connection_struct *conn)
+BOOL check_name(const pstring name,connection_struct *conn)
 {
        BOOL ret = True;
 
index 143c1196937585687f8d2dbc0ccc4cb48edf7ee3..e893e9fefc1cc7df78a10357d5d85b8c9c063890 100644 (file)
@@ -95,15 +95,13 @@ files_struct *file_new(connection_struct *conn)
                }
 
                DEBUG(0,("ERROR! Out of file structures\n"));
-               unix_ERR_class = ERRSRV;
-               unix_ERR_code = ERRnofids;
+               set_saved_error_triple(ERRSRV, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES);
                return NULL;
        }
 
        fsp = SMB_MALLOC_P(files_struct);
        if (!fsp) {
-               unix_ERR_class = ERRSRV;
-               unix_ERR_code = ERRnofids;
+               set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
                return NULL;
        }
 
index d8c5201ce679cb3d838796fe525cf405cf7b81be..127480f0b3deef73943514b104d812d859dc224d 100644 (file)
@@ -27,6 +27,9 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+extern userdom_struct current_user_info;
+
 #ifdef CHECK_TYPES
 #undef CHECK_TYPES
 #endif
@@ -1652,9 +1655,10 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
-       BOOL ret;
 
-       GROUP_MAP *group_list;
+       struct pdb_search *search;
+       struct samr_displayentry *entries;
+
        int num_entries;
  
        if (strcmp(str1,"WrLeh") != 0)
@@ -1672,30 +1676,39 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
 
        /* get list of domain groups SID_DOMAIN_GRP=2 */
        become_root();
-       ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False);
+       search = pdb_search_groups();
        unbecome_root();
-       
-       if( !ret ) {
-               DEBUG(3,("api_RNetGroupEnum:failed to get group list"));        
+
+       if (search == NULL) {
+               DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
                return False;
        }
 
        resume_context = SVAL(p,0); 
        cli_buf_size=SVAL(p+2,0);
-       DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
+       DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
+                 "%d\n", resume_context, cli_buf_size));
+
+       become_root();
+       num_entries = pdb_search_entries(search, resume_context, 0xffffffff,
+                                        &entries);
+       unbecome_root();
 
        *rdata_len = cli_buf_size;
        *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
 
        p = *rdata;
 
-       for(i=resume_context; i<num_entries; i++) {     
-               char* name=group_list[i].nt_name;
+       for(i=0; i<num_entries; i++) {
+               fstring name;
+               fstrcpy(name, entries[i].account_name);
                if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
                        /* truncate the name at 21 chars. */
                        memcpy(p, name, 21); 
                        DEBUG(10,("adding entry %d group %s\n", i, p));
-                       p += 21; 
+                       p += 21;
+                       p += 5; /* Both NT4 and W2k3SP1 do padding here.
+                                  No idea why... */
                } else {
                        /* set overflow error */
                        DEBUG(3,("overflow on entry %d group %s\n", i, name));
@@ -1704,6 +1717,8 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
                }
        }
 
+       pdb_search_destroy(search);
+
        *rdata_len = PTR_DIFF(p,*rdata);
 
        *rparam_len = 8;
@@ -1711,8 +1726,8 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
 
        SSVAL(*rparam, 0, errflags);
        SSVAL(*rparam, 2, 0);           /* converter word */
-       SSVAL(*rparam, 4, i-resume_context);    /* is this right?? */
-       SSVAL(*rparam, 6, num_entries); /* is this right?? */
+       SSVAL(*rparam, 4, i);   /* is this right?? */
+       SSVAL(*rparam, 6, resume_context+num_entries);  /* is this right?? */
 
        return(True);
 }
@@ -1831,11 +1846,12 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
                                 char **rdata,char **rparam,
                                 int *rdata_len,int *rparam_len)
 {
-       SAM_ACCOUNT  *pwd=NULL;
        int count_sent=0;
-       int count_total=0;
+       int num_users=0;
        int errflags=0;
-       int resume_context, cli_buf_size;
+       int i, resume_context, cli_buf_size;
+       struct pdb_search *search;
+       struct samr_displayentry *users;
 
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
@@ -1867,49 +1883,47 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
 
        p = *rdata;
 
-       /* to get user list enumerations for NetUserEnum in B21 format */
-       pdb_init_sam(&pwd);
-       
-       /* Open the passgrp file - not for update. */
        become_root();
-       if(!pdb_setsampwent(False, 0)) {
+       search = pdb_search_users(ACB_NORMAL);
+       unbecome_root();
+       if (search == NULL) {
                DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
-               unbecome_root();
                return False;
        }
-       errflags=NERR_Success;
 
-       while ( pdb_getsampwent(pwd) ) {
-               const char *name=pdb_get_username(pwd); 
-               if ((name) && (*(name+strlen(name)-1)!='$')) { 
-                       count_total++;
-                       if(count_total>=resume_context) {
-                               if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)  ) {
-                                       pstrcpy(p,name); 
-                                       DEBUG(10,("api_RNetUserEnum:adding entry %d username %s\n",count_sent,p));
-                                       p += 21; 
-                                       count_sent++; 
-                               } else {
-                                       /* set overflow error */
-                                       DEBUG(10,("api_RNetUserEnum:overflow on entry %d username %s\n",count_sent,name));
-                                       errflags=234;
-                                       break;
-                               }
-                       }
-               }       
-       } ;
-
-       pdb_endsampwent();
+       become_root();
+       num_users = pdb_search_entries(search, resume_context, 0xffffffff,
+                                      &users);
        unbecome_root();
 
-       pdb_free_sam(&pwd);
+       errflags=NERR_Success;
+
+       for (i=0; i<num_users; i++) {
+               const char *name = users[i].account_name;
+               
+               if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
+                       pstrcpy(p,name); 
+                       DEBUG(10,("api_RNetUserEnum:adding entry %d username "
+                                 "%s\n",count_sent,p));
+                       p += 21; 
+                       count_sent++; 
+               } else {
+                       /* set overflow error */
+                       DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
+                                 "username %s\n",count_sent,name));
+                       errflags=234;
+                       break;
+               }
+       }
+
+       pdb_search_destroy(search);
 
        *rdata_len = PTR_DIFF(p,*rdata);
 
        SSVAL(*rparam,0,errflags);
        SSVAL(*rparam,2,0);           /* converter word */
        SSVAL(*rparam,4,count_sent);  /* is this right?? */
-       SSVAL(*rparam,6,count_total); /* is this right?? */
+       SSVAL(*rparam,6,num_users); /* is this right?? */
 
        return True;
 }
@@ -2116,7 +2130,6 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
        int snum;
        fstring sharename;
        int errcode;
-       extern struct current_user current_user;
        WERROR werr = WERR_OK;
 
        if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
@@ -2183,7 +2196,6 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
        int errcode = NERR_notsupported;
        int snum;
        WERROR werr = WERR_OK;
-       extern struct current_user current_user;
 
        /* check it's a supported varient */
        if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
@@ -2435,7 +2447,6 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
   char *str2 = skip_string(str1,1);
   char *p = skip_string(str2,1);
   char *p2;
-  extern userdom_struct current_user_info;
   int level = SVAL(p,0);
 
   DEBUG(4,("NetWkstaGetInfo level %d\n",level));
index 184dde1635437956a02727fa9e2549b4c277fcc8..1891e59347b72973639451f04f3d9bebea1650c8 100644 (file)
@@ -64,7 +64,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
        DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename));
 
        /* rest is reqpath */
-       check_path_syntax(pdp->reqpath, p+1,True);
+       check_path_syntax(pdp->reqpath, p+1);
 
        DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath));
        return True;
@@ -75,7 +75,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
   into the dfs_path structure 
  **********************************************************************/
 
-static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
+static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp, BOOL allow_wcards)
 {
        pstring pathname_local;
        char* p,*temp;
@@ -110,7 +110,11 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
        DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename));
 
        /* rest is reqpath */
-       check_path_syntax(pdp->reqpath, p+1,True);
+       if (allow_wcards) {
+               check_path_syntax_wcard(pdp->reqpath, p+1);
+       } else {
+               check_path_syntax(pdp->reqpath, p+1);
+       }
 
        DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath));
        return True;
@@ -278,8 +282,12 @@ should try the remaining path on the redirected server.
 *****************************************************************/
 
 static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp, 
+<<<<<<< .mine
                      connection_struct* conn,
-                     BOOL findfirst_flag,
+                     BOOL findfirst_flag, 
+=======
+                     connection_struct* conn, BOOL search_flag, 
+>>>>>>> .r6366
                      struct referral** reflistpp, int* refcntp,
                      BOOL* self_referralp, int* consumedcntp)
 {
@@ -311,18 +319,17 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
 
        /* check if need to redirect */
        if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
-               if (findfirst_flag) {
+               if ( search_flag ) {
                        DEBUG(6,("resolve_dfs_path (FindFirst) No redirection "
                                 "for dfs link %s.\n", dfspath));
                        return False;
-               } else {                
-                       DEBUG(6,("resolve_dfs_path: %s resolves to a valid Dfs link.\n",
-                                dfspath));
-                       if (consumedcntp) 
-                               *consumedcntp = strlen(dfspath);
-                       return True;
                }
-       } 
+               
+               DEBUG(6,("resolve_dfs_path: %s resolves to a valid Dfs link.\n", dfspath));
+               if (consumedcntp) 
+                       *consumedcntp = strlen(dfspath);
+               return True;
+       }
 
        /* redirect if any component in the path is a link */
        pstrcpy(reqpath, dp->reqpath);
@@ -331,6 +338,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
                *p = '\0';
                pstrcpy(localpath, reqpath);
                if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
+               
                        DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath));
 
                        /* To find the path consumed, we truncate the original
@@ -338,6 +346,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
                           component. The length of the resulting string is
                           the path consumed 
                        */
+                       
                        if (consumedcntp) {
                                char *q;
                                pstring buf;
@@ -364,17 +373,20 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
 /*****************************************************************
   Decides if a dfs pathname should be redirected or not.
   If not, the pathname is converted to a tcon-relative local unix path
+
+  search_wcard_flag: this flag performs 2 functions bother related
+  to searches.  See resolve_dfs_path() and parse_processed_dfs_path()
+  for details.
 *****************************************************************/
 
-BOOL dfs_redirect(pstring pathname, connection_struct* conn,
-                 BOOL findfirst_flag)
+BOOL dfs_redirect( pstring pathname, connection_struct* conn, BOOL search_wcard_flag )
 {
        struct dfs_path dp;
        
        if (!conn || !pathname)
                return False;
 
-       parse_processed_dfs_path(pathname, &dp);
+       parse_processed_dfs_path(pathname, &dp, search_wcard_flag);
 
        /* if dfs pathname for a non-dfs share, convert to tcon-relative
           path and return false */
@@ -386,7 +398,11 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn,
        if (!strequal(dp.servicename, lp_servicename(SNUM(conn)) )) 
                return False;
 
-       if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag,
+<<<<<<< .mine
+       if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag, 
+=======
+       if (resolve_dfs_path(pathname, &dp, conn, search_wcard_flag,
+>>>>>>> .r6366
                             NULL, NULL, NULL, NULL)) {
                DEBUG(3,("dfs_redirect: Redirecting %s\n", pathname));
                return True;
@@ -802,6 +818,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
 /**********************************************************************
  Creates a junction structure from a Dfs pathname
  **********************************************************************/
+
 BOOL create_junction(char* pathname, struct junction_map* jucn)
 {
         struct dfs_path dp;
index 9aaa818c62a2449e7bb1ed30623a55d62a4934e9..054afac683df8dfc083828d55e9884b286a40f23 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "includes.h"
 
+extern fstring remote_proto;
 extern enum protocol_types Protocol;
 extern int max_recv;
 BOOL global_encrypted_passwords_negotiated = False;
@@ -419,6 +420,7 @@ static const struct {
        {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
        {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
        {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
+       {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
        {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
        {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
        {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
@@ -548,7 +550,6 @@ int reply_negprot(connection_struct *conn,
   
        SSVAL(outbuf,smb_vwv0,choice);
        if(choice != -1) {
-               extern fstring remote_proto;
                fstrcpy(remote_proto,supported_protocols[protocol].short_name);
                reload_services(True);          
                outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
index 8fcc18a09f9645264099d1b03f862971fdfaee46..c368fd79a129954ee27c8225a25fd369be42bd2c 100644 (file)
@@ -101,8 +101,9 @@ static BOOL kernel_check_notify(connection_struct *conn, uint16 vuid, char *path
                        close((int)fd_pending_array[i]);
                        fd_pending_array[i] = (SIG_ATOMIC_T)-1;
                        if (signals_received - i - 1) {
-                               memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
-                                               sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
+                               memmove(CONST_DISCARD(void *, &fd_pending_array[i]),
+                                        CONST_DISCARD(void *, &fd_pending_array[i+1]),
+                                        sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
                        }
                        data->directory_handle = -1;
                        signals_received--;
@@ -129,8 +130,9 @@ static void kernel_remove_notify(void *datap)
                        if (fd == (int)fd_pending_array[i]) {
                                fd_pending_array[i] = (SIG_ATOMIC_T)-1;
                                if (signals_received - i - 1) {
-                                       memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
-                                                       sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
+                                       memmove(CONST_DISCARD(void *, &fd_pending_array[i]),
+                                                CONST_DISCARD(void *, &fd_pending_array[i+1]),
+                                                sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
                                }
                                data->directory_handle = -1;
                                signals_received--;
index fbb73640901d75be2decfa48244e77bc32295d19..d747e84a3a5ee1162cbe6ad800f5a8dbe621ffae 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 
+extern int max_send;
 extern enum protocol_types Protocol;
 extern int smb_read_error;
 extern int global_oplock_break;
@@ -40,6 +41,8 @@ static const char *known_nt_pipes[] = {
        "\\spoolss",
        "\\netdfs",
        "\\rpcecho",
+        "\\svcctl",
+       "\\eventlog",
        NULL
 };
 
@@ -81,7 +84,6 @@ static char *nttrans_realloc(char **ptr, size_t size)
 static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
                            int paramsize, char *pdata, int datasize)
 {
-       extern int max_send;
        int data_to_send = datasize;
        int params_to_send = paramsize;
        int useable_space;
@@ -353,6 +355,11 @@ static int map_share_mode( char *fname, uint32 create_options,
        int smb_open_mode = -1;
        uint32 original_desired_access = *desired_access;
 
+       /* This is a nasty hack - must fix... JRA. */
+       if (*desired_access == MAXIMUM_ALLOWED_ACCESS) {
+               *desired_access = FILE_GENERIC_ALL;
+       }
+
        /*
         * Convert GENERIC bits to specific bits.
         */
@@ -581,7 +588,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
        uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
        uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
        uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
-       SMB_BIG_UINT allocation_size = 0;
        int smb_ofun;
        int smb_open_mode;
        /* Breakout the oplock request bits so we can set the
@@ -630,7 +636,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
        
        if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
                END_PROFILE(SMBntcreateX);
-               return(ERROR_DOS(ERRDOS,ERRnoaccess));
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
        }
 
        /*
@@ -883,10 +889,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
 
                                if (create_options & FILE_NON_DIRECTORY_FILE) {
                                        restore_case_semantics(conn, file_attributes);
-                                       SSVAL(outbuf, smb_flg2, 
-                                             SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
                                        END_PROFILE(SMBntcreateX);
-                                       return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
+                                       return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
                                }
        
                                oplock_request = 0;
@@ -903,7 +907,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                                END_PROFILE(SMBntcreateX);
                                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                                        /* We have re-scheduled this call. */
-                                       clear_cached_errors();
                                        return -1;
                                }
                                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@@ -915,8 +918,9 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                
        file_len = sbuf.st_size;
        fmode = dos_mode(conn,fname,&sbuf);
-       if(fmode == 0)
+       if(fmode == 0) {
                fmode = FILE_ATTRIBUTE_NORMAL;
+       }
        if (!fsp->is_directory && (fmode & aDIR)) {
                close_file(fsp,False);
                END_PROFILE(SMBntcreateX);
@@ -924,25 +928,27 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
        } 
        
        /* Save the requested allocation size. */
-       allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
+       if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
+               SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
 #ifdef LARGE_SMB_OFF_T
-       allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
+               allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
 #endif
-       if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
-               fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
-               if (fsp->is_directory) {
-                       close_file(fsp,False);
-                       END_PROFILE(SMBntcreateX);
-                       /* Can't set allocation size on a directory. */
-                       return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-               }
-               if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
-                       close_file(fsp,False);
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(NT_STATUS_DISK_FULL);
+               if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
+                       fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+                       if (fsp->is_directory) {
+                               close_file(fsp,False);
+                               END_PROFILE(SMBntcreateX);
+                               /* Can't set allocation size on a directory. */
+                               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+                       }
+                       if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+                               close_file(fsp,False);
+                               END_PROFILE(SMBntcreateX);
+                               return ERROR_NT(NT_STATUS_DISK_FULL);
+                       }
+               } else {
+                       fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
                }
-       } else {
-               fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
        }
 
        /* 
@@ -951,11 +957,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
         * correct bit for extended oplock reply.
         */
        
-       if (oplock_request && lp_fake_oplocks(SNUM(conn)))
+       if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
                extended_oplock_granted = True;
+       }
        
-       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
                extended_oplock_granted = True;
+       }
 
 #if 0
        /* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
@@ -1158,6 +1166,34 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
        return NT_STATUS_OK;
 }
 
+/****************************************************************************
+ Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+                                                                                                                             
+static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+       struct ea_list *ea_list_head = NULL;
+       size_t offset = 0;
+
+       if (data_size < 4) {
+               return NULL;
+       }
+
+       while (offset + 4 <= data_size) {
+               size_t next_offset = IVAL(pdata,offset);
+               struct ea_list *tmp;
+               struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
+
+               DLIST_ADD_END(ea_list_head, eal, tmp);
+               if (next_offset == 0) {
+                       break;
+               }
+               offset += next_offset;
+       }
+                                                                                                                             
+       return ea_list_head;
+}
+
 /****************************************************************************
  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
 ****************************************************************************/
@@ -1187,11 +1223,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        uint32 create_disposition;
        uint32 create_options;
        uint32 sd_len;
+       uint32 ea_len;
        uint16 root_dir_fid;
-       SMB_BIG_UINT allocation_size = 0;
        int smb_ofun;
        int smb_open_mode;
        time_t c_time;
+       struct ea_list *ea_list = NULL;
+       TALLOC_CTX *ctx = NULL;
+       char *pdata = NULL;
        NTSTATUS status;
 
        DEBUG(5,("call_nt_transact_create\n"));
@@ -1217,7 +1256,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
        if(parameter_count < 54) {
                DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
        }
 
        flags = IVAL(params,0);
@@ -1227,8 +1266,32 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        create_disposition = IVAL(params,28);
        create_options = IVAL(params,32);
        sd_len = IVAL(params,36);
+       ea_len = IVAL(params,40);
        root_dir_fid = (uint16)IVAL(params,4);
 
+       /* Ensure the data_len is correct for the sd and ea values given. */
+       if ((ea_len + sd_len > data_count) ||
+                       (ea_len > data_count) || (sd_len > data_count) ||
+                       (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
+               DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
+                       (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
+
+       if (ea_len) {
+               if (!lp_ea_support(SNUM(conn))) {
+                       DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
+                               (unsigned int)ea_len ));
+                       return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+               }
+
+               if (ea_len < 10) {
+                       DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
+                               (unsigned int)ea_len ));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        if (create_options & FILE_OPEN_BY_FILE_ID) {
                return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
        }
@@ -1238,8 +1301,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
         * NT values, as that's what our code is structured to accept.
         */    
 
-       if((smb_ofun = map_create_disposition( create_disposition )) == -1)
-               return ERROR_DOS(ERRDOS,ERRbadmem);
+       if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        /*
         * Get the file name.
@@ -1361,6 +1425,25 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                }
        }
 
+       if (ea_len) {
+               ctx = talloc_init("NTTRANS_CREATE_EA");
+               if (!ctx) {
+                       talloc_destroy(ctx);
+                       restore_case_semantics(conn, file_attributes);
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+
+               pdata = data + sd_len;
+
+               /* We have already checked that ea_len <= data_count here. */
+               ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);
+               if (!ea_list ) {
+                       talloc_destroy(ctx);
+                       restore_case_semantics(conn, file_attributes);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        /*
         * If it's a request for a directory open, deal with it separately.
         */
@@ -1369,6 +1452,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
                /* Can't open a temp directory. IFS kit test. */
                if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
+                       talloc_destroy(ctx);
+                       restore_case_semantics(conn, file_attributes);
                        return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                }
 
@@ -1383,6 +1468,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
 
                if(!fsp) {
+                       talloc_destroy(ctx);
                        restore_case_semantics(conn, file_attributes);
                        return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
                }
@@ -1398,7 +1484,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                                                oplock_request,&rmode,&smb_action);
 
                if (!fsp) { 
-
                        if(errno == EISDIR) {
 
                                /*
@@ -1407,84 +1492,113 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
                                if (create_options & FILE_NON_DIRECTORY_FILE) {
                                        restore_case_semantics(conn, file_attributes);
-                                       SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
-                                       return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
+                                       return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
                                }
        
                                oplock_request = 0;
                                fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
                                
                                if(!fsp) {
+                                       talloc_destroy(ctx);
                                        restore_case_semantics(conn, file_attributes);
                                        return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
                                }
                        } else {
+                               talloc_destroy(ctx);
                                restore_case_semantics(conn, file_attributes);
                                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                                        /* We have re-scheduled this call. */
-                                       clear_cached_errors();
                                        return -1;
                                }
                                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
                        }
                } 
-  
-               file_len = sbuf.st_size;
-               fmode = dos_mode(conn,fname,&sbuf);
-               if(fmode == 0)
-                       fmode = FILE_ATTRIBUTE_NORMAL;
-
-               if (fmode & aDIR) {
-                       close_file(fsp,False);
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_DOS(ERRDOS,ERRnoaccess);
-               } 
-
-               /* 
-                * If the caller set the extended oplock request bit
-                * and we granted one (by whatever means) - set the
-                * correct bit for extended oplock reply.
-                */
-    
-               if (oplock_request && lp_fake_oplocks(SNUM(conn)))
-                       extended_oplock_granted = True;
-  
-               if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
-                       extended_oplock_granted = True;
        }
 
        /*
-        * Now try and apply the desired SD.
+        * According to the MS documentation, the only time the security
+        * descriptor is applied to the opened file is iff we *created* the
+        * file; an existing file stays the same.
+        * 
+        * Also, it seems (from observation) that you can open the file with
+        * any access mask but you can still write the sd. We need to override
+        * the granted access before we call set_sd
+        * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
         */
 
-       if (lp_nt_acl_support(SNUM(conn)) && sd_len &&
-                       !NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) {
-               close_file(fsp,False);
-               restore_case_semantics(conn, file_attributes);
-               return ERROR_NT(status);
-       }
+       if (lp_nt_acl_support(SNUM(conn)) && sd_len && smb_action == FILE_WAS_CREATED) {
+               uint32 saved_access = fsp->desired_access;
+
+               /* We have already checked that sd_len <= data_count here. */
+
+               fsp->desired_access = FILE_GENERIC_ALL;
+
+               status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
+               if (!NT_STATUS_IS_OK(status)) {
+                       talloc_destroy(ctx);
+                       close_file(fsp,False);
+                       restore_case_semantics(conn, file_attributes);
+                       return ERROR_NT(status);
+               }
+               fsp->desired_access = saved_access;
+       }
        
+       if (ea_len && (smb_action == FILE_WAS_CREATED)) {
+               status = set_ea(conn, fsp, fname, ea_list);
+               talloc_destroy(ctx);
+               if (!NT_STATUS_IS_OK(status)) {
+                       close_file(fsp,False);
+                       restore_case_semantics(conn, file_attributes);
+                       return ERROR_NT(status);
+               }
+       }
+
        restore_case_semantics(conn, file_attributes);
 
+       file_len = sbuf.st_size;
+       fmode = dos_mode(conn,fname,&sbuf);
+       if(fmode == 0) {
+               fmode = FILE_ATTRIBUTE_NORMAL;
+       }
+       if (!fsp->is_directory && (fmode & aDIR)) {
+               close_file(fsp,False);
+               return ERROR_DOS(ERRDOS,ERRnoaccess);
+       } 
+       
        /* Save the requested allocation size. */
-       allocation_size = (SMB_BIG_UINT)IVAL(params,12);
+       if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
+               SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
 #ifdef LARGE_SMB_OFF_T
-       allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
+               allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
 #endif
-       if (allocation_size && (allocation_size > file_len)) {
-               fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
-               if (fsp->is_directory) {
-                       close_file(fsp,False);
-                       END_PROFILE(SMBntcreateX);
-                       /* Can't set allocation size on a directory. */
-                       return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-               }
-               if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
-                       close_file(fsp,False);
-                       return ERROR_NT(NT_STATUS_DISK_FULL);
+               if (allocation_size && (allocation_size > file_len)) {
+                       fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+                       if (fsp->is_directory) {
+                               close_file(fsp,False);
+                               /* Can't set allocation size on a directory. */
+                               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+                       }
+                       if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+                               close_file(fsp,False);
+                               return ERROR_NT(NT_STATUS_DISK_FULL);
+                       }
+               } else {
+                       fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
                }
-       } else {
-               fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
+       }
+
+       /* 
+        * If the caller set the extended oplock request bit
+        * and we granted one (by whatever means) - set the
+        * correct bit for extended oplock reply.
+        */
+    
+       if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+               extended_oplock_granted = True;
+       }
+  
+       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+               extended_oplock_granted = True;
        }
 
        /* Realloc the size of parameters and data we will return */
@@ -1662,12 +1776,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                        &access_mode,&smb_action);
 
        if (!fsp1) {
-               status = NT_STATUS_ACCESS_DENIED;
-               if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
-                       status = NT_STATUS_SHARING_VIOLATION;
-               unix_ERR_class = 0;
-               unix_ERR_code = 0;
-               unix_ERR_ntstatus = NT_STATUS_OK;
+               get_saved_error_triple(NULL, NULL, &status);
+               if (NT_STATUS_IS_OK(status)) {
+                       status = NT_STATUS_ACCESS_DENIED;
+               }
+               set_saved_error_triple(0, 0, NT_STATUS_OK);
                return status;
        }
 
@@ -1676,12 +1789,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                        &access_mode,&smb_action);
 
        if (!fsp2) {
-               status = NT_STATUS_ACCESS_DENIED;
-               if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
-                       status = NT_STATUS_SHARING_VIOLATION;
-               unix_ERR_class = 0;
-               unix_ERR_code = 0;
-               unix_ERR_ntstatus = NT_STATUS_OK;
+               get_saved_error_triple(NULL, NULL, &status);
+               if (NT_STATUS_IS_OK(status)) {
+                       status = NT_STATUS_ACCESS_DENIED;
+               }
+               set_saved_error_triple(0, 0, NT_STATUS_OK);
                close_file(fsp1,False);
                return status;
        }
@@ -1787,7 +1899,6 @@ int reply_ntrename(connection_struct *conn,
                END_PROFILE(SMBntrename);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return ERROR_NT(status);
@@ -1909,7 +2020,6 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
 
 static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
 {
-       extern DOM_SID global_sid_World;
        size_t sd_size;
 
        *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
@@ -1948,7 +2058,8 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
 
        security_info_wanted = IVAL(params,4);
 
-       DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
+       DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
+                       (unsigned int)security_info_wanted ));
 
        params = nttrans_realloc(ppparams, 4);
        if(params == NULL)
@@ -2836,6 +2947,9 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
 
                        ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
 
+                       /* We need to re-calcuate the new length after we've read the secondary packet. */
+                       length = smb_len(inbuf) + 4;
+
                        /*
                         * The sequence number for the trans reply is always
                         * based on the last secondary received.
@@ -2883,7 +2997,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
                                        goto bad_param;
                                if (parameter_displacement > total_parameter_count)
                                        goto bad_param;
-                               if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) ||
+                               if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length) ||
                                                (smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
                                        goto bad_param;
                                if (parameter_displacement + params < params)
@@ -2900,7 +3014,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
                                        goto bad_param;
                                if (data_displacement > total_data_count)
                                        goto bad_param;
-                               if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) ||
+                               if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
                                                (smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
                                        goto bad_param;
                                if (data_displacement + data < data)
index 0a3903234ddb822800bbe0f644e4fe020b666ce6..a3bc4a922d34abe8059648fc1a6c6e9bffc8ea78 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
 extern userdom_struct current_user_info;
 extern uint16 global_oplock_port;
 extern uint16 global_smbpid;
@@ -76,9 +77,92 @@ static void check_for_pipe(const char *fname)
        strlower_m(s);
        if (strstr(s,"pipe/")) {
                DEBUG(3,("Rejecting named pipe open for %s\n",fname));
-               unix_ERR_class = ERRSRV;
-               unix_ERR_code = ERRaccess;
-               unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
+               set_saved_error_triple(ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED);
+       }
+}
+
+/****************************************************************************
+ Change the ownership of a file to that of the parent directory.
+ Do this by fd if possible.
+****************************************************************************/
+
+void change_owner_to_parent(connection_struct *conn, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf)
+{
+       const char *parent_path = parent_dirname(fname);
+       SMB_STRUCT_STAT parent_st;
+       int ret;
+
+       ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
+       if (ret == -1) {
+               DEBUG(0,("change_owner_to_parent: failed to stat parent directory %s. Error was %s\n",
+                       parent_path, strerror(errno) ));
+               return;
+       }
+
+       if (fsp && fsp->fd != -1) {
+               become_root();
+               ret = SMB_VFS_FCHOWN(fsp, fsp->fd, parent_st.st_uid, (gid_t)-1);
+               unbecome_root();
+               if (ret == -1) {
+                       DEBUG(0,("change_owner_to_parent: failed to fchown file %s to parent directory uid %u. \
+Error was %s\n",
+                               fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
+               }
+
+               DEBUG(10,("change_owner_to_parent: changed new file %s to parent directory uid %u.\n",
+                       fname, (unsigned int)parent_st.st_uid ));
+
+       } else {
+               /* We've already done an lstat into psbuf, and we know it's a directory. If
+                  we can cd into the directory and the dev/ino are the same then we can safely
+                  chown without races as we're locking the directory in place by being in it.
+                  This should work on any UNIX (thanks tridge :-). JRA.
+               */
+
+               pstring saved_dir;
+               SMB_STRUCT_STAT sbuf;
+
+               if (!vfs_GetWd(conn,saved_dir)) {
+                       DEBUG(0,("change_owner_to_parent: failed to get current working directory\n"));
+                       return;
+               }
+
+               /* Chdir into the new path. */
+               if (vfs_ChDir(conn, fname) == -1) {
+                       DEBUG(0,("change_owner_to_parent: failed to change current working directory to %s. \
+Error was %s\n", fname, strerror(errno) ));
+                       goto out;
+               }
+
+               if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
+                       DEBUG(0,("change_owner_to_parent: failed to stat directory '.' (%s) \
+Error was %s\n", fname, strerror(errno)));
+                       goto out;
+               }
+
+               /* Ensure we're pointing at the same place. */
+               if (sbuf.st_dev != psbuf->st_dev || sbuf.st_ino != psbuf->st_ino || sbuf.st_mode != psbuf->st_mode ) {
+                       DEBUG(0,("change_owner_to_parent: device/inode/mode on directory %s changed. Refusing to chown !\n",
+                               fname ));
+                       goto out;
+               }
+
+               become_root();
+               ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
+               unbecome_root();
+               if (ret == -1) {
+                       DEBUG(10,("change_owner_to_parent: failed to chown directory %s to parent directory uid %u. \
+Error was %s\n",
+                               fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
+                       goto out;
+               }
+
+               DEBUG(10,("change_owner_to_parent: changed ownership of new directory %s to parent directory uid %u.\n",
+                       fname, (unsigned int)parent_st.st_uid ));
+
+  out:
+
+               vfs_ChDir(conn,saved_dir);
        }
 }
 
@@ -89,7 +173,6 @@ static void check_for_pipe(const char *fname)
 static BOOL open_file(files_struct *fsp,connection_struct *conn,
                      const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
 {
-       extern struct current_user current_user;
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
 
@@ -165,9 +248,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
 
                /* Don't create files with Microsoft wildcard characters. */
                if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname))  {
-                       unix_ERR_class = ERRDOS;
-                       unix_ERR_code = ERRinvalidname;
-                       unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
+                       set_saved_error_triple(ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID);
                        return False;
                }
 
@@ -402,9 +483,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
                DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
                        fname ));
                /* Use errno to map to correct error. */
-               unix_ERR_class = SMB_SUCCESS;
-               unix_ERR_code = 0;
-               unix_ERR_ntstatus = NT_STATUS_OK;
+               set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
                return False;
        }
 
@@ -444,10 +523,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
                                (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
                        DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
                                fname ));
-                       unix_ERR_class = ERRDOS;
-                       unix_ERR_code = ERRbadshare;
-                       unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+                       set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                        return False;
                }
 
@@ -472,10 +548,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
        if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
                DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
                        fname ));
-               unix_ERR_class = ERRDOS;
-               unix_ERR_code = ERRbadshare;
-               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+               set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                return False;
        }
 
@@ -488,18 +561,14 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
        if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
                DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
                        fname ));
-               unix_ERR_class = ERRDOS;
-               unix_ERR_code = ERRbadshare;
-               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+               set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                return False;
        }
 
 #if 0
        /* Bluarc test may need this ... needs further investigation. */
        if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) {
-               unix_ERR_class = ERRDOS;
-               unix_ERR_code = ERRbadshare;
-               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+               set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                return False;
        }
 #endif
@@ -529,10 +598,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
                                deny_mode,old_deny_mode,old_open_mode,
                                (int)share->pid,fname, fcbopen, *flags, access_allowed));
 
-                       unix_ERR_class = ERRDOS;
-                       unix_ERR_code = ERRbadshare;
-                       unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+                       set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                        return False;
                }
 
@@ -683,10 +749,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
                                        DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
                                        SAFE_FREE(old_shares);
-                                       errno = EACCES;
-                                       unix_ERR_class = ERRDOS;
-                                       unix_ERR_code = ERRbadshare;
-                                       unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+                                       set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                                        return -1;
                                }
                                
@@ -750,9 +813,7 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n"
                                        if (del_share_entry(dev, inode, &broken_entry->entry, NULL) == -1) {
                                                free_broken_entry_list(broken_entry_list);
                                                errno = EACCES;
-                                               unix_ERR_class = ERRDOS;
-                                               unix_ERR_code = ERRbadshare;
-                                               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+                                               set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                                                return -1;
                                        }
                                        
@@ -1019,9 +1080,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                        delete_defered_open_entry_record(conn, dib.dev, dib.inode);
                        unlock_share_entry(conn, dib.dev, dib.inode);
 
-                       unix_ERR_class = ERRDOS;
-                       unix_ERR_code = ERRbadshare;
-                       unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+                       set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                        return NULL;
                }
                /* Ensure we don't reprocess this message. */
@@ -1039,15 +1098,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                return print_fsp_open(conn, fname);
        }
 
-       fsp = file_new(conn);
-       if(!fsp)
-               return NULL;
-
        DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
                fname, new_dos_mode, share_mode, ofun, (int)mode,  oplock_request ));
 
        if (!check_name(fname,conn)) {
-               file_free(fsp);
                return NULL;
        } 
 
@@ -1063,21 +1117,15 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
 
        /* this is for OS/2 long file names - say we don't support them */
        if (strstr(fname,".+,;=[].")) {
-               unix_ERR_class = ERRDOS;
                /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
-               unix_ERR_code = ERRcannotopen;
-               unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               set_saved_error_triple(ERRDOS, ERRcannotopen, NT_STATUS_OBJECT_NAME_NOT_FOUND);
                DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n"));
-               /* need to reset errno or DEVELOPER will cause us to coredump */
-               errno = 0;
-               file_free(fsp);
                return NULL;
        }
 
        if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed)  {
                DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
                        fname ));
-               file_free(fsp);
                if (S_ISDIR(psbuf->st_mode)) {
                        errno = EISDIR;
                } else {
@@ -1099,7 +1147,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                        DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
                                                fname, existing_dos_mode, new_dos_mode,
                                                (int)psbuf->st_mode, (int)mode ));
-                       file_free(fsp);
                        errno = EACCES;
                        return NULL;
                }
@@ -1112,6 +1159,12 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                append does not mean the same thing under dos and unix */
 
        switch (GET_OPEN_MODE(share_mode)) {
+               case DOS_OPEN_EXEC:
+               case DOS_OPEN_RDONLY:
+                       flags = O_RDONLY;
+                       if (desired_access == 0)
+                               desired_access = FILE_READ_DATA;
+                       break;
                case DOS_OPEN_WRONLY: 
                        flags = O_WRONLY; 
                        if (desired_access == 0)
@@ -1129,10 +1182,9 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                                desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
                        break;
                default:
-                       flags = O_RDONLY;
-                       if (desired_access == 0)
-                               desired_access = FILE_READ_DATA;
-                       break;
+                       /* Force DOS error. */
+                       set_saved_error_triple(ERRDOS, ERRinvalidparam, NT_STATUS_INVALID);
+                       return NULL;
        }
 
 #if defined(O_SYNC)
@@ -1146,7 +1198,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                if (!fcbopen) {
                        DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
                                fname, !CAN_WRITE(conn) ? "share" : "file" ));
-                       file_free(fsp);
                        errno = EACCES;
                        return NULL;
                }
@@ -1155,7 +1206,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
 
        if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
                DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
-               file_free(fsp);
                errno = EINVAL;
                return NULL;
        }
@@ -1171,6 +1221,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
                }
        }
 
+       fsp = file_new(conn);
+       if(!fsp)
+               return NULL;
+
        if (file_existed) {
 
                dev = psbuf->st_dev;
@@ -1204,9 +1258,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                                flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
 
                        if (!fsp_open && errno) {
-                               unix_ERR_class = ERRDOS;
-                               unix_ERR_code = ERRnoaccess;
-                               unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
+                               /* Default error. */
+                               set_saved_error_triple(ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED);
                        }
 
                        /* 
@@ -1214,9 +1267,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                         * the braindead 1 second delay.
                         */
 
-                       if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
-                               /* The fsp->open_time here represents the current time of day. */
-                               defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
+                       if (!internal_only_open) {
+                               NTSTATUS status;
+                               get_saved_error_triple(NULL, NULL, &status);
+                               if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
+                                       /* The fsp->open_time here represents the current time of day. */
+                                       defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
+                               }
                        }
 
                        unlock_share_entry(conn, dev, inode);
@@ -1226,9 +1283,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                                 * We have detected a sharing violation here
                                 * so return the correct error code
                                 */
-                               unix_ERR_class = ERRDOS;
-                               unix_ERR_code = ERRbadshare;
-                               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+                               set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                        }
                        file_free(fsp);
                        return NULL;
@@ -1300,7 +1355,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                         * the braindead 1 second delay.
                         */
 
-                       if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
+                       NTSTATUS status;
+                       get_saved_error_triple(NULL, NULL, &status);
+                       if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
                                /* The fsp->open_time here represents the current time of day. */
                                defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
                        }
@@ -1312,9 +1369,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                         * We have detected a sharing violation here, so
                         * return the correct code.
                         */
-                        unix_ERR_class = ERRDOS;
-                        unix_ERR_code = ERRbadshare;
-                        unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+                       set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
                        return NULL;
                }
 
@@ -1380,7 +1435,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
        DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
 
        if (Access) {
-               (*Access) = open_mode;
+               (*Access) = (SET_DENY_MODE(deny_mode) | SET_OPEN_MODE(open_mode));
        }
 
        action = 0;
@@ -1389,8 +1444,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                action = FILE_WAS_OPENED;
        if (file_existed && (flags2 & O_TRUNC))
                action = FILE_WAS_OVERWRITTEN;
-       if (!file_existed) 
+       if (!file_existed) {
                action = FILE_WAS_CREATED;
+               /* Change the owner if required. */
+               if (lp_inherit_owner(SNUM(conn))) {
+                       change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
+               }
+       }
 
        if (paction) {
                *paction = action;
@@ -1437,9 +1497,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
                        fd_close(conn,fsp);
                        file_free(fsp);
                        ntstatus_to_dos(result, &u_e_c, &u_e_code);
-                        unix_ERR_ntstatus = result;
-                        unix_ERR_class = u_e_c;
-                        unix_ERR_code = u_e_code;
+                       set_saved_error_triple(u_e_c, u_e_code, result);
                        return NULL;
                }
        }
@@ -1545,10 +1603,9 @@ int close_file_fchmod(files_struct *fsp)
  Open a directory from an NT SMB call.
 ****************************************************************************/
 
-files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
+files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
                        uint32 desired_access, int share_mode, int smb_ofun, int *action)
 {
-       extern struct current_user current_user;
        BOOL got_stat = False;
        files_struct *fsp = file_new(conn);
        BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
@@ -1583,39 +1640,29 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
                         * Try and create the directory.
                         */
 
-                       if(!CAN_WRITE(conn)) {
-                               DEBUG(2,("open_directory: failing create on read-only share\n"));
-                               file_free(fsp);
-                               errno = EACCES;
-                               return NULL;
-                       }
+                       /* We know bad_path is false as it's caught earlier. */
 
-                       if (ms_has_wild(fname))  {
-                               file_free(fsp);
-                               DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
-                               unix_ERR_class = ERRDOS;
-                               unix_ERR_code = ERRinvalidname;
-                               unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
-                               return NULL;
-                       }
+                       NTSTATUS status = mkdir_internal(conn, fname, False);
 
-                       if( strchr_m(fname, ':')) {
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
+                                        fname, strerror(errno) ));
                                file_free(fsp);
-                               DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname));
-                               unix_ERR_class = ERRDOS;
-                               unix_ERR_code = ERRinvalidname;
-                               unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY;
+                               /* Ensure we return the correct NT status to the client. */
+                               set_saved_error_triple(0, 0, status);
                                return NULL;
                        }
 
-                       if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname, True)) < 0) {
-                               DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
-                                        fname, strerror(errno) ));
+                       /* Ensure we're checking for a symlink here.... */
+                       /* We don't want to get caught by a symlink racer. */
+
+                       if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {
                                file_free(fsp);
                                return NULL;
                        }
 
-                       if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
+                       if(!S_ISDIR(psbuf->st_mode)) {
+                               DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
                                file_free(fsp);
                                return NULL;
                        }
@@ -1672,13 +1719,19 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
        string_set(&fsp->fsp_name,fname);
 
        if (delete_on_close) {
-               NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close, 0);
+               NTSTATUS status = set_delete_on_close_internal(fsp, delete_on_close, 0);
 
-               if (NT_STATUS_V(result) !=  NT_STATUS_V(NT_STATUS_OK)) {
+               if (!NT_STATUS_IS_OK(status)) {
                        file_free(fsp);
                        return NULL;
                }
        }
+
+       /* Change the owner if required. */
+       if ((*action == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) {
+               change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
+       }
+
        conn->num_files_open++;
 
        return fsp;
@@ -1690,7 +1743,6 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
 
 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
 {
-       extern struct current_user current_user;
        files_struct *fsp = NULL;
 
        if (!VALID_STAT(*psbuf))
index b9e38e30fcc41494771195ff7a3d8a343387e575..9b8df98fd564077ba449e9c1f406c0d34c6ba93c 100644 (file)
@@ -31,6 +31,9 @@ static int32 level_II_oplocks_open = 0;
 BOOL global_client_failed_oplock_break = False;
 BOOL global_oplock_break = False;
 
+extern struct timeval smb_last_time;
+extern uint32 global_client_caps;
+extern struct current_user current_user;
 extern int smb_read_error;
 
 static struct kernel_oplocks *koplocks;
@@ -518,8 +521,6 @@ static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
 
 static void wait_before_sending_break(BOOL local_request)
 {
-       extern struct timeval smb_last_time;
-
        if(local_request) {
                struct timeval cur_tv;
                long wait_left = (long)lp_oplock_break_wait_time();
@@ -603,7 +604,6 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un
 
 static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request)
 {
-       extern uint32 global_client_caps;
        char outbuf[128];
        SMB_DEV_T dev = fsp->dev;
        SMB_INO_T inode = fsp->inode;
@@ -676,8 +676,6 @@ static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request)
 
 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local_request)
 {
-       extern uint32 global_client_caps;
-       extern struct current_user current_user;
        char *inbuf = NULL;
        char *outbuf = NULL;
        files_struct *fsp = NULL;
@@ -807,7 +805,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
        saved_user_conn = current_user.conn;
        saved_vuid = current_user.vuid;
        saved_fsp_conn = fsp->conn;
-       change_to_root_user();
        /*
         * Initialize saved_dir to something sensible: vfs_GetWd may not work well
         * for root: the directory may be NFS-mounted and exported with root_squash
@@ -818,6 +815,10 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
        /* Save the chain fnum. */
        file_chain_save();
 
+       pstrcpy(file_name, fsp->fsp_name);
+
+       change_to_root_user();
+
        /*
         * From Charles Hoch <hoch@exemplary.com>. If the break processing
         * code closes the file (as it often does), then the fsp pointer here
@@ -825,8 +826,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
         * around the loop.
         */
 
-       pstrcpy(file_name, fsp->fsp_name);
-
        while((fsp = initial_break_processing(dev, inode, file_id)) &&
                        OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
                if(receive_smb(smbd_server_fd(),inbuf, timeout) == False) {
@@ -940,6 +939,9 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
                abort();
        }
 
+       /* We know we have no saved errors here. */
+       set_saved_error_triple(0, 0, NT_STATUS_OK);
+
        if( DEBUGLVL( 3 ) ) {
                dbgtext( "oplock_break: returning success for " );
                dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, file_id );
index 5de9dd56e68d8cb7175efbeccaa1580df25e0f60..5d6bdb98832c875790fbcb76496bc26c35f60916 100644 (file)
 
 #if HAVE_KERNEL_OPLOCKS_LINUX
 
+/* these can be removed when they are in glibc headers */
+struct  cap_user_header {
+       uint32 version;
+       int pid;
+} header;
+struct cap_user_data {
+       uint32 effective;
+       uint32 permitted;
+       uint32 inheritable;
+} data;
+
+extern int capget(struct cap_user_header * hdrp,
+                 struct cap_user_data * datap);
+extern int capset(struct cap_user_header * hdrp,
+                 const struct cap_user_data * datap);
+
 static SIG_ATOMIC_T signals_received;
 #define FD_PENDING_SIZE 100
 static SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
@@ -68,17 +84,6 @@ static void set_capability(unsigned capability)
 #ifndef _LINUX_CAPABILITY_VERSION
 #define _LINUX_CAPABILITY_VERSION 0x19980330
 #endif
-       /* these can be removed when they are in glibc headers */
-       struct  {
-               uint32 version;
-               int pid;
-       } header;
-       struct {
-               uint32 effective;
-               uint32 permitted;
-               uint32 inheritable;
-       } data;
-
        header.version = _LINUX_CAPABILITY_VERSION;
        header.pid = 0;
 
@@ -133,7 +138,8 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l
        fsp = file_find_fd(fd);
        fd_pending_array[0] = (SIG_ATOMIC_T)-1;
        if (signals_received > 1)
-               memmove((void *)&fd_pending_array[0], (void *)&fd_pending_array[1],
+                memmove(CONST_DISCARD(void *, &fd_pending_array[0]),
+                        CONST_DISCARD(void *, &fd_pending_array[1]),
                        sizeof(SIG_ATOMIC_T)*(signals_received-1));
        signals_received--;
        /* now we can receive more signals */
index af58630ee2c024fe32e0d5d3225866ceaf163c28..353f9a3b0384fe68fc0bd3aee98298229abeac09 100644 (file)
@@ -21,6 +21,9 @@
 
 #include "includes.h"
 
+extern struct current_user current_user;
+extern struct generic_mapping file_generic_mapping;
+
 #undef  DBGC_CLASS
 #define DBGC_CLASS DBGC_ACLS
 
@@ -916,7 +919,6 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid
                        if (lp_force_unknown_acl_user(snum)) {
                                /* this allows take ownership to work
                                 * reasonably */
-                               extern struct current_user current_user;
                                *puser = current_user.uid;
                        } else {
                                DEBUG(3,("unpack_nt_owners: unable to validate"
@@ -938,7 +940,6 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid
                        if (lp_force_unknown_acl_user(snum)) {
                                /* this allows take group ownership to work
                                 * reasonably */
-                               extern struct current_user current_user;
                                *pgrp = current_user.gid;
                        } else {
                                DEBUG(3,("unpack_nt_owners: unable to validate"
@@ -1003,10 +1004,8 @@ static void apply_default_perms(files_struct *fsp, canon_ace *pace, mode_t type)
 
 static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
 {
-       extern DOM_SID global_sid_World;
        fstring u_name;
        fstring g_name;
-       extern struct current_user current_user;
 
        /* "Everyone" always matches every uid. */
 
@@ -1041,12 +1040,11 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
 
 static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
                                                        files_struct *fsp,
-                                                       DOM_SID *pfile_owner_sid,
-                                                       DOM_SID *pfile_grp_sid,
+                                                       const DOM_SID *pfile_owner_sid,
+                                                       const DOM_SID *pfile_grp_sid,
                                                        SMB_STRUCT_STAT *pst,
                                                        BOOL setting_acl)
 {
-       extern DOM_SID global_sid_World;
        canon_ace *pace;
        BOOL got_user = False;
        BOOL got_grp = False;
@@ -1220,10 +1218,6 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
                                                        canon_ace **ppfile_ace, canon_ace **ppdir_ace,
                                                        SEC_ACL *dacl)
 {
-       extern DOM_SID global_sid_Creator_Owner;
-       extern DOM_SID global_sid_Creator_Group;
-       extern DOM_SID global_sid_World;
-       extern struct generic_mapping file_generic_mapping;
        BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
        canon_ace *file_ace = NULL;
        canon_ace *dir_ace = NULL;
@@ -1647,7 +1641,6 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
 
 static void process_deny_list( canon_ace **pp_ace_list )
 {
-       extern DOM_SID global_sid_World;
        canon_ace *ace_list = *pp_ace_list;
        canon_ace *curr_ace = NULL;
        canon_ace *curr_ace_next = NULL;
@@ -2065,9 +2058,8 @@ static void arrange_posix_perms( char *filename, canon_ace **pp_list_head)
 ****************************************************************************/
 
 static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf,
-                                       DOM_SID *powner, DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
+                                       const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
 {
-       extern DOM_SID global_sid_World;
        connection_struct *conn = fsp->conn;
        mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR);
        canon_ace *list_head = NULL;
@@ -2629,10 +2621,6 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
 
 size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
 {
-       extern DOM_SID global_sid_Builtin_Administrators;
-       extern DOM_SID global_sid_Builtin_Users;
-       extern DOM_SID global_sid_Creator_Owner;
-       extern DOM_SID global_sid_Creator_Group;
        connection_struct *conn = fsp->conn;
        SMB_STRUCT_STAT sbuf;
        SEC_ACE *nt_ace_list = NULL;
@@ -2920,7 +2908,6 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
 static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
 {
        int ret;
-       extern struct current_user current_user;
        files_struct *fsp;
        SMB_STRUCT_STAT st;
 
@@ -2976,7 +2963,6 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
        uid_t orig_uid;
        gid_t orig_gid;
        BOOL need_chown = False;
-       extern struct current_user current_user;
 
        DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
 
@@ -3067,7 +3053,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
        create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
 
        acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
-                                                                       &file_ace_list, &dir_ace_list, security_info_sent, psd);
+                                       &file_ace_list, &dir_ace_list, security_info_sent, psd);
 
        /* Ignore W2K traverse DACL set. */
        if (file_ace_list || dir_ace_list) {
@@ -3760,7 +3746,6 @@ BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *
 
 static int check_posix_acl_group_write(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
 {
-       extern struct current_user current_user;
        SMB_ACL_T posix_acl = NULL;
        int entry_id = SMB_ACL_FIRST_ENTRY;
        SMB_ACL_ENTRY_T entry;
@@ -3867,6 +3852,23 @@ match on user %u -> %s.\n", fname, (unsigned int)*puid, ret ? "can write" : "can
                                if (pgid == NULL) {
                                        goto check_stat;
                                }
+
+                               /* Does it match the current effective group ? */
+                               if (current_user.gid == *pgid) {
+                                       ret = have_write;
+                                       DEBUG(10,("check_posix_acl_group_write: file %s \
+match on group %u -> can write.\n", fname, (unsigned int)*pgid ));
+
+                                       /* If we don't have write permission this entry doesn't
+                                        * prevent the subsequent enumeration of the supplementary
+                                        * groups.
+                                        */
+                                       if (have_write) {
+                                               goto done;
+                                       }
+                               }
+
+                               /* Continue with the supplementary groups. */
                                for (i = 0; i < current_user.ngroups; i++) {
                                        if (current_user.groups[i] == *pgid) {
                                                ret = have_write;
@@ -3898,6 +3900,15 @@ match on group %u -> can write.\n", fname, (unsigned int)*pgid ));
 
        /* Do we match on the owning group entry ? */
 
+       /* First, does it match the current effective group ? */
+       if (current_user.gid == psbuf->st_gid) {
+               ret = (psbuf->st_mode & S_IWGRP) ? 1 : 0;
+               DEBUG(10,("check_posix_acl_group_write: file %s \
+match on owning group %u -> %s.\n", fname, (unsigned int)psbuf->st_gid, ret ? "can write" : "cannot write"));
+               goto done;
+       }
+
+       /* If not look at the supplementary groups. */
        for (i = 0; i < current_user.ngroups; i++) {
                if (current_user.groups[i] == psbuf->st_gid) {
                        ret = (psbuf->st_mode & S_IWGRP) ? 1 : 0;
@@ -3927,7 +3938,6 @@ failed to match on user or group in token (ret = %d).\n", fname, ret ));
 
 BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
 {
-       extern struct current_user current_user;
        SMB_STRUCT_STAT sbuf;  
        pstring dname;
        int ret;
@@ -3985,7 +3995,6 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
 
 BOOL can_write_to_file(connection_struct *conn, const char *fname)
 {
-       extern struct current_user current_user;
        SMB_STRUCT_STAT sbuf;  
        int ret;
 
index 54837c3b9ae8aa43af6250e294e745962d438d99..e79686b43e2fbd48e4676d039ea04dd9dcf8d9b8 100644 (file)
 
 #include "includes.h"
 
+extern uint16 global_smbpid;
+extern int keepalive;
+extern struct auth_context *negprot_global_auth_context;
+extern int smb_echo_count;
+
 struct timeval smb_last_time;
 
 static char *InBuffer = NULL;
@@ -211,6 +216,7 @@ BOOL open_was_deferred(uint16 mid)
 
        for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
                if (SVAL(pml->buf.data,smb_mid) == mid) {
+                       set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
                        return True;
                }
        }
@@ -851,7 +857,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
 {
        static pid_t pid= (pid_t)-1;
        int outsize = 0;
-       extern uint16 global_smbpid;
 
        type &= 0xff;
 
@@ -859,6 +864,8 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
                pid = sys_getpid();
 
        errno = 0;
+       set_saved_error_triple(0, 0, NT_STATUS_OK);
+
        last_message = type;
 
        /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */
@@ -955,8 +962,12 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
                        return(ERROR_DOS(ERRSRV,ERRaccess));        
 
                /* load service specific parameters */
-               if (conn && !set_current_service(conn,SVAL(inbuf,smb_flg),(flags & (AS_USER|DO_CHDIR)?True:False)))
-                       return(ERROR_DOS(ERRSRV,ERRaccess));
+               if (conn) {
+                       if (!set_current_service(conn,SVAL(inbuf,smb_flg),(flags & (AS_USER|DO_CHDIR)?True:False))) {
+                               return(ERROR_DOS(ERRSRV,ERRaccess));
+                       }
+                       conn->num_smb_operations++;
+               }
 
                /* does this protocol need to be run as guest? */
                if ((flags & AS_GUEST) && (!change_to_guest() || 
@@ -1328,7 +1339,6 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
        static time_t last_idle_closed_check = 0;
        time_t t;
        BOOL allidle = True;
-       extern int keepalive;
 
        if (smb_read_error == READ_EOF) {
                DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
@@ -1372,7 +1382,6 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
        }
 
        if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
-               extern struct auth_context *negprot_global_auth_context;
                if (!send_keepalive(smbd_server_fd())) {
                        DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
                        return False;
@@ -1490,7 +1499,6 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup()));
 
 void smbd_process(void)
 {
-       extern int smb_echo_count;
        time_t last_timeout_processing_time = time(NULL);
        unsigned int num_smbs = 0;
        const size_t total_buffer_size = BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN;
index 1117461bc25477ad133c1f6e2999e72a6e872014..1a73fdf2223a9c3e10c808f99104eac140c3ee53 100644 (file)
@@ -882,8 +882,17 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
     restore_re_uid();
 
     if (r==-1)
+    {
+      DEBUG(5, ("quotactl for uid=%u: %s", euser_id, strerror(errno)));
       return(False);
+    }
         
+    /* No quota for this user. */
+    if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
+    {
+      return(False);
+    }
+
     /* Use softlimit to determine disk space, except when it has been exceeded */
     if (
         (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
@@ -895,14 +904,10 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
       *dfree = 0;
       *dsize = F.d_bcount;
     }
-    else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
-    {
-      return(False);
-    }
     else 
     {
       *dfree = (F.d_blk_softlimit - F.d_bcount);
-      *dsize = F.d_blk_softlimit;
+      *dsize = F.d_blk_softlimit ? F.d_blk_softlimit : F.d_blk_hardlimit;
     }
 
   }
index 5802720b7e9b0d29caebd1b79901cc161bea544f..c3cb81ddfc412b8333d0147f408342386715cb85 100644 (file)
@@ -35,16 +35,17 @@ extern int global_oplock_break;
 unsigned int smb_echo_count = 0;
 extern uint32 global_client_caps;
 
+extern struct current_user current_user;
 extern BOOL global_encrypted_passwords_negotiated;
 
 /****************************************************************************
- Ensure we check the path in *exactly* the same way as W2K.
+ Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
  We're assuming here that '/' is not the second byte in any multibyte char
  set (a safe assumption). '\\' *may* be the second byte in a multibyte char
  set.
 ****************************************************************************/
 
-NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_wcard_names)
+NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
 {
        char *d = destname;
        const char *s = srcname;
@@ -118,20 +119,16 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_w
                }
 
                if (!(*s & 0x80)) {
-                       if (allow_wcard_names) {
-                               *d++ = *s++;
-                       } else {
-                               switch (*s) {
-                                       case '*':
-                                       case '?':
-                                       case '<':
-                                       case '>':
-                                       case '"':
-                                               return NT_STATUS_OBJECT_NAME_INVALID;
-                                       default:
-                                               *d++ = *s++;
-                                               break;
-                               }
+                       switch (*s) {
+                               case '*':
+                               case '?':
+                               case '<':
+                               case '>':
+                               case '"':
+                                       return NT_STATUS_OBJECT_NAME_INVALID;
+                               default:
+                                       *d++ = *s++;
+                                       break;
                        }
                } else {
                        switch(next_mb_char_size(s)) {
@@ -157,17 +154,127 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_w
        }
 
        if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
-               /* For some strange reason being called from findfirst changes
-                  the num_components number to cause the error return to change. JRA. */
-               if (allow_wcard_names) {
-                       if (num_bad_components > 2) {
-                               ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               if (num_bad_components > 1) {
+                       ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               }
+       }
+
+       *d = '\0';
+       return ret;
+}
+
+/****************************************************************************
+ Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
+ path or anything including wildcards.
+ We're assuming here that '/' is not the second byte in any multibyte char
+ set (a safe assumption). '\\' *may* be the second byte in a multibyte char
+ set.
+****************************************************************************/
+
+NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
+{
+       char *d = destname;
+       const char *s = srcname;
+       NTSTATUS ret = NT_STATUS_OK;
+       BOOL start_of_name_component = True;
+       unsigned int num_bad_components = 0;
+
+       while (*s) {
+               if (IS_DIRECTORY_SEP(*s)) {
+                       /*
+                        * Safe to assume is not the second part of a mb char as this is handled below.
+                        */
+                       /* Eat multiple '/' or '\\' */
+                       while (IS_DIRECTORY_SEP(*s)) {
+                               s++;
+                       }
+                       if ((d != destname) && (*s != '\0')) {
+                               /* We only care about non-leading or trailing '/' or '\\' */
+                               *d++ = '/';
                        }
+
+                       start_of_name_component = True;
+                       continue;
+               }
+
+               if (start_of_name_component) {
+                       if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
+                               /* Uh oh - "/../" or "\\..\\"  or "/..\0" or "\\..\0" ! */
+
+                               /*
+                                * No mb char starts with '.' so we're safe checking the directory separator here.
+                                */
+
+                               /* If  we just added a '/' - delete it */
+                               if ((d > destname) && (*(d-1) == '/')) {
+                                       *(d-1) = '\0';
+                                       d--;
+                               }
+
+                               /* Are we at the start ? Can't go back further if so. */
+                               if (d <= destname) {
+                                       ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+                                       break;
+                               }
+                               /* Go back one level... */
+                               /* We know this is safe as '/' cannot be part of a mb sequence. */
+                               /* NOTE - if this assumption is invalid we are not in good shape... */
+                               /* Decrement d first as d points to the *next* char to write into. */
+                               for (d--; d > destname; d--) {
+                                       if (*d == '/')
+                                               break;
+                               }
+                               s += 2; /* Else go past the .. */
+                               /* We're still at the start of a name component, just the previous one. */
+
+                               if (num_bad_components) {
+                                       /* Hmmm. Should we only decrement the bad_components if
+                                          we're removing a bad component ? Need to check this. JRA. */
+                                       num_bad_components--;
+                               }
+
+                               continue;
+
+                       } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
+                               /* Component of pathname can't be "." only. */
+                               ret =  NT_STATUS_OBJECT_NAME_INVALID;
+                               num_bad_components++;
+                               *d++ = *s++;
+                               continue;
+                       }
+               }
+
+               if (!(*s & 0x80)) {
+                       *d++ = *s++;
                } else {
-                       if (num_bad_components > 1) {
-                               ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+                       switch(next_mb_char_size(s)) {
+                               case 4:
+                                       *d++ = *s++;
+                               case 3:
+                                       *d++ = *s++;
+                               case 2:
+                                       *d++ = *s++;
+                               case 1:
+                                       *d++ = *s++;
+                                       break;
+                               default:
+                                       DEBUG(0,("check_path_syntax_wcard: character length assumptions invalid !\n"));
+                                       *d = '\0';
+                                       return NT_STATUS_INVALID_PARAMETER;
                        }
                }
+               if (start_of_name_component && num_bad_components) {
+                       num_bad_components++;
+               }
+               start_of_name_component = False;
+       }
+
+       if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
+               /* For some strange reason being called from findfirst changes
+                  the num_components number to cause the error return to change. JRA. */
+               if (num_bad_components > 2) {
+                       ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               }
        }
 
        *d = '\0';
@@ -192,7 +299,11 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
        } else {
                ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
        }
-       *err = check_path_syntax(dest, tmppath, allow_wcard_names);
+       if (allow_wcard_names) {
+               *err = check_path_syntax_wcard(dest, tmppath);
+       } else {
+               *err = check_path_syntax(dest, tmppath);
+       }
        return ret;
 }
 
@@ -361,7 +472,6 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        int passlen = SVAL(inbuf,smb_vwv3);
        pstring path;
        char *p, *q;
-       extern BOOL global_encrypted_passwords_negotiated;
        
        START_PROFILE(SMBtconX);        
 
@@ -821,6 +931,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        BOOL can_open = True;
        BOOL bad_path = False;
        NTSTATUS nt_status;
+       BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
+
        START_PROFILE(SMBsearch);
 
        *mask = *directory = *fname = 0;
@@ -839,7 +951,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                return ERROR_NT(nt_status);
        }
 
-       RESOLVE_DFSPATH(path, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(path, conn, inbuf, outbuf);
   
        p++;
        status_len = SVAL(p, 0);
@@ -920,7 +1032,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                if (ok) {
                        if ((dirtype&0x1F) == aVOLID) {   
                                memcpy(p,status,21);
-                               make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
+                               make_dir_struct(p,"???????????",volume_label(SNUM(conn)),
+                                               0,aVOLID,0,!allow_long_path_components);
                                dptr_fill(p+12,dptr_num);
                                if (dptr_zero(p+12) && (status_len==0))
                                        numentries = 1;
@@ -940,7 +1053,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                                        finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
                                        if (!finished) {
                                                memcpy(p,status,21);
-                                               make_dir_struct(p,mask,fname,size,mode,date);
+                                               make_dir_struct(p,mask,fname,size, mode,date,
+                                                               !allow_long_path_components);
                                                dptr_fill(p+12,dptr_num);
                                                numentries++;
                                                p += DIR_STRUCT_SIZE;
@@ -978,8 +1092,11 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        SCVAL(smb_buf(outbuf),0,5);
        SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
 
-       if (Protocol >= PROTOCOL_NT1)
-               SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+       /* The replies here are never long name. */
+       SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
+       if (!allow_long_path_components) {
+               SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS));
+       }
 
        /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
        SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
@@ -1089,7 +1206,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                END_PROFILE(SMBopen);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1152,6 +1268,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        BOOL bad_path = False;
        files_struct *fsp;
        NTSTATUS status;
+       SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
+       ssize_t retval = -1;
+
        START_PROFILE(SMBopenX);
 
        /* If it's an IPC, pass off the pipe handler. */
@@ -1179,7 +1298,17 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                END_PROFILE(SMBopenX);
                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
        }
-    
+
+       /* Strange open mode mapping. */
+       if (smb_ofun == 0) {
+               if (GET_OPEN_MODE(smb_mode) == DOS_OPEN_EXEC) {
+                       smb_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
+               } else {
+                       END_PROFILE(SMBopenX);
+                       return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
+               }
+       }
+
        fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
                        oplock_request, &rmode,&smb_action);
       
@@ -1187,13 +1316,31 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                END_PROFILE(SMBopenX);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
        }
 
        size = sbuf.st_size;
+
+       /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
+          if the file is truncated or created. */
+       if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
+               fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+               if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+                       close_file(fsp,False);
+                       END_PROFILE(SMBntcreateX);
+                       return ERROR_NT(NT_STATUS_DISK_FULL);
+               }
+               retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
+               if (retval < 0) {
+                       close_file(fsp,False);
+                       END_PROFILE(SMBwrite);
+                       return ERROR_NT(NT_STATUS_DISK_FULL);
+               }
+               size = get_allocation_size(conn,fsp,&sbuf);
+       }
+
        fmode = dos_mode(conn,fname,&sbuf);
        mtime = sbuf.st_mtime;
        if (fmode & aDIR) {
@@ -1321,7 +1468,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                END_PROFILE(SMBcreate);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1405,7 +1551,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                END_PROFILE(SMBctemp);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1467,20 +1612,19 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
                return NT_STATUS_OK;
 
        /* We need a better way to return NT status codes from open... */
-       unix_ERR_class = 0;
-       unix_ERR_code = 0;
+       set_saved_error_triple(0, 0, NT_STATUS_OK);
 
        fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
                (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
 
        if (!fsp) {
-               NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
-               if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
-                       ret = NT_STATUS_SHARING_VIOLATION;
-               unix_ERR_class = 0;
-               unix_ERR_code = 0;
-               unix_ERR_ntstatus = NT_STATUS_OK;
-               return ret;
+               NTSTATUS ret;
+               if (get_saved_error_triple(NULL, NULL, &ret)) {
+                       set_saved_error_triple(0, 0, NT_STATUS_OK);
+                       return ret;
+               }
+               set_saved_error_triple(0, 0, NT_STATUS_OK);
+               return NT_STATUS_ACCESS_DENIED;
        }
        close_file(fsp,False);
        return NT_STATUS_OK;
@@ -1540,22 +1684,19 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_
                   don't do it here as we'll get it wrong. */
 
                /* We need a better way to return NT status codes from open... */
-               unix_ERR_class = 0;
-               unix_ERR_code = 0;
+               set_saved_error_triple(0, 0, NT_STATUS_OK);
 
                fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
                        (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
 
                if (!fsp) {
-                       NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
-                       if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
-                               ret = unix_ERR_ntstatus;
-                       else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
-                               ret = NT_STATUS_SHARING_VIOLATION;
-                       unix_ERR_class = 0;
-                       unix_ERR_code = 0;
-                       unix_ERR_ntstatus = NT_STATUS_OK;
-                       return ret;
+                       NTSTATUS ret;
+                       if (get_saved_error_triple(NULL, NULL, &ret)) {
+                               set_saved_error_triple(0, 0, NT_STATUS_OK);
+                               return ret;
+                       }
+                       set_saved_error_triple(0, 0, NT_STATUS_OK);
+                       return NT_STATUS_ACCESS_DENIED;
                }
                close_file(fsp,False);
        }
@@ -1716,7 +1857,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                return ERROR_NT(status);
        }
        
-       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
        
        DEBUG(3,("reply_unlink : %s\n",name));
        
@@ -1724,7 +1865,6 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return ERROR_NT(status);
@@ -1870,7 +2010,6 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
 
 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
 {
-       extern struct current_user current_user;
        ssize_t maxcount,mincount;
        size_t nread = 0;
        SMB_OFF_T startpos;
@@ -2840,7 +2979,6 @@ int reply_exit(connection_struct *conn,
 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
                 int dum_buffsize)
 {
-       extern struct current_user current_user;
        int outsize = 0;
        time_t mtime;
        int32 eclass = 0, err = 0;
@@ -3314,29 +3452,32 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
  code. 
 ****************************************************************************/
 
-NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
+NTSTATUS mkdir_internal(connection_struct *conn, const pstring directory, BOOL bad_path)
 {
-       BOOL bad_path = False;
-       SMB_STRUCT_STAT sbuf;
        int ret= -1;
        
-       unix_convert(directory,conn,0,&bad_path,&sbuf);
-
-       if( strchr_m(directory, ':')) {
-               return NT_STATUS_NOT_A_DIRECTORY;
-       }
-
-       if (ms_has_wild(directory)) {
-               return NT_STATUS_OBJECT_NAME_INVALID;
+       if(!CAN_WRITE(conn)) {
+               DEBUG(5,("mkdir_internal: failing create on read-only share %s\n", lp_servicename(SNUM(conn))));
+               errno = EACCES;
+               return map_nt_error_from_unix(errno);
        }
 
        if (bad_path) {
                return NT_STATUS_OBJECT_PATH_NOT_FOUND;
        }
 
-       if (check_name(directory, conn))
-               ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
-       
+       if (!check_name(directory, conn)) {
+               if(errno == ENOENT) {
+                       if (bad_path) {
+                               return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+                       } else {
+                               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+                       }
+               }
+               return map_nt_error_from_unix(errno);
+       }
+
+       ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
        if (ret == -1) {
                if(errno == ENOENT) {
                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3356,6 +3497,9 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        pstring directory;
        int outsize;
        NTSTATUS status;
+       BOOL bad_path = False;
+       SMB_STRUCT_STAT sbuf;
+
        START_PROFILE(SMBmkdir);
  
        srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
@@ -3366,12 +3510,38 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
 
-       status = mkdir_internal(conn, directory);
+       unix_convert(directory,conn,0,&bad_path,&sbuf);
+
+       if( strchr_m(directory, ':')) {
+               DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
+               END_PROFILE(SMBmkdir);
+               return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
+       }
+
+       status = mkdir_internal(conn, directory,bad_path);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBmkdir);
                return ERROR_NT(status);
        }
 
+       if (lp_inherit_owner(SNUM(conn))) {
+               /* Ensure we're checking for a symlink here.... */
+               /* We don't want to get caught by a symlink racer. */
+
+               if(SMB_VFS_LSTAT(conn,directory, &sbuf) != 0) {
+                       END_PROFILE(SMBmkdir);
+                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+               }
+                                                                                                                                                   
+               if(!S_ISDIR(sbuf.st_mode)) {
+                       DEBUG(0,("reply_mkdir: %s is not a directory !\n", directory ));
+                       END_PROFILE(SMBmkdir);
+                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+               }
+
+               change_owner_to_parent(conn, NULL, directory, &sbuf);
+       }
+
        outsize = set_message(outbuf,0,0,True);
 
        DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
@@ -4145,8 +4315,8 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                return ERROR_NT(status);
        }
        
-       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
-       RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
        
        DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
        
@@ -4155,7 +4325,6 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                END_PROFILE(SMBmv);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return ERROR_NT(status);
@@ -4305,8 +4474,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                return ERROR_DOS(ERRSRV,ERRinvdevice);
        }
 
-       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
-       RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
 
        rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
        unix_convert(newname,conn,0,&bad_path2,&sbuf2);
@@ -4419,8 +4588,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                        return ERROR_DOS(ERRDOS,error);
                } else {
                        if((errno == ENOENT) && (bad_path1 || bad_path2)) {
-                               unix_ERR_class = ERRDOS;
-                               unix_ERR_code = ERRbadpath;
+                               set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK);
                        }
                        END_PROFILE(SMBcopy);
                        return(UNIXERROR(ERRDOS,error));
@@ -4976,7 +5144,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
        CHECK_FSP(fsp,conn);
        CHECK_WRITE(fsp);
-       CHECK_ERROR(fsp);
+       if (HAS_CACHED_ERROR(fsp)) {
+               return(CACHED_ERROR(fsp));
+       }
 
        tcount = SVAL(inbuf,smb_vwv1);
        startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
@@ -5119,8 +5289,12 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
                        END_PROFILE(SMBwriteBs);
                        return(ERROR_DOS(ERRHRD,ERRdiskfull));
                }
+               wbms->wr_errclass = ERRHRD;
+               wbms->wr_error = ERRdiskfull;
+               wbms->wr_status = NT_STATUS_DISK_FULL;
+               wbms->wr_discard = True;
                END_PROFILE(SMBwriteBs);
-               return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+               return -1;
        }
 
        /* Increment the total written, if this matches tcount
index 7f7d55c7e3a027e70c57ea34072273708441fe1f..9d910cd14adf1ff02ea9d8fdd379708f3b6d1e7b 100644 (file)
@@ -30,6 +30,8 @@ int last_message = -1;
 /* a useful macro to debug the last message processed */
 #define LAST_MESSAGE() smb_fn_name(last_message)
 
+extern char *last_inbuf;
+extern struct auth_context *negprot_global_auth_context;
 extern pstring user_socket_options;
 extern SIG_ATOMIC_T got_sig_term;
 extern SIG_ATOMIC_T reload_after_sighup;
@@ -598,8 +600,6 @@ static BOOL dump_core(void)
 void exit_server(const char *reason)
 {
        static int firsttime=1;
-       extern char *last_inbuf;
-       extern struct auth_context *negprot_global_auth_context;
 
        if (!firsttime)
                exit(0);
index 684d49c56aeab39adbabe430fa442373263cc41d..d39d3d3836c05531e60303c3b48c64007adce54a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "includes.h"
 
+extern char magic_char;
 extern struct timeval smb_last_time;
 extern userdom_struct current_user_info;
 
@@ -30,7 +31,6 @@ extern userdom_struct current_user_info;
 
 BOOL set_current_service(connection_struct *conn, uint16 flags, BOOL do_chdir)
 {
-       extern char magic_char;
        static connection_struct *last_conn;
        static uint16 last_flags;
        int snum;
@@ -272,7 +272,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        struct passwd *pass = NULL;
        BOOL guest = False;
        connection_struct *conn;
-       struct stat st;
+       SMB_STRUCT_STAT st;
        fstring user;
        fstring dev;
 
index 19acc4b1b08112d9b4bc1c7aa654b8eb22b145e6..9fbf0b1d51ddb488102ff8f65e95ed944ab4b701 100644 (file)
 
 uint32 global_client_caps = 0;
 
+extern BOOL global_encrypted_passwords_negotiated;
+extern BOOL global_spnego_negotiated;
+extern enum protocol_types Protocol;
+extern int max_send;
+extern struct auth_context *negprot_global_auth_context;
+
 static struct auth_ntlmssp_state *global_ntlmssp_state;
 
 /*
@@ -313,7 +319,9 @@ static int reply_spnego_kerberos(connection_struct *conn,
 
         /* wrap that up in a nice GSS-API wrapping */
        if (NT_STATUS_IS_OK(ret)) {
-               ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
+               ap_rep_wrapped = spnego_gen_krb5_wrap(
+                        ap_rep,
+                        CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REP));
        } else {
                ap_rep_wrapped = data_blob(NULL, 0);
        }
@@ -417,7 +425,9 @@ static int reply_spnego_negotiate(connection_struct *conn,
        DATA_BLOB secblob;
        int i;
        DATA_BLOB chal;
-       BOOL got_kerberos = False;
+#ifdef HAVE_KRB5
+       BOOL got_kerberos_mechanism = False;
+#endif
        NTSTATUS nt_status;
 
        /* parse out the OIDs and the first sec blob */
@@ -434,11 +444,13 @@ static int reply_spnego_negotiate(connection_struct *conn,
           server sent back krb5/mskrb5/ntlmssp as mechtypes, but the 
           client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an 
           NTLMSSP mechtoken.                 --jerry              */
-       
+
+#ifdef HAVE_KRB5       
        if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
            strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
-               got_kerberos = True;
+               got_kerberos_mechanism = True;
        }
+#endif
                
        for (i=0;OIDs[i];i++) {
                DEBUG(3,("Got OID %s\n", OIDs[i]));
@@ -447,7 +459,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
        DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length));
 
 #ifdef HAVE_KRB5
-       if (got_kerberos && (SEC_ADS == lp_security())) {
+       if (got_kerberos_mechanism && (SEC_ADS == lp_security())) {
                int ret = reply_spnego_kerberos(conn, inbuf, outbuf, 
                                                length, bufsize, &secblob);
                data_blob_free(&secblob);
@@ -631,13 +643,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        fstring native_lanman;
        fstring primary_domain;
        static BOOL done_sesssetup = False;
-       extern BOOL global_encrypted_passwords_negotiated;
-       extern BOOL global_spnego_negotiated;
-       extern enum protocol_types Protocol;
-       extern int max_send;
 
        auth_usersupplied_info *user_info = NULL;
-       extern struct auth_context *negprot_global_auth_context;
        auth_serversupplied_info *server_info = NULL;
 
        NTSTATUS nt_status;
index cfc5286327b9be6e71b3a0a770a50b9bda1ef53f..8e22d9687b8d2785810feb9d7fd02bcfbf2ccc3c 100644 (file)
@@ -47,10 +47,15 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
        TDB_DATA data_val;
        char *original_path;
        size_t original_path_length;
+       size_t sc_size = lp_max_stat_cache_size();
 
        if (!lp_stat_cache())
                return;
 
+       if (sc_size && (tdb_stat_cache->map_size > sc_size*1024)) {
+               reset_stat_cache();
+       }
+
        ZERO_STRUCT(data_val);
 
        /*
index daa458f3a977a57c4351bd128a4b55ace0d6cccb..dd72db2fae604fff76a1f2a8c65169bbe161cf34 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "includes.h"
 
+extern int max_send;
 extern enum protocol_types Protocol;
 extern int smb_read_error;
 extern int global_oplock_break;
@@ -58,14 +59,18 @@ SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB
 {
        SMB_BIG_UINT ret;
 
+       if(S_ISDIR(sbuf->st_mode)) {
+               return 0;
+       }
+
 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
        ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
 #else
        ret = (SMB_BIG_UINT)get_file_size(*sbuf);
 #endif
 
-       if (!ret && fsp && fsp->initial_allocation_size)
-               ret = fsp->initial_allocation_size;
+       if (fsp && fsp->initial_allocation_size)
+               ret = MAX(ret,fsp->initial_allocation_size);
 
        return smb_roundup(conn, ret);
 }
@@ -95,11 +100,6 @@ static BOOL samba_private_attr_name(const char *unix_ea_name)
        return False;
 }
 
-struct ea_list {
-       struct ea_list *next, *prev;
-       struct ea_struct ea;
-};
-
 /****************************************************************************
  Get one EA value. Fill in a struct ea_struct.
 ****************************************************************************/
@@ -152,7 +152,8 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str
  Return a linked list of the total EA's. Plus the total size
 ****************************************************************************/
 
-static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
+static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
+                                       const char *fname, size_t *pea_total_len)
 {
        /* Get a list of all xattrs. Max namesize is 64k. */
        size_t ea_namelist_size = 1024;
@@ -186,7 +187,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
        if (sizeret == -1)
                return NULL;
 
-       DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
+       DEBUG(10,("get_ea_list_from_file: ea_namelist size = %d\n", sizeret ));
 
        if (sizeret) {
                for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
@@ -207,7 +208,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
                                fstring dos_ea_name;
                                push_ascii_fstring(dos_ea_name, listp->ea.name);
                                *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
-                               DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
+                               DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
                                        *pea_total_len, dos_ea_name,
                                        (unsigned int)listp->ea.value.length ));
                        }
@@ -219,7 +220,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
                }
        }
 
-       DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
+       DEBUG(10,("get_ea_list_from_file: total_len = %u\n", *pea_total_len));
        return ea_list_head;
 }
 
@@ -228,34 +229,16 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
  that was filled.
 ****************************************************************************/
 
-static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
-       connection_struct *conn, files_struct *fsp, const char *fname)
+static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
+       connection_struct *conn, struct ea_list *ea_list)
 {
        unsigned int ret_data_size = 4;
        char *p = pdata;
-       size_t total_ea_len;
-       TALLOC_CTX *mem_ctx;
-       struct ea_list *ea_list;
 
        SMB_ASSERT(total_data_size >= 4);
 
-       SIVAL(pdata,0,0);
        if (!lp_ea_support(SNUM(conn))) {
-               return 4;
-       }
-       mem_ctx = talloc_init("fill_ea_buffer");
-       if (!mem_ctx) {
-               return 4;
-       }
-
-       ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
-       if (!ea_list) {
-               talloc_destroy(mem_ctx);
-               return 4;
-       }
-
-       if (total_ea_len > total_data_size) {
-               talloc_destroy(mem_ctx);
+               SIVAL(pdata,4,0);
                return 4;
        }
 
@@ -286,9 +269,7 @@ static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
        }
 
        ret_data_size = PTR_DIFF(p, pdata);
-       DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
-                       ret_data_size, total_ea_len ));
-       talloc_destroy(mem_ctx);
+       DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
        SIVAL(pdata,0,ret_data_size);
        return ret_data_size;
 }
@@ -302,7 +283,7 @@ static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp,
                return 0;
        }
        mem_ctx = talloc_init("estimate_ea_size");
-       (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
+       (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
        talloc_destroy(mem_ctx);
        return total_ea_len;
 }
@@ -315,7 +296,7 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
 {
        size_t total_ea_len;
        TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
-       struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
+       struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
 
        for (; ea_list; ea_list = ea_list->next) {
                if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
@@ -332,99 +313,246 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
  Set or delete an extended attribute.
 ****************************************************************************/
 
-static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
-                       char *pdata, int total_data)
+NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
 {
-       unsigned int namelen;
-       unsigned int ealen;
-       int ret;
-       fstring unix_ea_name;
-
        if (!lp_ea_support(SNUM(conn))) {
                return NT_STATUS_EAS_NOT_SUPPORTED;
        }
 
-       if (total_data < 8) {
-               return NT_STATUS_INVALID_PARAMETER;
+       for (;ea_list; ea_list = ea_list->next) {
+               int ret;
+               fstring unix_ea_name;
+
+               fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
+               fstrcat(unix_ea_name, ea_list->ea.name);
+
+               canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
+
+               DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ea_list->ea.value.length));
+
+               if (samba_private_attr_name(unix_ea_name)) {
+                       DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
+                       return NT_STATUS_ACCESS_DENIED;
+               }
+
+               if (ea_list->ea.value.length == 0) {
+                       /* Remove the attribute. */
+                       if (fsp && (fsp->fd != -1)) {
+                               DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
+                                       unix_ea_name, fsp->fsp_name));
+                               ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
+                       } else {
+                               DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
+                                       unix_ea_name, fname));
+                               ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
+                       }
+#ifdef ENOATTR
+                       /* Removing a non existent attribute always succeeds. */
+                       if (ret == -1 && errno == ENOATTR) {
+                               DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
+                                               unix_ea_name));
+                               ret = 0;
+                       }
+#endif
+               } else {
+                       if (fsp && (fsp->fd != -1)) {
+                               DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
+                                       unix_ea_name, fsp->fsp_name));
+                               ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name,
+                                                       ea_list->ea.value.data, ea_list->ea.value.length, 0);
+                       } else {
+                               DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
+                                       unix_ea_name, fname));
+                               ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
+                                                       ea_list->ea.value.data, ea_list->ea.value.length, 0);
+                       }
+               }
+
+               if (ret == -1) {
+#ifdef ENOTSUP
+                       if (errno == ENOTSUP) {
+                               return NT_STATUS_EAS_NOT_SUPPORTED;
+                       }
+#endif
+                       return map_nt_error_from_unix(errno);
+               }
+
+       }
+       return NT_STATUS_OK;
+}
+/****************************************************************************
+ Read a list of EA names from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+
+static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+       struct ea_list *ea_list_head = NULL;
+       size_t offset = 0;
+
+       while (offset + 2 < data_size) {
+               struct ea_list *tmp;
+               struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+               unsigned int namelen = CVAL(pdata,offset);
+
+               offset++; /* Go past the namelen byte. */
+
+               /* integer wrap paranioa. */
+               if ((offset + namelen < offset) || (offset + namelen < namelen) ||
+                               (offset > data_size) || (namelen > data_size) ||
+                               (offset + namelen >= data_size)) {
+                       break;
+               }
+               /* Ensure the name is null terminated. */
+               if (pdata[offset + namelen] != '\0') {
+                       return NULL;
+               }
+               pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
+               if (!eal->ea.name) {
+                       return NULL;
+               }
+
+               offset += (namelen + 1); /* Go past the name + terminating zero. */
+               DLIST_ADD_END(ea_list_head, eal, tmp);
+               DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
+       }
+
+       return ea_list_head;
+}
+
+/****************************************************************************
+ Read one EA list entry from the buffer.
+****************************************************************************/
+
+struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
+{
+       struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+       uint16 val_len;
+       unsigned int namelen;
+
+       if (!eal) {
+               return NULL;
        }
 
-       if (IVAL(pdata,0) > total_data) {
-               DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
-               return NT_STATUS_INVALID_PARAMETER;
+       if (data_size < 6) {
+               return NULL;
        }
 
-       pdata += 4;
+       eal->ea.flags = CVAL(pdata,0);
        namelen = CVAL(pdata,1);
-       ealen = SVAL(pdata,2);
-       pdata += 4;
-       if (total_data < 8 + namelen + 1 + ealen) {
-               DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
-                       (unsigned int)total_data, namelen, ealen));
-               return NT_STATUS_INVALID_PARAMETER;
+       val_len = SVAL(pdata,2);
+
+       if (4 + namelen + 1 + val_len > data_size) {
+               return NULL;
        }
 
-       if (pdata[namelen] != '\0') {
-               DEBUG(10,("set_ea: ea name not null terminated\n"));
-               return NT_STATUS_INVALID_PARAMETER;
+       /* Ensure the name is null terminated. */
+       if (pdata[namelen + 4] != '\0') {
+               return NULL;
+       }
+       pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
+       if (!eal->ea.name) {
+               return NULL;
        }
 
-       fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
-       pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
-       pdata += (namelen + 1);
+       eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
+       if (!eal->ea.value.data) {
+               return NULL;
+       }
 
-       canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
+       memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
 
-       DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
-       if (ealen) {
-               DEBUG(10,("set_ea: data :\n"));
-               dump_data(10, pdata, ealen);
-       }
+       /* Ensure we're null terminated just in case we print the value. */
+       eal->ea.value.data[val_len] = '\0';
+       /* But don't count the null. */
+       eal->ea.value.length--;
 
-       if (samba_private_attr_name(unix_ea_name)) {
-               DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
-               return NT_STATUS_ACCESS_DENIED;
+       if (pbytes_used) {
+               *pbytes_used = 4 + namelen + 1 + val_len;
        }
 
-       if (ealen == 0) {
-               /* Remove the attribute. */
-               if (fsp && (fsp->fd != -1)) {
-                       DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
-                               unix_ea_name, fsp->fsp_name));
-                       ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
-               } else {
-                       DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
-                               unix_ea_name, fname));
-                       ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
-               }
-#ifdef ENOATTR
-               /* Removing a non existent attribute always succeeds. */
-               if (ret == -1 && errno == ENOATTR) {
-                       DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
-                       ret = 0;
-               }
-#endif
-       } else {
-               if (fsp && (fsp->fd != -1)) {
-                       DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
-                               unix_ea_name, fsp->fsp_name));
-                       ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
-               } else {
-                       DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
-                               unix_ea_name, fname));
-                       ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
+       DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
+       dump_data(10, eal->ea.value.data, eal->ea.value.length);
+
+       return eal;
+}
+
+/****************************************************************************
+ Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+
+static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+       struct ea_list *ea_list_head = NULL;
+       size_t offset = 0;
+       size_t bytes_used = 0;
+
+       while (offset < data_size) {
+               struct ea_list *tmp;
+               struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
+
+               if (!eal) {
+                       return NULL;
                }
+
+               DLIST_ADD_END(ea_list_head, eal, tmp);
+               offset += bytes_used;
        }
 
-       if (ret == -1) {
-#ifdef ENOTSUP
-               if (errno == ENOTSUP) {
-                       return NT_STATUS_EAS_NOT_SUPPORTED;
+       return ea_list_head;
+}
+
+/****************************************************************************
+ Count the total EA size needed.
+****************************************************************************/
+
+static size_t ea_list_size(struct ea_list *ealist)
+{
+       fstring dos_ea_name;
+       struct ea_list *listp;
+       size_t ret = 0;
+
+       for (listp = ealist; listp; listp = listp->next) {
+               push_ascii_fstring(dos_ea_name, listp->ea.name);
+               ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
+       }
+       /* Add on 4 for total length. */
+       if (ret) {
+               ret += 4;
+       }
+
+       return ret;
+}
+
+/****************************************************************************
+ Return a union of EA's from a file list and a list of names.
+ The TALLOC context for the two lists *MUST* be identical as we steal
+ memory from one list to add to another. JRA.
+****************************************************************************/
+
+static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
+{
+       struct ea_list *nlistp, *flistp;
+
+       for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
+               for (flistp = file_list; flistp; flistp = flistp->next) {
+                       if (strequal(nlistp->ea.name, flistp->ea.name)) {
+                               break;
+                       }
+               }
+
+               if (flistp) {
+                       /* Copy the data from this entry. */
+                       nlistp->ea.flags = flistp->ea.flags;
+                       nlistp->ea.value = flistp->ea.value;
+               } else {
+                       /* Null entry. */
+                       nlistp->ea.flags = 0;
+                       ZERO_STRUCT(nlistp->ea.value);
                }
-#endif
-               return map_nt_error_from_unix(errno);
        }
 
-       return NT_STATUS_OK;
+       *total_ea_len = ea_list_size(name_list);
+       return name_list;
 }
 
 /****************************************************************************
@@ -447,7 +575,6 @@ static int send_trans2_replies(char *outbuf,
         global struct. These different max_xmit variables should
         be merged as this is now too confusing */
 
-       extern int max_send;
        int data_to_send = datasize;
        int params_to_send = paramsize;
        int useable_space;
@@ -587,6 +714,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
                                unsigned int max_data_bytes)
 {
        char *params = *pparams;
+       char *pdata = *ppdata;
        int16 open_mode;
        int16 open_attr;
        BOOL oplock_request;
@@ -606,18 +734,27 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
        int smb_action = 0;
        BOOL bad_path = False;
        files_struct *fsp;
+       TALLOC_CTX *ctx = NULL;
+       struct ea_list *ea_list = NULL;
+       uint16 flags = 0;
        NTSTATUS status;
 
        /*
         * Ensure we have enough parameters to perform the operation.
         */
 
-       if (total_params < 29)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 29) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
+       flags = SVAL(params, 0);
        open_mode = SVAL(params, 2);
        open_attr = SVAL(params,6);
-       oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
+        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+        if (oplock_request) {
+                oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+        }
+
 #if 0
        return_additional_info = BITSETW(params,0);
        open_sattr = SVAL(params, 4);
@@ -635,7 +772,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
                return ERROR_NT(status);
        }
 
-       DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
+       DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
                fname,open_mode, open_attr, open_ofun, open_size));
 
        /* XXXX we need to handle passed times, sattr and flags */
@@ -649,13 +786,47 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
        }
 
+       /* Strange open mode mapping. */
+       if (open_ofun == 0) {
+               if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) {
+                       open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
+               }
+       }
+
+       /* Any data in this call is an EA list. */
+       if (total_data && !lp_ea_support(SNUM(conn))) {
+               return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+       }
+
+       if (total_data) {
+               if (total_data < 10) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               if (IVAL(pdata,0) > total_data) {
+                       DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
+                               IVAL(pdata,0), (unsigned int)total_data));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               ctx = talloc_init("TRANS2_OPEN_SET_EA");
+               if (!ctx) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+               ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+               if (!ea_list) {
+                       talloc_destroy(ctx);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
                oplock_request, &rmode,&smb_action);
       
        if (!fsp) {
+               talloc_destroy(ctx);
                if (open_was_deferred(SVAL(inbuf,smb_mid))) {
                        /* We have re-scheduled this call. */
-                       clear_cached_errors();
                        return -1;
                }
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@@ -666,25 +837,37 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
        mtime = sbuf.st_mtime;
        inode = sbuf.st_ino;
        if (fmode & aDIR) {
+               talloc_destroy(ctx);
                close_file(fsp,False);
                return(ERROR_DOS(ERRDOS,ERRnoaccess));
        }
 
+       if (total_data && smb_action == FILE_WAS_CREATED) {
+               status = set_ea(conn, fsp, fname, ea_list);
+               talloc_destroy(ctx);
+               if (!NT_STATUS_IS_OK(status)) {
+                       close_file(fsp,False);
+                       return ERROR_NT(status);
+               }
+       }
+
        /* Realloc the size of parameters and data we will return */
-       params = SMB_REALLOC(*pparams, 28);
-       if( params == NULL )
-               return(ERROR_DOS(ERRDOS,ERRnomem));
+       params = SMB_REALLOC(*pparams, 30);
+       if( params == NULL ) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
-       memset((char *)params,'\0',28);
+       memset((char *)params,'\0',30);
        SSVAL(params,0,fsp->fnum);
        SSVAL(params,2,fmode);
        put_dos_date2(params,4, mtime);
        SIVAL(params,8, (uint32)size);
        SSVAL(params,12,rmode);
 
-       if (oplock_request && lp_fake_oplocks(SNUM(conn)))
+       if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
                smb_action |= EXTENDED_OPLOCK_GRANTED;
+       }
 
        SSVAL(params,18,smb_action);
 
@@ -692,9 +875,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
         * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
         */
        SIVAL(params,20,inode);
+       if (flags & 8) {
+               uint32 ea_size = estimate_ea_size(conn, fsp, fname);
+               SIVAL(params, 26, ea_size);
+       }
+
        /* Send the required number of replies */
-       send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
+       send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
 
        return -1;
 }
@@ -811,7 +998,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                 BOOL dont_descend,char **ppdata, 
                                 char *base_data, int space_remaining, 
                                 BOOL *out_of_space, BOOL *got_exact_match,
-                                int *last_entry_off)
+                                int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
 {
        const char *dname;
        BOOL found = False;
@@ -832,6 +1019,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        BOOL was_8_3;
        int nt_extmode; /* Used for NT connections instead of mode */
        BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+       BOOL check_mangled_names = lp_manglednames(SNUM(conn));
 
        *fname = 0;
        *out_of_space = False;
@@ -876,7 +1064,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
                        got_match = mask_match(fname, mask, conn->case_sensitive);
 
-               if(!got_match && !mangle_is_8_3(fname, False)) {
+               if(!got_match && check_mangled_names && !mangle_is_8_3(fname, False)) {
 
                        /*
                         * It turns out that NT matches wildcards against
@@ -970,8 +1158,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
 
        switch (info_level) {
-               case SMB_INFO_STANDARD:
-                       DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
+               case SMB_FIND_INFO_STANDARD:
+                       DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
                        if(requires_resume_key) {
                                SIVAL(p,0,reskey);
                                p += 4;
@@ -1002,8 +1190,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        p += len;
                        break;
 
-               case SMB_INFO_QUERY_EA_SIZE:
-                       DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
+               case SMB_FIND_EA_SIZE:
+                       DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
                        if(requires_resume_key) {
                                SIVAL(p,0,reskey);
                                p += 4;
@@ -1039,6 +1227,63 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
                        break;
 
+               case SMB_FIND_EA_LIST:
+               {
+                       struct ea_list *file_list = NULL;
+                       size_t ea_len = 0;
+
+                       DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
+                       if (!name_list) {
+                               return False;
+                       }
+                       if(requires_resume_key) {
+                               SIVAL(p,0,reskey);
+                               p += 4;
+                       }
+                       put_dos_date2(p,l2_fdateCreation,cdate);
+                       put_dos_date2(p,l2_fdateLastAccess,adate);
+                       put_dos_date2(p,l2_fdateLastWrite,mdate);
+                       SIVAL(p,l2_cbFile,(uint32)file_size);
+                       SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
+                       SSVAL(p,l2_attrFile,mode);
+                       p += l2_cbList; /* p now points to the EA area. */
+
+                       file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
+                       name_list = ea_list_union(name_list, file_list, &ea_len);
+
+                       /* We need to determine if this entry will fit in the space available. */
+                       /* Max string size is 255 bytes. */
+                       if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
+                               /* Move the dirptr back to prev_dirpos */
+                               dptr_SeekDir(conn->dirptr, prev_dirpos);
+                               *out_of_space = True;
+                               DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
+                               return False; /* Not finished - just out of space */
+                       }
+
+                       /* Push the ea_data followed by the name. */
+                       p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
+                       nameptr = p;
+                       len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
+                       if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
+                               if (len > 2) {
+                                       len -= 2;
+                               } else {
+                                       len = 0;
+                               }
+                       } else {
+                               if (len > 1) {
+                                       len -= 1;
+                               } else {
+                                       len = 0;
+                               }
+                       }
+                       SCVAL(nameptr,0,len);
+                       p += len + 1;
+                       SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
+                       break;
+               }
+
                case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
                        DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
                        was_8_3 = mangle_is_8_3(fname, True);
@@ -1338,10 +1583,13 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
        int space_remaining;
        BOOL bad_path = False;
        SMB_STRUCT_STAT sbuf;
+       TALLOC_CTX *ea_ctx = NULL;
+       struct ea_list *ea_list = NULL;
        NTSTATUS ntstatus = NT_STATUS_OK;
 
-       if (total_params < 12)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 12) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        *directory = *mask = 0;
 
@@ -1356,8 +1604,9 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
        }
  
        switch (info_level) {
-               case SMB_INFO_STANDARD:
-               case SMB_INFO_QUERY_EA_SIZE:
+               case SMB_FIND_INFO_STANDARD:
+               case SMB_FIND_EA_SIZE:
+               case SMB_FIND_EA_LIST:
                case SMB_FIND_FILE_DIRECTORY_INFO:
                case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
                case SMB_FIND_FILE_NAMES_INFO:
@@ -1378,7 +1627,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                return ERROR_NT(ntstatus);
        }
 
-       RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
 
        unix_convert(directory,conn,0,&bad_path,&sbuf);
        if (bad_path) {
@@ -1403,29 +1652,66 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
 
        DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
 
+       if (info_level == SMB_FIND_EA_LIST) {
+               uint32 ea_size;
+
+               if (total_data < 4) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               ea_size = IVAL(pdata,0);
+               if (ea_size != total_data) {
+                       DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               if (!lp_ea_support(SNUM(conn))) {
+                       return ERROR_DOS(ERRDOS,ERReasnotsupported);
+               }
+                                                                                                                                                        
+               if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+                                                                                                                                                        
+               /* Pull out the list of names. */
+               ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+               if (!ea_list) {
+                       talloc_destroy(ea_ctx);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
-       if( pdata == NULL )
-               return(ERROR_DOS(ERRDOS,ERRnomem));
+       if( pdata == NULL ) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
 
        *ppdata = pdata;
        memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
 
        /* Realloc the params space */
        params = SMB_REALLOC(*pparams, 10);
-       if (params == NULL)
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if (params == NULL) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
        dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
-       if (dptr_num < 0)
+       if (dptr_num < 0) {
+               talloc_destroy(ea_ctx);
                return(UNIXERROR(ERRDOS,ERRbadfile));
+       }
 
        /* Save the wildcard match and attribs we are using on this directory - 
                needed as lanman2 assumes these are being saved between calls */
 
        if (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
                dptr_close(&dptr_num);
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
 
        DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
@@ -1455,7 +1741,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                                        mask,dirtype,info_level,
                                        requires_resume_key,dont_descend,
                                        &p,pdata,space_remaining, &out_of_space, &got_exact_match,
-                                       &last_entry_off);
+                                       &last_entry_off, ea_list, ea_ctx);
                }
 
                if (finished && out_of_space)
@@ -1477,6 +1763,8 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
        }
   
+       talloc_destroy(ea_ctx);
+
        /* Check if we can close the dirptr */
        if(close_after_first || (finished && close_if_end)) {
                DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
@@ -1566,10 +1854,13 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
        BOOL dont_descend = False;
        BOOL out_of_space = False;
        int space_remaining;
+       TALLOC_CTX *ea_ctx = NULL;
+       struct ea_list *ea_list = NULL;
        NTSTATUS ntstatus = NT_STATUS_OK;
 
-       if (total_params < 12)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 12) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        *mask = *directory = *resume_name = 0;
 
@@ -1600,8 +1891,9 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
        }
 
        switch (info_level) {
-               case SMB_INFO_STANDARD:
-               case SMB_INFO_QUERY_EA_SIZE:
+               case SMB_FIND_INFO_STANDARD:
+               case SMB_FIND_EA_SIZE:
+               case SMB_FIND_EA_LIST:
                case SMB_FIND_FILE_DIRECTORY_INFO:
                case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
                case SMB_FIND_FILE_NAMES_INFO:
@@ -1615,29 +1907,66 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
                        return ERROR_DOS(ERRDOS,ERRunknownlevel);
        }
 
+       if (info_level == SMB_FIND_EA_LIST) {
+               uint32 ea_size;
+
+               if (total_data < 4) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               ea_size = IVAL(pdata,0);
+               if (ea_size != total_data) {
+                       DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+                                                                                                                                                     
+               if (!lp_ea_support(SNUM(conn))) {
+                       return ERROR_DOS(ERRDOS,ERReasnotsupported);
+               }
+                                                                                                                                                     
+               if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+
+               /* Pull out the list of names. */
+               ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+               if (!ea_list) {
+                       talloc_destroy(ea_ctx);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
-       if(pdata == NULL)
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if(pdata == NULL) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
 
        *ppdata = pdata;
        memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
 
        /* Realloc the params space */
        params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
-       if( params == NULL )
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if( params == NULL ) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
 
        *pparams = params;
 
        /* Check that the dptr is valid */
-       if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
+       if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
+               talloc_destroy(ea_ctx);
                return ERROR_DOS(ERRDOS,ERRnofiles);
+       }
 
        string_set(&conn->dirpath,dptr_path(dptr_num));
 
        /* Get the wildcard mask from the dptr */
        if((p = dptr_wcard(dptr_num))== NULL) {
                DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
+               talloc_destroy(ea_ctx);
                return ERROR_DOS(ERRDOS,ERRnofiles);
        }
 
@@ -1708,7 +2037,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
                                                mask,dirtype,info_level,
                                                requires_resume_key,dont_descend,
                                                &p,pdata,space_remaining, &out_of_space, &got_exact_match,
-                                               &last_entry_off);
+                                               &last_entry_off, ea_list, ea_ctx);
                }
 
                if (finished && out_of_space)
@@ -1730,6 +2059,8 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
                space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
        }
   
+       talloc_destroy(ea_ctx);
+
        /* Check if we can close the dirptr */
        if(close_after_request || (finished && close_if_end)) {
                DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
@@ -1780,8 +2111,9 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
        }
 
        pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
-       if ( pdata == NULL )
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if ( pdata == NULL ) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
 
        *ppdata = pdata;
        memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
@@ -1830,7 +2162,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
                         * the called hostname and the service name.
                         */
                        SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
-                       len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
+                       /*
+                        * Win2k3 and previous mess this up by sending a name length
+                        * one byte short. I believe only older clients (OS/2 Win9x) use
+                        * this call so try fixing this by adding a terminating null to
+                        * the pushed string. The change here was adding the STR_TERMINATE. JRA.
+                        */
+                       len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
                        SCVAL(pdata,l2_vol_cch,len);
                        data_len = l2_vol_szVolLabel + len;
                        DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
@@ -2098,7 +2436,7 @@ static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outb
        if (total_params < 4) {
                DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
                        total_params));
-               return ERROR_DOS(ERRDOS,ERRinvalidparam);
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
        }
 
        fsp = file_fsp(params,0);
@@ -2323,17 +2661,17 @@ static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
 ****************************************************************************/
 
 static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+                                       unsigned int tran_call,
                                        char **pparams, int total_params, char **ppdata, int total_data,
                                        unsigned int max_data_bytes)
 {
        char *params = *pparams;
        char *pdata = *ppdata;
-       uint16 tran_call = SVAL(inbuf, smb_setup0);
        uint16 info_level;
        int mode=0;
        SMB_OFF_T file_size=0;
        SMB_BIG_UINT allocation_size=0;
-       unsigned int data_size;
+       unsigned int data_size = 0;
        unsigned int param_size = 2;
        SMB_STRUCT_STAT sbuf;
        pstring fname, dos_fname;
@@ -2346,6 +2684,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
        int len;
        time_t c_time;
        files_struct *fsp = NULL;
+       TALLOC_CTX *ea_ctx = NULL;
+       struct ea_list *ea_list = NULL;
        uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
 
        if (!params)
@@ -2354,8 +2694,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
        ZERO_STRUCT(sbuf);
 
        if (tran_call == TRANSACT2_QFILEINFO) {
-               if (total_params < 4)
-                       return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+               if (total_params < 4) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
 
                fsp = file_fsp(params,0);
                info_level = SVAL(params,2);
@@ -2410,8 +2751,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                NTSTATUS status = NT_STATUS_OK;
 
                /* qpathinfo */
-               if (total_params < 6)
-                       return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+               if (total_params < 6) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
 
                info_level = SVAL(params,0);
 
@@ -2463,7 +2805,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
 
        fullpathname = fname;
        file_size = get_file_size(sbuf);
-       allocation_size = get_allocation_size(conn,fsp,&sbuf);
        if (mode & aDIR) {
                /* This is necessary, as otherwise the desktop.ini file in
                 * this folder is ignored */
@@ -2471,27 +2812,58 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                file_size = 0;
        }
 
+       /* Pull any EA list from the data portion. */
+       if (info_level == SMB_INFO_QUERY_EAS_FROM_LIST) {
+               uint32 ea_size;
+
+               if (total_data < 4) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+               ea_size = IVAL(pdata,0);
+
+               if (total_data > 0 && ea_size != total_data) {
+                       DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               if (!lp_ea_support(SNUM(conn))) {
+                       return ERROR_DOS(ERRDOS,ERReasnotsupported);
+               }
+
+               if ((ea_ctx = talloc_init("ea_list")) == NULL) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+
+               /* Pull out the list of names. */
+               ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+               if (!ea_list) {
+                       talloc_destroy(ea_ctx);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
        params = SMB_REALLOC(*pparams,2);
-       if (params == NULL)
-         return ERROR_DOS(ERRDOS,ERRnomem);
+       if (params == NULL) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
        memset((char *)params,'\0',2);
        data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
        pdata = SMB_REALLOC(*ppdata, data_size); 
-       if ( pdata == NULL )
-               return ERROR_DOS(ERRDOS,ERRnomem);
-       *ppdata = pdata;
-
-       if (total_data > 0 && IVAL(pdata,0) == total_data) {
-               /* uggh, EAs for OS2 */
-               DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
-               return ERROR_DOS(ERRDOS,ERReasnotsupported);
+       if ( pdata == NULL ) {
+               talloc_destroy(ea_ctx);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
+       *ppdata = pdata;
 
        memset((char *)pdata,'\0',data_size);
 
        c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
 
+       allocation_size = get_allocation_size(conn,fsp,&sbuf);
+
        if (fsp) {
                if (fsp->pending_modtime) {
                        /* the pending modtime overrides the current modtime */
@@ -2504,6 +2876,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                        /* the pending modtime overrides the current modtime */
                        sbuf.st_mtime = fsp1->pending_modtime;
                }
+               if (fsp1 && fsp1->initial_allocation_size) {
+                       allocation_size = get_allocation_size(conn, fsp1, &sbuf);
+               }
        }
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
@@ -2560,21 +2935,51 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                        break;
                        
                case SMB_INFO_QUERY_EAS_FROM_LIST:
+               {
+                       size_t total_ea_len = 0;
+                       struct ea_list *ea_file_list = NULL;
+
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
-                       data_size = 24;
-                       put_dos_date2(pdata,0,c_time);
-                       put_dos_date2(pdata,4,sbuf.st_atime);
-                       put_dos_date2(pdata,8,sbuf.st_mtime);
-                       SIVAL(pdata,12,(uint32)file_size);
-                       SIVAL(pdata,16,(uint32)allocation_size);
-                       SIVAL(pdata,20,mode);
+
+                       ea_file_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
+                       ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+
+                       if (!ea_list || (total_ea_len > data_size)) {
+                               talloc_destroy(ea_ctx);
+                               data_size = 4;
+                               SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
+                               break;
+                       }
+
+                       data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
+                       talloc_destroy(ea_ctx);
                        break;
+               }
 
                case SMB_INFO_QUERY_ALL_EAS:
-                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+               {
                        /* We have data_size bytes to put EA's into. */
-                       data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
+                       size_t total_ea_len = 0;
+
+                       DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+
+                       ea_ctx = talloc_init("ea_ctx");
+                       if (!ea_ctx) {
+                               return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       }
+
+                       ea_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
+                       if (!ea_list || (total_ea_len > data_size)) {
+                               talloc_destroy(ea_ctx);
+                               data_size = 4;
+                               SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
+                               break;
+                       }
+
+                       data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
+                       talloc_destroy(ea_ctx);
                        break;
+               }
 
                case SMB_FILE_BASIC_INFORMATION:
                case SMB_QUERY_FILE_BASIC_INFO:
@@ -3153,12 +3558,12 @@ NTSTATUS hardlink_internals(connection_struct *conn, char *oldname, char *newnam
 ****************************************************************************/
 
 static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+                                       unsigned int tran_call,
                                        char **pparams, int total_params, char **ppdata, int total_data,
                                        unsigned int max_data_bytes)
 {
        char *params = *pparams;
        char *pdata = *ppdata;
-       uint16 tran_call = SVAL(inbuf, smb_setup0);
        uint16 info_level;
        int dosmode=0;
        SMB_OFF_T size=0;
@@ -3177,10 +3582,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
        ZERO_STRUCT(sbuf);
+       ZERO_STRUCT(tvs);
 
        if (tran_call == TRANSACT2_SETFILEINFO) {
-               if (total_params < 4)
-                       return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+               if (total_params < 4) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
 
                fsp = file_fsp(params,0);
                info_level = SVAL(params,2);    
@@ -3226,8 +3633,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                }
        } else {
                /* set path info */
-               if (total_params < 6)
-                       return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+               if (total_params < 6) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
 
                info_level = SVAL(params,0);    
                srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
@@ -3266,10 +3674,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
        DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
                tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
 
-       /* Realloc the parameter and data sizes */
+       /* Realloc the parameter size */
        params = SMB_REALLOC(*pparams,2);
-       if(params == NULL)
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if(params == NULL) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
        SSVAL(params,0,0);
@@ -3291,8 +3700,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
        switch (info_level) {
                case SMB_INFO_STANDARD:
                {
-                       if (total_data < 12)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 12) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        /* access time */
                        tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
@@ -3302,17 +3712,50 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                }
 
                case SMB_INFO_SET_EA:
-                       status = set_ea(conn, fsp, fname, pdata, total_data);
-                       if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
+               {
+                       struct ea_list *ea_list = NULL;
+                       TALLOC_CTX *ctx = NULL;
+
+                       if (total_data < 10) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
+
+                       if (IVAL(pdata,0) > total_data) {
+                               DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
+                                       IVAL(pdata,0), (unsigned int)total_data));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
+
+                       ctx = talloc_init("SMB_INFO_SET_EA");
+                       if (!ctx) {
+                               return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       }
+                       ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+                       if (!ea_list) {
+                               talloc_destroy(ctx);
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
+                       status = set_ea(conn, fsp, fname, ea_list);
+                       talloc_destroy(ctx);
+
+                       if (!NT_STATUS_IS_OK(status)) {
                                return ERROR_NT(status);
-                       break;
+                       }
 
+                       /* We're done. We only get EA info in this call. */
+                       SSVAL(params,0,0);
+                       send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+                       return(-1);
+               }
+
+#if 0
+               /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
                /* XXXX um, i don't think this is right.
                        it's also not in the cifs6.txt spec.
                */
                case SMB_INFO_QUERY_EAS_FROM_LIST:
                        if (total_data < 28)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
                        tvs.actime = make_unix_date2(pdata+8);
                        tvs.modtime = make_unix_date2(pdata+12);
@@ -3323,13 +3766,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                /* XXXX nor this.  not in cifs6.txt, either. */
                case SMB_INFO_QUERY_ALL_EAS:
                        if (total_data < 28)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
                        tvs.actime = make_unix_date2(pdata+8);
                        tvs.modtime = make_unix_date2(pdata+12);
                        size = IVAL(pdata,16);
                        dosmode = IVAL(pdata,24);
                        break;
+#endif
 
                case SMB_SET_FILE_BASIC_INFO:
                case SMB_FILE_BASIC_INFORMATION:
@@ -3338,8 +3782,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                        time_t write_time;
                        time_t changed_time;
 
-                       if (total_data < 36)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 36) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        /* Ignore create time at offset pdata. */
 
@@ -3370,8 +3815,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                        int ret = -1;
                        SMB_BIG_UINT allocation_size;
 
-                       if (total_data < 8)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 8) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
 #ifdef LARGE_SMB_OFF_T
@@ -3444,8 +3890,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                case SMB_FILE_END_OF_FILE_INFORMATION:
                case SMB_SET_FILE_END_OF_FILE_INFO:
                {
-                       if (total_data < 8)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 8) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        size = IVAL(pdata,0);
 #ifdef LARGE_SMB_OFF_T
@@ -3463,8 +3910,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                {
                        BOOL delete_on_close;
 
-                       if (total_data < 1)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 1) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        delete_on_close = (CVAL(pdata,0) ? True : False);
 
@@ -3477,23 +3925,28 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
 
                        status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
  
-                       if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
+                       if (!NT_STATUS_IS_OK(status)) {
                                return ERROR_NT(status);
+                       }
 
                        /* The set is across all open files on this dev/inode pair. */
                        status =set_delete_on_close_over_all(fsp, delete_on_close);
-                       if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
+                       if (!NT_STATUS_IS_OK(status)) {
                                return ERROR_NT(status);
+                       }
 
-                       break;
+                       SSVAL(params,0,0);
+                       send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+                       return(-1);
                }
 
                case SMB_FILE_POSITION_INFORMATION:
                {
                        SMB_BIG_UINT position_information;
 
-                       if (total_data < 8)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 8) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        position_information = (SMB_BIG_UINT)IVAL(pdata,0);
 #ifdef LARGE_SMB_OFF_T
@@ -3504,9 +3957,38 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
 #endif /* LARGE_SMB_OFF_T */
                        DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
                                        fname, (double)position_information ));
-                       if (fsp)
+                       if (fsp) {
                                fsp->position_information = position_information;
-                       break;
+                       }
+
+                       /* We're done. We only get position info in this call. */
+                       SSVAL(params,0,0);
+                       send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+                       return(-1);
+               }
+
+               /* From tridge Samba4 : 
+                * MODE_INFORMATION in setfileinfo (I have no
+                * idea what "mode information" on a file is - it takes a value of 0,
+                * 2, 4 or 6. What could it be?).
+                */
+
+               case SMB_FILE_MODE_INFORMATION:
+               {
+                       uint32 mode;
+
+                       if (total_data < 4) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
+                       mode = IVAL(pdata,0);
+                       if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
+
+                       /* We're done. We only get mode info in this call. */
+                       SSVAL(params,0,0);
+                       send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+                       return(-1);
                }
 
                /*
@@ -3517,8 +3999,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                {
                        uint32 raw_unixmode;
 
-                       if (total_data < 100)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 100) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
                           IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
@@ -3567,8 +4050,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                                if (tran_call == TRANSACT2_SETFILEINFO)
                                        return(ERROR_DOS(ERRDOS,ERRnoaccess));
 
-                               if (raw_unixmode == SMB_MODE_NO_CHANGE)
-                                       return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               if (raw_unixmode == SMB_MODE_NO_CHANGE) {
+                                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                               }
 
 #if defined(HAVE_MAKEDEV)
                                dev = makedev(dev_major, dev_minor);
@@ -3736,8 +4220,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        pstring base_name;
                        char *p;
 
-                       if (total_data < 12)
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                       if (total_data < 12) {
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       }
 
                        overwrite = (CVAL(pdata,0) ? True : False);
                        root_fid = IVAL(pdata,4);
@@ -3790,7 +4275,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        BOOL valid_def_acls = True;
 
                        if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                        }
                        posix_acl_version = SVAL(pdata,0);
                        num_file_acls = SVAL(pdata,2);
@@ -3807,12 +4292,12 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        }
 
                        if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                        }
 
                        if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
                                        (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
-                               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+                               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                        }
 
                        if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
@@ -3971,17 +4456,21 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
                                        unsigned int max_data_bytes)
 {
        char *params = *pparams;
+       char *pdata = *ppdata;
        pstring directory;
        int ret = -1;
        SMB_STRUCT_STAT sbuf;
        BOOL bad_path = False;
        NTSTATUS status = NT_STATUS_OK;
+       TALLOC_CTX *ctx = NULL;
+       struct ea_list *ea_list = NULL;
 
        if (!CAN_WRITE(conn))
                return ERROR_DOS(ERRSRV,ERRaccess);
 
-       if (total_params < 4)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 4) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
        if (!NT_STATUS_IS_OK(status)) {
@@ -3994,18 +4483,58 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
        if (bad_path) {
                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
        }
-       if (check_name(directory,conn))
+
+       /* Any data in this call is an EA list. */
+       if (total_data && !lp_ea_support(SNUM(conn))) {
+               return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+       }
+
+       if (total_data) {
+               if (total_data < 10) {
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               if (IVAL(pdata,0) > total_data) {
+                       DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
+                               IVAL(pdata,0), (unsigned int)total_data));
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+
+               ctx = talloc_init("TRANS2_MKDIR_SET_EA");
+               if (!ctx) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
+               ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+               if (!ea_list) {
+                       talloc_destroy(ctx);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               }
+       }
+
+       if (check_name(directory,conn)) {
                ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
+       }
   
        if(ret < 0) {
+               talloc_destroy(ctx);
                DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
                return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
        }
 
+       /* Try and set any given EA. */
+       if (total_data) {
+               status = set_ea(conn, NULL, directory, ea_list);
+               talloc_destroy(ctx);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return ERROR_NT(status);
+               }
+       }
+
        /* Realloc the parameter and data sizes */
        params = SMB_REALLOC(*pparams,2);
-       if(params == NULL)
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if(params == NULL) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
        SSVAL(params,0,0);
@@ -4028,8 +4557,9 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
        char *params = *pparams;
        uint16 info_level;
 
-       if (total_params < 6)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 6) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        info_level = SVAL(params,4);
        DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
@@ -4044,8 +4574,9 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
 
        /* Realloc the parameter and data sizes */
        params = SMB_REALLOC(*pparams,6);
-       if(params == NULL) 
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if(params == NULL) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
        SSVAL(params,0,fnf_handle);
@@ -4077,8 +4608,9 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char
 
        /* Realloc the parameter and data sizes */
        params = SMB_REALLOC(*pparams,4);
-       if(params == NULL)
-               return ERROR_DOS(ERRDOS,ERRnomem);
+       if(params == NULL) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       }
        *pparams = params;
 
        SSVAL(params,0,0); /* No changes */
@@ -4104,8 +4636,9 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
 
        DEBUG(10,("call_trans2getdfsreferral\n"));
 
-       if (total_params < 2)
-               return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+       if (total_params < 2) {
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       }
 
        max_referral_level = SVAL(params,0);
 
@@ -4144,8 +4677,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf,
        if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
                        (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
                pdata = SMB_REALLOC(*ppdata, 32);
-               if(pdata == NULL)
-                       return ERROR_DOS(ERRDOS,ERRnomem);
+               if(pdata == NULL) {
+                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+               }
                *ppdata = pdata;
 
                /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
@@ -4288,7 +4822,7 @@ int reply_trans2(connection_struct *conn,
                        DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
                        DEBUG(2,("Transaction is %d\n",tran_call));
                        END_PROFILE(SMBtrans2);
-                       ERROR_DOS(ERRDOS,ERRinvalidparam);
+                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                }
        }
     
@@ -4303,7 +4837,7 @@ int reply_trans2(connection_struct *conn,
                SAFE_FREE(params);
                SAFE_FREE(data); 
                END_PROFILE(SMBtrans2);
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
 
        /* Copy the param and data bytes sent with this request into
@@ -4352,6 +4886,9 @@ int reply_trans2(connection_struct *conn,
                        unsigned int data_off;
 
                        ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+                       /* We need to re-calcuate the new length after we've read the secondary packet. */
+                       length = smb_len(inbuf) + 4;
                        
                        /*
                         * The sequence number for the trans reply is always
@@ -4399,7 +4936,7 @@ int reply_trans2(connection_struct *conn,
                                        goto bad_param;
                                if (param_disp > total_params)
                                        goto bad_param;
-                               if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
+                               if ((smb_base(inbuf) + param_off + num_params > inbuf + length) ||
                                                (smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
                                        goto bad_param;
                                if (params + param_disp < params)
@@ -4415,7 +4952,7 @@ int reply_trans2(connection_struct *conn,
                                        goto bad_param;
                                if (data_disp > total_data)
                                        goto bad_param;
-                               if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
+                               if ((smb_base(inbuf) + data_off + num_data > inbuf + length) ||
                                                (smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
                                        goto bad_param;
                                if (data + data_disp < data)
@@ -4471,14 +5008,14 @@ int reply_trans2(connection_struct *conn,
        case TRANSACT2_QPATHINFO:
        case TRANSACT2_QFILEINFO:
                START_PROFILE_NESTED(Trans2_qpathinfo);
-               outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize, 
+               outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize, tran_call,
                                          &params, total_params, &data, total_data, max_data_bytes);
                END_PROFILE_NESTED(Trans2_qpathinfo);
                break;
        case TRANSACT2_SETPATHINFO:
        case TRANSACT2_SETFILEINFO:
                START_PROFILE_NESTED(Trans2_setpathinfo);
-               outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize, 
+               outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize, tran_call,
                                          &params, total_params, &data, total_data, max_data_bytes);
                END_PROFILE_NESTED(Trans2_setpathinfo);
                break;
index bf60c2bc68c96d4f20d29fcf6c9c3d1e2d5b30e2..edcc7a5c2f958568b4a0724d76715acf3646c12b 100644 (file)
@@ -1224,7 +1224,7 @@ a wrapper for lseek()
 off_t smbw_lseek(int fd, off_t offset, int whence)
 {
        struct smbw_file *file;
-       size_t size;
+       SMB_OFF_T size;
 
        smbw_busy++;
 
index bb76ef006a442fc2f3818126b0838cf7478d2c2c..6effc9a71bcfa85f2bc0fbf90673b296690c4991 100644 (file)
@@ -69,17 +69,33 @@ BOOL smbw_getatr(struct smbw_server *srv, char *path,
                 time_t *c_time, time_t *a_time, time_t *m_time,
                 SMB_INO_T *ino)
 {
+        time_t c_a_m_time;
+        /*
+         * "size" (size_t) is only 32 bits.  Rather than change the interface
+         * in this code as we change cli_qpathinfo2() and cli_getatr() to
+         * support 64-bit file sizes, we'll use a temporary variable and
+         * maintain the interface size_t.  At some point, someone may want to
+         * change the interface as well.  djl
+         */
+        SMB_OFF_T fullsize;
+
        DEBUG(4,("sending qpathinfo\n"));
 
        if (!srv->no_pathinfo2 &&
            cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
-                          size, mode, ino)) return True;
+                          &fullsize, mode, ino)) {
+                if (size != NULL) *size = (size_t) fullsize;
+                return True;
+        }
 
        /* if this is NT then don't bother with the getatr */
        if (srv->cli.capabilities & CAP_NT_SMBS) return False;
 
-       if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
-               a_time = c_time = m_time;
+       if (cli_getatr(&srv->cli, path, mode, &fullsize, &c_a_m_time)) {
+                if (a_time != NULL) *a_time = c_a_m_time;
+                if (c_time != NULL) *a_time = c_a_m_time;
+                if (m_time != NULL) *a_time = c_a_m_time;
+                if (size != NULL) *size = (size_t) fullsize;
                srv->no_pathinfo2 = True;
                return True;
        }
@@ -129,7 +145,7 @@ int smbw_fstat(int fd, struct stat *st)
 {
        struct smbw_file *file;
        time_t c_time, a_time, m_time;
-       size_t size;
+       SMB_OFF_T size;
        uint16 mode;
        SMB_INO_T ino = 0;
 
index f66e50afe46ecd7c05339c43de4f76ef8bc5773b..7159550c0c2b79e94001589b26a1ecbb58f0490a 100644 (file)
 
 /* free memory if the pointer is valid and zero the pointer */
 #ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(CONST_DISCARD(void *, (x))); (x)=NULL;} } while(0)
 #endif
 
 #define BUCKET(hash) ((hash) % tdb->header.hash_size)
index 1a0e1c1588fdc4affd532ae7c699c6f1e6a35d91..f49cd339c79ff256d8c12b003a6f4a4299e2da0c 100644 (file)
@@ -69,6 +69,9 @@
 #include "tdb.h"
 #include "tdbback.h"
 
+extern int optind;
+extern char *optarg;
+
 /*
   see if one file is newer than another
 */
@@ -100,8 +103,6 @@ static void usage(void)
        int c;
        int verify = 0;
        const char *suffix = ".bak";
-       extern int optind;
-       extern char *optarg;
 
        while ((c = getopt(argc, argv, "vhs:")) != -1) {
                switch (c) {
index 92009dcef48cbd435dfa2e28d4c629ad946486b8..2de3df961cf75d2a82a0a5ed7d5b1b375fa7c203 100644 (file)
@@ -131,7 +131,7 @@ static void help(void)
 "\n");
 }
 
-static void terror(char *why)
+static void terror(const char *why)
 {
        printf("%s\n", why);
 }
@@ -407,7 +407,7 @@ static void info_tdb(void)
                printf("%d records totalling %d bytes\n", count, total_bytes);
 }
 
-static char *tdb_getline(char *prompt)
+static char *tdb_getline(const char *prompt)
 {
        static char line[1024];
        char *p;
index 45ebdae3af04384250ffb95b0c3f8645a325f330..4fcfb6185aefb6c8352c7d0e2a418e9247760c8a 100644 (file)
@@ -40,14 +40,19 @@ static void gotalarm_sig(void)
  Make a TDB_DATA and keep the const warning in one place
 ****************************************************************/
 
-static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
+TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
 {
        TDB_DATA ret;
-       ret.dptr = dptr;
+       ret.dptr = CONST_DISCARD(char *, dptr);
        ret.dsize = dsize;
        return ret;
 }
 
+TDB_DATA string_tdb_data(const char *string)
+{
+       return make_tdb_data(string, strlen(string));
+}
+
 /****************************************************************************
  Lock a chain with timeout (in seconds).
 ****************************************************************************/
@@ -57,7 +62,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
        /* Allow tdb_chainlock to be interrupted by an alarm. */
        int ret;
        gotalarm = 0;
-       tdb_set_lock_alarm(&gotalarm);
+       tdb_set_lock_alarm(CONST_DISCARD(sig_atomic_t *, &gotalarm));
 
        if (timeout) {
                CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
index 2aa643326c0622925a0c1a7fb8b250bdde405f91..48a34feb13e8703ba0e42a6d0a99ecd3670273f7 100644 (file)
@@ -1,5 +1,7 @@
 /* this test should find out what quota api is available on the os */
 
+ int autoconf_quota(void);
+
 #if defined(HAVE_QUOTACTL_4A)
 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
 
index b37a30cf2e39ad90ec90ed699a5786263481bb36..8a4de57e7ffa45724b4e1eedc48b7b94bbba4d58 100644 (file)
@@ -590,7 +590,7 @@ static BOOL run_readwritelarge(int dummy)
        static struct cli_state *cli1;
        int fnum1;
        const char *lockfname = "\\large.dat";
-       size_t fsize;
+       SMB_OFF_T fsize;
        char buf[126*1024];
        BOOL correct = True;
  
@@ -2360,7 +2360,7 @@ static BOOL run_trans2test(int dummy)
 {
        struct cli_state *cli;
        int fnum;
-       size_t size;
+       SMB_OFF_T size;
        time_t c_time, a_time, m_time, w_time, m_time2;
        const char *fname = "\\trans2.tst";
        const char *dname = "\\trans2";
@@ -3591,7 +3591,7 @@ static BOOL run_opentest(int dummy)
        const char *fname = "\\readonly.file";
        int fnum1, fnum2;
        char buf[20];
-       size_t fsize;
+       SMB_OFF_T fsize;
        BOOL correct = True;
        char *tmp_path;
 
index ba803a0da4fabf980387367e62b524e7ca8ab141..c9b30f06e1cdc1b3c61061b857cbf7bb7e63176b 100644 (file)
@@ -137,7 +137,7 @@ BOOL torture_casetable(int dummy)
        }
 
        for (c=1; c < 0x10000; c++) {
-               size_t size;
+               SMB_OFF_T size;
 
                if (c == '.' || c == '\\') continue;
 
index 9c05828357c15f90d6f35ca844f502a7767afda7..61c366710c66a4f48cb46e68e342f01e20f0af38 100644 (file)
@@ -87,6 +87,7 @@ const char *opt_destination = NULL;
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
+extern struct in_addr loopback_ip;
 extern BOOL AllowDebugChange;
 
 uint32 get_sec_channel_type(const char *param) 
@@ -321,7 +322,6 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
                }
                *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
-               extern struct in_addr loopback_ip;
                *server_ip = loopback_ip;
                *server_name = SMB_STRDUP("127.0.0.1");
        }
@@ -632,62 +632,38 @@ static int net_afs(int argc, const char **argv)
 
 #endif /* WITH_FAKE_KASERVER */
 
-static uint32 get_maxrid(void)
+static BOOL search_maxrid(struct pdb_search *search, const char *type,
+                         uint32 *max_rid)
 {
-       SAM_ACCOUNT *pwd = NULL;
-       uint32 max_rid = 0;
-       GROUP_MAP *map = NULL;
-       int num_entries = 0;
-       int i;
-
-       if (!pdb_setsampwent(False, 0)) {
-               DEBUG(0, ("get_maxrid: Unable to open passdb.\n"));
-               return 0;
-       }
+       struct samr_displayentry *entries;
+       uint32 i, num_entries;
 
-       for (; (NT_STATUS_IS_OK(pdb_init_sam(&pwd))) 
-                    && pdb_getsampwent(pwd) == True; pwd=NULL) {
-               uint32 rid;
-
-               if (!sid_peek_rid(pdb_get_user_sid(pwd), &rid)) {
-                       DEBUG(0, ("can't get RID for user '%s'\n",
-                                 pdb_get_username(pwd)));
-                       pdb_free_sam(&pwd);
-                       continue;
-               }
-
-               if (rid > max_rid)
-                       max_rid = rid;
-
-               DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd)));
-               pdb_free_sam(&pwd);
+       if (search == NULL) {
+               d_printf("get_maxrid: Could not search %s\n", type);
+               return False;
        }
 
-       pdb_endsampwent();
-       pdb_free_sam(&pwd);
-
-       if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
-                                   ENUM_ONLY_MAPPED))
-               return max_rid;
-
-       for (i = 0; i < num_entries; i++) {
-               uint32 rid;
+       num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
+       for (i=0; i<num_entries; i++)
+               *max_rid = MAX(*max_rid, entries[i].rid);
+       pdb_search_destroy(search);
+       return True;
+}
 
-               if (!sid_peek_check_rid(get_global_sam_sid(), &map[i].sid,
-                                       &rid)) {
-                       DEBUG(3, ("skipping map for group '%s', SID %s\n",
-                                 map[i].nt_name,
-                                 sid_string_static(&map[i].sid)));
-                       continue;
-               }
-               DEBUG(1,("%d is group '%s'\n", rid, map[i].nt_name));
+static uint32 get_maxrid(void)
+{
+       uint32 max_rid = 0;
 
-               if (rid > max_rid)
-                       max_rid = rid;
-       }
+       if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
+               return 0;
 
-       SAFE_FREE(map);
+       if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
+               return 0;
 
+       if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
+                          "aliases", &max_rid))
+               return 0;
+       
        return max_rid;
 }
 
index 9c00f05bfbb7441e7ef7d372668f593d055c1958..34a357cd46d2f3c86b76866ef3174adf6cdd522b 100644 (file)
@@ -81,7 +81,7 @@ static int net_ads_lookup(int argc, const char **argv)
                d_printf("Didn't find the cldap server!\n");
                return -1;
        } if (!ads->config.realm) {
-               ads->config.realm = opt_target_workgroup;
+                ads->config.realm = CONST_DISCARD(char *, opt_target_workgroup);
                ads->ldap_port = 389;
        }
 
@@ -1168,7 +1168,7 @@ static int net_ads_password(int argc, const char **argv)
        }
 
        if (argv[1]) {
-               new_password = (char *)argv[1];
+               new_password = CONST_DISCARD(char *, argv[1]);
        } else {
                asprintf(&prompt, "Enter new password for %s:", user);
                new_password = getpass(prompt);
index a63e8176f8a9e03cfc97ce3974febadecc509065..b20a37c7267dd866dcba426edc19f33c5416707c 100644 (file)
@@ -693,12 +693,37 @@ static int net_groupmap_listmem(int argc, const char **argv)
        return 0;
 }
 
+static BOOL print_alias_memberships(TALLOC_CTX *mem_ctx,
+                                   const DOM_SID *domain_sid,
+                                   const DOM_SID *member)
+{
+       uint32 *alias_rids;
+       int i, num_alias_rids;
+
+       alias_rids = NULL;
+       num_alias_rids = 0;
+
+       if (!pdb_enum_alias_memberships(mem_ctx, domain_sid, member, 1,
+                                       &alias_rids, &num_alias_rids)) {
+               d_printf("Could not list memberships for sid %s\n",
+                        sid_string_static(member));
+               return False;
+       }
+
+       for (i = 0; i < num_alias_rids; i++) {
+               DOM_SID alias;
+               sid_copy(&alias, domain_sid);
+               sid_append_rid(&alias, alias_rids[i]);
+               printf("%s\n", sid_string_static(&alias));
+       }
+
+       return True;
+}
+
 static int net_groupmap_memberships(int argc, const char **argv)
 {
-       DOM_SID member;
-       DOM_SID *aliases;
-       int i, num;
-       NTSTATUS result;
+       TALLOC_CTX *mem_ctx;
+       DOM_SID *domain_sid, *builtin_sid, member;
 
        if ( (argc != 1) || 
             !string_to_sid(&member, argv[0]) ) {
@@ -706,17 +731,24 @@ static int net_groupmap_memberships(int argc, const char **argv)
                return -1;
        }
 
-       if (!pdb_enum_alias_memberships(&member, 1, &aliases, &num)) {
-               d_printf("Could not list memberships for sid %s: %s\n",
-                        argv[0], nt_errstr(result));
+       mem_ctx = talloc_init("net_groupmap_memberships");
+       if (mem_ctx == NULL) {
+               d_printf("talloc_init failed\n");
                return -1;
        }
 
-       for (i = 0; i < num; i++) {
-               printf("%s\n", sid_string_static(&(aliases[i])));
+       domain_sid = get_global_sam_sid();
+       builtin_sid = string_sid_talloc(mem_ctx, "S-1-5-32");
+       if ((domain_sid == NULL) || (builtin_sid == NULL)) {
+               d_printf("Could not get domain sid\n");
+               return -1;
        }
 
-       SAFE_FREE(aliases);
+       if (!print_alias_memberships(mem_ctx, domain_sid, &member) ||
+           !print_alias_memberships(mem_ctx, builtin_sid, &member))
+               return -1;
+
+       talloc_destroy(mem_ctx);
 
        return 0;
 }
index 7e5f12da4541719632e148b0024c53bc1c67b2f8..9ddfe62508129681ee149125038ac555ed86376f 100644 (file)
@@ -193,7 +193,7 @@ static int net_lookup_kdc(int argc, const char **argv)
        }
 
        if (argc>0) {
-               realm.data = (krb5_pointer) argv[0];
+                realm.data = CONST_DISCARD(krb5_pointer, argv[0]);
                realm.length = strlen(argv[0]);
        } else if (lp_realm() && *lp_realm()) {
                realm.data = (krb5_pointer) lp_realm();
@@ -209,7 +209,7 @@ static int net_lookup_kdc(int argc, const char **argv)
                realm.length = strlen(realm.data);
        }
 
-       rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0);
+       rc = krb5_locate_kdc(ctx, &realm, (struct sockaddr **) &addrs, &num_kdcs, 0);
        if (rc) {
                DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
                return -1;
index 6e8f0d088dafc4d24f20cf1deb00912688629674..8205fe3fda9a4e8721df09779f790a0f49b78bb7 100644 (file)
@@ -589,9 +589,7 @@ static int net_rap_user_usage(int argc, const char **argv)
        return net_help_user(argc, argv);
 } 
        
-static void user_fn(const char *user_name, const char *comment,
-                   const char * home_dir, const char * logon_script,
-                   void *state)
+static void user_fn(const char *user_name, void *state)
 {
        d_printf("%-21.21s\n", user_name);
 }
@@ -696,7 +694,7 @@ int net_rap_user(int argc, const char **argv)
                        cli_shutdown(cli);
                        goto done;
                }
-               ret = cli_RNetUserEnum(cli, user_fn, NULL); 
+               ret = cli_RNetUserEnum0(cli, user_fn, NULL); 
                cli_shutdown(cli);
                goto done;
        }
@@ -721,7 +719,7 @@ static void long_group_fn(const char *group_name, const char *comment,
        d_printf("%-21.21s %s\n", group_name, comment);
 }
 
-static void group_fn(const char *group_name, const char *comment, void *state)
+static void group_fn(const char *group_name, void *state)
 {
        d_printf("%-21.21s\n", group_name);
 }
@@ -787,7 +785,7 @@ int net_rap_group(int argc, const char **argv)
                        cli_shutdown(cli);
                        return ret;
                }
-               ret = cli_RNetGroupEnum(cli, group_fn, NULL); 
+               ret = cli_RNetGroupEnum0(cli, group_fn, NULL); 
                cli_shutdown(cli);
                return ret;
        }
@@ -912,6 +910,12 @@ static int rap_service_stop(int argc, const char **argv)
        return errmsg_not_implemented();
 }
 
+static void service_fn(const char *service_name, const char *dummy,
+                      void *state)
+{
+       d_printf("%-21.21s\n", service_name);
+}
+
 int net_rap_service(int argc, const char **argv)
 {
        struct functable func[] = {
@@ -931,7 +935,7 @@ int net_rap_service(int argc, const char **argv)
                        d_printf("-----------------------------\n");
                        ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
                }
-               ret = cli_RNetServiceEnum(cli, group_fn, NULL); 
+               ret = cli_RNetServiceEnum(cli, service_fn, NULL); 
                cli_shutdown(cli);
                return ret;
        }
index 27cc2a091864d2b72b3561001b6c03d664fff8de..6e884c24dfbd33ce0ecfb96028ad81ab1549d88a 100644 (file)
@@ -1909,7 +1909,6 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
        struct acct_info *groups;
-       DOM_SID global_sid_Builtin;
        BOOL global = False;
        BOOL local = False;
        BOOL builtin = False;
@@ -1931,8 +1930,6 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
                        builtin = True;
        }
 
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
        /* Get sam policy handle */
        
        result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
@@ -2702,6 +2699,11 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
                    strequal(netname,"global")) 
                        continue;
 
+               if (opt_exclude && in_list(netname, opt_exclude, False)) {
+                       printf("excluding  [%s]\n", netname);
+                       continue;
+               } 
+
                /* only work with file-shares */
                if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
                        d_printf("skipping   [%s]: not a file share.\n", netname);
@@ -2971,7 +2973,7 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
                        continue;
                }
 
-               if (opt_exclude && in_list(netname, (char *)opt_exclude, False)) {
+               if (opt_exclude && in_list(netname, opt_exclude, False)) {
                        printf("excluding  [%s]\n", netname);
                        continue;
                } 
@@ -3273,7 +3275,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
 {
        NTSTATUS result;
        POLICY_HND connect_pol;
-       DOM_SID global_sid_Builtin;
 
        result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
                                  &connect_pol);
@@ -3281,8 +3282,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
        if (!NT_STATUS_IS_OK(result))
                goto done;
        
-       string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
        result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
                                          &global_sid_Builtin);
 
@@ -3299,14 +3298,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
 
 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
 {
-       DOM_SID global_sid_World;
-       DOM_SID global_sid_Network;
-       DOM_SID global_sid_Authenticated_Users;
-
-       string_to_sid(&global_sid_World, "S-1-1-0");
-       string_to_sid(&global_sid_Network, "S-1-5-2");
-       string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
-
        token->num_sids = 4;
 
        token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4);
@@ -4472,6 +4463,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
        POLICY_HND connect_pol, domain_pol, user_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        char *acct_name;
+       const char **names;
        DOM_SID trust_acct_sid;
        uint32 *user_rids, num_rids, *name_types;
        uint32 flags = 0x000003e8; /* Unknown */
@@ -4484,13 +4476,17 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
        /* 
         * Make valid trusting domain account (ie. uppercased and with '$' appended)
         */
-        
-       if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
+       acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
+
+       if (acct_name == NULL)
                return NT_STATUS_NO_MEMORY;
-       }
 
        strupper_m(acct_name);
 
+       names = TALLOC_ARRAY(mem_ctx, const char *, 1);
+       names[0] = acct_name;
+
+
        /* Get samr policy handle */
        result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
                                  &connect_pol);
@@ -4507,8 +4503,8 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
        }
 
        result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, 1,
-                                      &acct_name, &num_rids, &user_rids,
-                                      &name_types);
+                                      names, &num_rids,
+                                      &user_rids, &name_types);
        
        if (!NT_STATUS_IS_OK(result)) {
                goto done;
@@ -4552,7 +4548,6 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
        }
 
  done:
-       SAFE_FREE(acct_name);
        return result;
 }
 
@@ -4594,7 +4589,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
        TALLOC_CTX *mem_ctx;
        NTSTATUS nt_status;
        DOM_SID *domain_sid;
-       WKS_INFO_100 wks_info;
+       smb_ucs2_t *uni_domain_name;
        
        char* domain_name;
        char* domain_name_pol;
@@ -4663,44 +4658,17 @@ static int rpc_trustdom_establish(int argc, const char **argv)
                         for domain %s\n", domain_name));
        }
         
-       /*
-        * Call WksQueryInfo to check remote server's capabilities
-        * note: It is now used only to get unicode domain name
-        */
-       
-       if (!cli_nt_session_open(cli, PI_WKSSVC)) {
-               DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
-               return -1;
-       }
-
-       if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
-                       domain_name))) {
+       if (!(mem_ctx = talloc_init("establishing trust relationship to "
+                                   "domain %s", domain_name))) {
                DEBUG(0, ("talloc_init() failed\n"));
                cli_shutdown(cli);
                return -1;
        }
        
-       nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
-       
-       if (NT_STATUS_IS_ERR(nt_status)) {
-               DEBUG(0, ("WksQueryInfo call failed.\n"));
-               return -1;
-       }
-
-       if (cli->nt_pipe_fnum[cli->pipe_idx])
-               cli_nt_session_close(cli);
-
-
        /*
         * Call LsaOpenPolicy and LsaQueryInfo
         */
         
-       if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
-               DEBUG(0, ("talloc_init() failed\n"));
-               cli_shutdown(cli);
-               return -1;
-       }
-
        if (!cli_nt_session_open(cli, PI_LSARPC)) {
                DEBUG(0, ("Could not initialise lsa pipe\n"));
                cli_shutdown(cli);
@@ -4718,16 +4686,19 @@ static int rpc_trustdom_establish(int argc, const char **argv)
        /* Querying info level 5 */
        
        nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
-                                             5 /* info level */, &domain_name_pol,
-                                             &domain_sid);
+                                             5 /* info level */,
+                                             &domain_name_pol, &domain_sid);
        if (NT_STATUS_IS_ERR(nt_status)) {
                DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
                        nt_errstr(nt_status)));
                return -1;
        }
 
-
-
+       if (push_ucs2_talloc(mem_ctx, &uni_domain_name, domain_name_pol) < 0) {
+               DEBUG(0, ("Could not convert domain name %s to unicode\n",
+                         domain_name_pol));
+               return -1;
+       }
 
        /* There should be actually query info level 3 (following nt serv behaviour),
           but I still don't know if it's _really_ necessary */
@@ -4736,8 +4707,10 @@ static int rpc_trustdom_establish(int argc, const char **argv)
         * Store the password in secrets db
         */
 
-       if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
-                                                  wks_info.uni_lan_grp.uni_str_len, opt_password,
+       if (!secrets_store_trusted_domain_password(domain_name,
+                                                  uni_domain_name,
+                                                  strlen_w(uni_domain_name)+1,
+                                                  opt_password,
                                                   *domain_sid)) {
                DEBUG(0, ("Storing password for trusted domain failed.\n"));
                return -1;
@@ -4756,6 +4729,8 @@ static int rpc_trustdom_establish(int argc, const char **argv)
 
        if (cli->nt_pipe_fnum[cli->pipe_idx])
                cli_nt_session_close(cli);
+
+       cli_shutdown(cli);
         
        talloc_destroy(mem_ctx);
         
@@ -5583,6 +5558,7 @@ int net_rpc(int argc, const char **argv)
                {"vampire", rpc_vampire},
                {"getsid", net_rpc_getsid},
                {"rights", net_rpc_rights},
+               {"service", net_rpc_service},
                {"help", net_rpc_help},
                {NULL, NULL}
        };
index 32cb6a4650b7499a79c635cf7283d807929de790..3a986ed2516d13ee5a63bf533cbb84af1af9c9f9 100644 (file)
@@ -133,6 +133,36 @@ static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
 /********************************************************************
 ********************************************************************/
 
+static NTSTATUS check_privilege_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
+                                          POLICY_HND *pol, DOM_SID *sid, const char *right)
+{
+       NTSTATUS result;
+       uint32 count;
+       char **rights;
+       int i;
+
+       result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
+
+       if (count == 0) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+               
+       for (i = 0; i < count; i++) {
+               if (StrCaseCmp(rights[i], right) == 0) {
+                       return NT_STATUS_OK;
+               }
+       }
+
+       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+}
+
+/********************************************************************
+********************************************************************/
+
 static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
                                           POLICY_HND *pol, DOM_SID *sid )
 {
@@ -159,6 +189,52 @@ static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli
 /********************************************************************
 ********************************************************************/
 
+static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *cli,
+                                           POLICY_HND *pol, const char *privilege)
+{
+       NTSTATUS result;
+       uint32 enum_context=0;
+       uint32 pref_max_length=0x1000;
+       DOM_SID *sids;
+       uint32 count=0;
+       int i;
+       fstring name;
+
+       result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context, 
+               pref_max_length, &count, &sids);
+
+       if (!NT_STATUS_IS_OK(result))
+               return result;
+               
+       d_printf("%s:\n", privilege);
+
+       for ( i=0; i<count; i++ ) {
+       
+                  
+               result = check_privilege_for_user( ctx, cli, pol, &sids[i], privilege);
+               
+               if ( ! NT_STATUS_IS_OK(result)) {
+                       if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                               return result;
+                       }
+                       continue;
+               }
+
+               /* try to convert the SID to a name.  Fall back to 
+                  printing the raw SID if necessary */
+               result = sid_to_name( cli, ctx, &sids[i], name );
+               if ( !NT_STATUS_IS_OK (result) )
+                       fstrcpy( name, sid_string_static(&sids[i]) );
+                       
+               d_printf("  %s\n", name);
+       }
+
+       return NT_STATUS_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
 static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli,
                                               POLICY_HND *pol )
 {
@@ -208,43 +284,99 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
        POLICY_HND pol;
        NTSTATUS result;
        DOM_SID sid;
+       fstring privname;
+       fstring description;
+       uint16 lang_id = 0;
+       uint16 lang_id_sys = 0;
+       uint16 lang_id_desc;
+       
        
        result = cli_lsa_open_policy(cli, mem_ctx, True, 
                SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
 
        if ( !NT_STATUS_IS_OK(result) )
                return result;
-               
-       switch (argc) {
-       case 0:
+       
+       /* backwards compatibility; just list available privileges if no arguement */
+          
+       if (argc == 0) {
                result = enum_privileges( mem_ctx, cli, &pol );
-               break;
-                       
-       case 1:
-               /* special case to enuemrate all privileged SIDs 
-                  with associated rights */
-               
-               if ( strequal( argv[0], "accounts" ) ) {
-                       result = enum_privileges_for_accounts( mem_ctx, cli, &pol );
-               }
-               else {
+               goto done;
+       }
 
-                       result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
-                       if (!NT_STATUS_IS_OK(result))
-                               goto done;      
-                       result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
+       if (strequal(argv[0], "privileges")) {
+               int i = 1;
+
+               if (argv[1] == NULL) {
+                       result = enum_privileges( mem_ctx, cli, &pol );
+                       goto done;
                }
-               break;
+
+               while ( argv[i] != NULL ) 
+               {
+                       fstrcpy( privname, argv[i] );
+                       i++;
+               
+                       /* verify that this is a valid privilege for error reporting */
+                       
+                       result = cli_lsa_get_dispname(cli, mem_ctx, &pol, privname, lang_id, 
+                               lang_id_sys, description, &lang_id_desc);
+                       
+                       if ( !NT_STATUS_IS_OK(result) ) {
+                               if ( NT_STATUS_EQUAL( result, NT_STATUS_NO_SUCH_PRIVILEGE ) ) 
+                                       d_printf("No such privilege exists: %s.\n", privname);
+                               else
+                                       d_printf("Error resolving privilege display name [%s].\n", nt_errstr(result));
+                               continue;
+                       }
                        
-       default:                
-               if ( argc > 1 ) {
-                       d_printf("Usage: net rpc rights list [name|SID]\n");
-                       result = NT_STATUS_OK;
+                       result = enum_accounts_for_privilege(mem_ctx, cli, &pol, privname);
+                       if (!NT_STATUS_IS_OK(result)) {
+                               d_printf("Error enumerating accounts for privilege %s [%s].\n", 
+                                       privname, nt_errstr(result));
+                               continue;
+                       }
                }
+               goto done;
        }
 
+       /* special case to enumerate all privileged SIDs with associated rights */
        
+       if (strequal( argv[0], "accounts")) {
+               int i = 1;
+
+               if (argv[1] == NULL) {
+                       result = enum_privileges_for_accounts(mem_ctx, cli, &pol);
+                       goto done;
+               }
+
+               while (argv[i] != NULL) {
+                       result = name_to_sid(cli, mem_ctx, &sid, argv[i]);
+                       if (!NT_STATUS_IS_OK(result)) {
+                               goto done;
+                       }
+                       result = enum_privileges_for_user(mem_ctx, cli, &pol, &sid);
+                       if (!NT_STATUS_IS_OK(result)) {
+                               goto done;
+                       }
+                       i++;
+               }
+               goto done;
+       }
 
+       /* backward comaptibility: if no keyword provided, treat the key
+          as an account name */
+       if (argc > 1) {
+               d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
+               result = NT_STATUS_OK;
+               goto done;
+       }
+
+       result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+       result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
 
 done:
        cli_lsa_close(cli, mem_ctx, &pol);
@@ -379,9 +511,9 @@ static int rpc_rights_revoke( int argc, const char **argv )
 
 static int net_help_rights( int argc, const char **argv )
 {
-       d_printf("net rpc rights list [accounts|username]   View available or assigned privileges\n");
-       d_printf("net rpc rights grant <name|SID> <right>   Assign privilege[s]\n");
-       d_printf("net rpc rights revoke <name|SID> <right>  Revoke privilege[s]\n");
+       d_printf("net rpc rights list [{accounts|privileges} [name|SID]]   View available or assigned privileges\n");
+       d_printf("net rpc rights grant <name|SID> <right>                  Assign privilege[s]\n");
+       d_printf("net rpc rights revoke <name|SID> <right>                 Revoke privilege[s]\n");
        
        d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
        d_printf("For example\n");
index 49aef2a23cd18b8c553ee3d83a458aac796a09d8..fa38004fe6fb13e37f5de10580fa493206600cee 100644 (file)
@@ -24,8 +24,6 @@
 #include "includes.h"
 #include "utils/net.h"
 
-extern DOM_SID global_sid_Builtin; 
-
 static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
 {
        int i;
@@ -429,7 +427,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
        if (delta->buf_logon_hrs.buffer) {
                pstring old, new;
                pdb_sethexhours(old, pdb_get_hours(account));
-               pdb_sethexhours(new, (const char *)delta->buf_logon_hrs.buffer);
+               pdb_sethexhours(new, delta->buf_logon_hrs.buffer);
                if (!strequal(old, new))
                        pdb_set_hours(account, (const char *)delta->buf_logon_hrs.buffer, PDB_CHANGED);
        }
diff --git a/source/utils/net_rpc_service.c b/source/utils/net_rpc_service.c
new file mode 100644 (file)
index 0000000..94644f8
--- /dev/null
@@ -0,0 +1,529 @@
+/* 
+   Samba Unix/Linux SMB client library 
+   Distributed SMB/CIFS Server Management Utility 
+   Copyright (C) Gerald (Jerry) Carter          2005
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+#include "includes.h"
+#include "utils/net.h"
+
+
+/********************************************************************
+********************************************************************/
+
+static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                             POLICY_HND *hSCM, const char *service, uint32 *state )
+{
+       POLICY_HND hService;
+       SERVICE_STATUS service_status;
+       WERROR result = WERR_GENERAL_FAILURE;
+       
+       /* now cycle until the status is actually 'watch_state' */
+       
+       result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService, 
+               service, SC_RIGHT_SVC_QUERY_STATUS );
+
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open service.  [%s]\n", dos_errstr(result));
+               return result;
+       }
+
+       result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status  );
+       if ( W_ERROR_IS_OK(result) ) {
+               *state = service_status.state;
+       }
+       
+       cli_svcctl_close_service( cli, mem_ctx, &hService );
+       
+       return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                   POLICY_HND *hSCM, const char *service, 
+                                  uint32 watch_state, uint32 *final_state )
+{
+       uint32 i;
+       uint32 state = 0;
+       WERROR result = WERR_GENERAL_FAILURE;
+       
+       
+       i = 0;
+       while ( (state != watch_state ) && i<30 ) {
+               /* get the status */
+
+               result = query_service_state( cli, mem_ctx, hSCM, service, &state  );
+               if ( !W_ERROR_IS_OK(result) ) {
+                       break;
+               }
+               
+               d_printf(".");
+               i++;
+               usleep( 100 );
+       }
+       d_printf("\n");
+       
+       *final_state = state;
+       
+       return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                             POLICY_HND *hSCM, const char *service, 
+                            uint32 control, uint32 watch_state )
+{
+       POLICY_HND hService;
+       WERROR result = WERR_GENERAL_FAILURE;
+       SERVICE_STATUS service_status;
+       uint32 state = 0;
+       
+       /* Open the Service */
+       
+       result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService, 
+               service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
+
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open service.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       /* get the status */
+
+       result = cli_svcctl_control_service( cli, mem_ctx, &hService, 
+               control, &service_status  );
+               
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Control service request failed.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       /* loop -- checking the state until we are where we want to be */
+       
+       result = watch_service_state( cli, mem_ctx, hSCM, service, watch_state, &state );
+               
+       d_printf("%s service is %s.\n", service, svc_status_string(state));
+
+done:  
+       cli_svcctl_close_service( cli, mem_ctx, &hService  );
+               
+       return result;
+}      
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM;
+       ENUM_SERVICES_STATUS *services;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       fstring displayname;
+       uint32 num_services = 0;
+       int i;
+       
+       if (argc != 0 ) {
+               d_printf("Usage: net rpc service list\n");
+               return NT_STATUS_OK;
+       }
+
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       result = cli_svcctl_enumerate_services( cli, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
+               SVCCTL_STATE_ALL, &num_services, &services );
+       
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to enumerate services.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       if ( num_services == 0 )
+               d_printf("No services returned\n");
+       
+       for ( i=0; i<num_services; i++ ) {
+               rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
+               rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
+               
+               d_printf("%-20s    \"%s\"\n", servicename, displayname);
+       }
+
+done:  
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}      
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM, hService;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       SERVICE_STATUS service_status;
+       SERVICE_CONFIG config;
+       fstring ascii_string;
+       
+       if (argc != 1 ) {
+               d_printf("Usage: net rpc service status <service>\n");
+               return NT_STATUS_OK;
+       }
+
+       fstrcpy( servicename, argv[0] );
+
+       /* Open the Service Control Manager */
+       
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       /* Open the Service */
+       
+       result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService, servicename, 
+               (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
+
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open service.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       /* get the status */
+
+       result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Query status request failed.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
+
+       /* get the config */
+
+       result = cli_svcctl_query_config( cli, mem_ctx, &hService, &config  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Query config request failed.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+
+       /* print out the configuration information for the service */
+
+       d_printf("Configuration details:\n");
+       d_printf("\tService Type         = 0x%x\n", config.service_type);
+       d_printf("\tStart Type           = 0x%x\n", config.start_type);
+       d_printf("\tError Control        = 0x%x\n", config.error_control);
+       d_printf("\tTag ID               = 0x%x\n", config.tag_id);
+
+       if ( config.executablepath ) {
+               rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+               d_printf("\tExecutable Path      = %s\n", ascii_string);
+       }
+
+       if ( config.loadordergroup ) {
+               rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+               d_printf("\tLoad Order Group     = %s\n", ascii_string);
+       }
+
+       if ( config.dependencies ) {
+               rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+               d_printf("\tDependencies         = %s\n", ascii_string);
+       }
+
+       if ( config.startname ) {
+               rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+               d_printf("\tStart Name           = %s\n", ascii_string);
+       }
+
+       if ( config.displayname ) {
+               rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+               d_printf("\tDisplay Name         = %s\n", ascii_string);
+       }
+
+done:  
+       cli_svcctl_close_service( cli, mem_ctx, &hService  );
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}      
+
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       
+       if (argc != 1 ) {
+               d_printf("Usage: net rpc service status <service>\n");
+               return NT_STATUS_OK;
+       }
+
+       fstrcpy( servicename, argv[0] );
+
+       /* Open the Service Control Manager */
+       
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       result = control_service( cli, mem_ctx, &hSCM, servicename, 
+               SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
+               
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}      
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       
+       if (argc != 1 ) {
+               d_printf("Usage: net rpc service status <service>\n");
+               return NT_STATUS_OK;
+       }
+
+       fstrcpy( servicename, argv[0] );
+
+       /* Open the Service Control Manager */
+       
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       result = control_service( cli, mem_ctx, &hSCM, servicename, 
+               SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
+               
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}      
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       
+       if (argc != 1 ) {
+               d_printf("Usage: net rpc service status <service>\n");
+               return NT_STATUS_OK;
+       }
+
+       fstrcpy( servicename, argv[0] );
+
+       /* Open the Service Control Manager */
+       
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       result = control_service( cli, mem_ctx, &hSCM, servicename, 
+               SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
+               
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}      
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv )
+{
+       POLICY_HND hSCM, hService;
+       WERROR result = WERR_GENERAL_FAILURE;
+       fstring servicename;
+       uint32 state = 0;
+       
+       if (argc != 1 ) {
+               d_printf("Usage: net rpc service status <service>\n");
+               return NT_STATUS_OK;
+       }
+
+       fstrcpy( servicename, argv[0] );
+
+       /* Open the Service Control Manager */
+       
+       result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE  );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open Service Control Manager.  [%s]\n", dos_errstr(result));
+               return werror_to_ntstatus(result);
+       }
+       
+       /* Open the Service */
+       
+       result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService, 
+               servicename, SC_RIGHT_SVC_START );
+
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Failed to open service.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       /* get the status */
+
+       result = cli_svcctl_start_service( cli, mem_ctx, &hService, NULL, 0 );
+       if ( !W_ERROR_IS_OK(result) ) {
+               d_printf("Query status request failed.  [%s]\n", dos_errstr(result));
+               goto done;
+       }
+       
+       result = watch_service_state( cli, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state  );
+       
+       if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
+               d_printf("Successfully started service: %s\n", servicename );
+       else
+               d_printf("Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
+       
+done:  
+       cli_svcctl_close_service( cli, mem_ctx, &hService  );
+       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+               
+       return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_list( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_list_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_start( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_start_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_stop( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_stop_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_resume( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_resume_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_pause( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_pause_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_status( int argc, const char **argv )
+{
+       return run_rpc_command( NULL, PI_SVCCTL, 0, 
+               rpc_service_status_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int net_help_service( int argc, const char **argv )
+{
+       d_printf("net rpc service list               View configured Win32 services\n");
+       d_printf("net rpc service start <service>    Start a service\n");
+       d_printf("net rpc service stop <service>     Stop a service\n");
+       d_printf("net rpc service pause <service>    Pause a service\n");
+       d_printf("net rpc service resume <service>   Resume a paused a service\n");
+       d_printf("net rpc service status <service>   View the current status of a service\n");
+       
+       return -1;
+}
+
+/********************************************************************
+********************************************************************/
+
+int net_rpc_service(int argc, const char **argv) 
+{
+       struct functable func[] = {
+               {"list", rpc_service_list},
+               {"start", rpc_service_start},
+               {"stop", rpc_service_stop},
+               {"pause", rpc_service_pause},
+               {"resume", rpc_service_resume},
+               {"status", rpc_service_status},
+               {NULL, NULL}
+       };
+       
+       if ( argc )
+               return net_run_function( argc, argv, func, net_help_service );
+               
+       return net_help_service( argc, argv );
+}
+
+
index c5ba59487cc1cec40b6a1d22469a393d41068cbb..88ec6b1f4facf697edb7f2892fceff2ed767d89c 100644 (file)
@@ -175,7 +175,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
                        pdb_get_bad_password_count(sam_pwent));
                
                hours = pdb_get_hours(sam_pwent);
-               pdb_sethexhours(temp, (const char *)hours);
+               pdb_sethexhours(temp, hours);
                printf ("Logon hours         : %s\n", temp);
                
        } else if (smbpwdstyle) {
@@ -911,7 +911,7 @@ int main (int argc, char **argv)
                if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
                        time_t pwd_can_change = -1;
                        time_t pwd_must_change = -1;
-                       char *errstr;
+                       const char *errstr;
 
                        if (pwd_can_change_time) {
                                errstr = "can";
index 2eb661c8b68b4e07d1efbfb9a174112b1967fcaa..5a7b6548c29cb4ad0b07810fc2c3ef62b0dd1d6c 100644 (file)
@@ -428,7 +428,8 @@ static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
                        return False;
                }
 
-               notify_printer_byname(argv[2], attribute, argv[4]);
+               notify_printer_byname(argv[2], attribute,
+                                      CONST_DISCARD(char *, argv[4]));
 
                goto send;
        }
index 836a161021d20d43caed3747d7e2a61ed129b516..708d44df9f0937db925da46b10cf1a7c3bc998f8 100644 (file)
@@ -290,7 +290,7 @@ static BOOL password_change(const char *remote_mach, char *username,
                                     err_str, sizeof(err_str), msg_str, sizeof(msg_str));
 
        if(*msg_str)
-               printf(msg_str);
+               printf("%s", msg_str);
        if(*err_str)
                fprintf(stderr, "%s", err_str);
 
index 85e710cee8f09d583cb3f0a9b2a673eabbc3b468..f4b022cf587d13a4579b90d0ba6f2c8b5e31fdc4 100644 (file)
@@ -41,7 +41,6 @@ BOOL winbindd_running(void)
    response */
 BOOL nmbd_running(void)
 {
-       extern struct in_addr loopback_ip;
        int fd, count, flags;
        struct in_addr *ip_list;
 
@@ -66,7 +65,6 @@ BOOL nmbd_running(void)
 BOOL smbd_running(void)
 {
        static struct cli_state cli;
-       extern struct in_addr loopback_ip;
 
        if (!cli_initialise(&cli))
                return False;
index ca671822d87a7f3301049fba276e55addd735b8c..cc2924afde6982da66fdbed8ae8a9c66099abd98 100644 (file)
@@ -54,8 +54,8 @@ struct pri_list {
 };
 
 static int qsort_cmp_list(const void *x, const void *y) {
-       struct pri_list *a = (struct pri_list *)x;
-       struct pri_list *b = (struct pri_list *)y;
+        struct pri_list *a = CONST_DISCARD(struct pri_list *, x);
+       struct pri_list *b = CONST_DISCARD(struct pri_list *, y);
        if (a->pri > b->pri) return -1;
        if (a->pri == b->pri) return 0;
        return 1;