merge of smbd and related files, from cvs main.
authorLuke Leighton <lkcl@samba.org>
Mon, 3 Apr 2000 02:39:42 +0000 (02:39 +0000)
committerLuke Leighton <lkcl@samba.org>
Mon, 3 Apr 2000 02:39:42 +0000 (02:39 +0000)
134 files changed:
source/Makefile.in
source/client/.cvsignore
source/client/client.c
source/client/smbmount.c
source/codepages/.cvsignore
source/configure.in
source/groupdb/.cvsignore
source/include/.cvsignore
source/include/charset.h
source/include/debug.h
source/include/includes.h
source/include/lib_smb_proto.h
source/include/local.h
source/include/proto.h
source/include/rpc_parse_proto.h
source/include/safe_string.h
source/include/smb.h
source/include/smb_macros.h
source/include/vfs.h
source/lib/.cvsignore
source/lib/access.c
source/lib/bitmap.c
source/lib/charcnv.c
source/lib/charset.c
source/lib/domain_namemap.c
source/lib/doscalls.c
source/lib/fault.c
source/lib/genrand.c
source/lib/kanji.c
source/lib/pidfile.c
source/lib/replace.c
source/lib/smbrun.c
source/lib/surs.c
source/lib/surs.h [new file with mode: 0644]
source/lib/sursalgdomonly.c
source/lib/sursalgnt5ldap.c
source/lib/surstdb.c
source/lib/system.c
source/lib/username.c
source/lib/util.c
source/lib/util_file.c
source/lib/util_sec.c
source/lib/util_sock.c
source/lib/util_str.c
source/lib/util_unistr.c
source/lib/util_wunistr.c [new file with mode: 0644]
source/libsmb/.cvsignore
source/libsmb/nmblib.c
source/libsmb/pwd_cache.c
source/libsmb/smbencrypt.c
source/locking/locking.c
source/msrpc/msrpcd.c
source/msrpc/msrpcd_process.c
source/nmbd/.cvsignore
source/nsswitch/.cvsignore
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_surs.c
source/nsswitch/winbindd_user.c
source/param/.cvsignore
source/param/loadparm.c
source/param/params.c
source/passdb/.cvsignore
source/printing/.cvsignore
source/printing/nt_printing.c
source/printing/printing.c
source/rpc_client/.cvsignore
source/rpc_parse/.cvsignore
source/rpc_parse/parse_net.c
source/rpc_parse/parse_netsec.c
source/rpc_parse/parse_prs.c
source/rpc_parse/parse_reg.c
source/rpc_parse/parse_samr.c
source/rpc_parse/parse_sec.c
source/rpc_parse/parse_srv.c
source/rpc_parse/parse_svc.c
source/rpc_server/.cvsignore
source/rpc_server/srv_reg.c
source/rpc_server/srv_samr.c
source/rpc_server/srv_srvsvc.c
source/rpc_server/srv_svcctl.c
source/samrd/.cvsignore
source/samrd/srv_samr_usr_tdb.c
source/script/.cvsignore
source/script/mkproto.awk
source/smbd/.cvsignore
source/smbd/blocking.c
source/smbd/chgpasswd.c
source/smbd/close.c
source/smbd/conn.c
source/smbd/connection.c
source/smbd/dfree.c
source/smbd/dir.c
source/smbd/dosmode.c
source/smbd/fileio.c
source/smbd/filename.c
source/smbd/files.c
source/smbd/ipc.c
source/smbd/lanman.c
source/smbd/mangle.c
source/smbd/message.c
source/smbd/negprot.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/oplock.c
source/smbd/password.c
source/smbd/pipes.c
source/smbd/predict.c
source/smbd/process.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/service.c
source/smbd/ssl.c
source/smbd/trans2.c
source/smbd/vfs-wrap.c
source/smbd/vfs.c
source/smbwrapper/.cvsignore
source/smbwrapper/smbw.c
source/spoolssd/srv_spoolss_nt.c
source/srvsvcd/srv_srvsvc_nt.c
source/tdb/.cvsignore
source/tests/.cvsignore
source/ubiqx/.cvsignore
source/ubiqx/sys_include.h
source/utils/debug2html.c
source/utils/make_printerdef.c
source/utils/make_smbcodepage.c
source/utils/smbfilter.c
source/utils/smbrun.c
source/utils/status.c
source/utils/testparm.c
source/web/.cvsignore
source/web/cgi.c
source/web/statuspage.c
source/web/swat.c

index 6c7d7f833eb4567cb13f6c14f2013915bf1caf04..3603678fd365207e17b6c1894e762665e3c6c5c1 100644 (file)
@@ -154,7 +154,7 @@ LIB_OBJ =   lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
                lib/username.o \
                lib/access.o lib/smbrun.o \
                lib/bitmap.o lib/util_sid.o lib/snprintf.o \
-               lib/util_str.o lib/util_unistr.o \
+               lib/util_str.o lib/util_unistr.o lib/util_wunistr.o \
                lib/util_file.o \
                lib/util_sock.o lib/util_sec.o lib/util_array.o \
                lib/vagent.o \
@@ -237,7 +237,7 @@ RPC_CLIENT_OBJ = \
                rpc_client/cli_eventlog.o \
                rpc_client/cli_dfs.o
 
-LOCKING_OBJ = locking/locking.o 
+LOCKING_OBJ = lib/hash.o locking/locking.o locking/brlock.o
 
 GROUPDB_OBJ = groupdb/groupdb.o groupdb/aliasdb.o groupdb/builtindb.o \
                groupdb/groupfile.o groupdb/aliasfile.o \
@@ -261,19 +261,20 @@ SIDDB_OBJ = lib/sids.o lib/util_seaccess.o
 PROFILE_OBJ = profile/profile.o
 
 SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/connection.o \
-            lib/set_uid.o \
-            smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
-            smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
-            smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
-            smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
-            smbd/uid.o \
-           smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
-           smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \
-           smbd/vfs-wrap.o smbd/dfs.o \
-               smbd/challenge.o \
-               lib/util_pwdb.o smbd/afsticket.o
+               lib/set_uid.o smbd/dfree.o smbd/dir.o smbd/password.o \
+               smbd/conn.o smbd/fileio.o \
+               smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
+               smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
+               smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
+               smbd/uid.o smbd/dosmode.o smbd/filename.o smbd/open.o \
+               smbd/close.o smbd/blocking.o smbd/process.o smbd/oplock.o \
+               smbd/service.o smbd/error.o smbd/vfs.o smbd/vfs-wrap.o \
+               smbd/challenge.o  lib/util_pwdb.o smbd/afsticket.o
+
 PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
 
+MSDFS_OBJ = msdfs/msdfs.o msdfs/msdfs_tdb.o msdfs/parse_dfs_map.o
+
 MSRPCD_OBJ = msrpc/msrpcd.o \
                msrpc/msrpcd_process.o \
                lib/set_vuid.o \
@@ -343,7 +344,7 @@ SPOOLSSD_OBJ1 = spoolssd/spoolssd.o \
                spoolssd/srv_spoolss_nt.o \
                printing/nt_printing.o 
 
-SMBD_OBJ = $(SMBD_OBJ1) $(UNIXPASSDB_OBJ) \
+SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(UNIXPASSDB_OBJ) \
            $(RPC_SERVER_OBJ) \
            lib/domain_namemap.o \
            $(LOCKING_OBJ) \
@@ -354,33 +355,33 @@ SMBD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(LIBSURS)
 
 SRVSVCD_OBJ = $(MSRPCD_OBJ) $(SRVSVCD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ)  \
+           $(PROFILE_OBJ)  \
            $(SIDDB_OBJ) \
                $(LIBSTATUS_OBJ)
 
 WKSSVCD_OBJ = $(MSRPCD_OBJ) $(WKSSVCD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
            $(SIDDB_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) 
+           $(PROFILE_OBJ) 
 
 BROWSERD_OBJ = $(MSRPCD_OBJ) $(BROWSERD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
            $(SIDDB_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) 
+           $(PROFILE_OBJ) 
 
 WINREGD_OBJ = $(MSRPCD_OBJ) $(WINREGD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
            $(SIDDB_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) 
+           $(PROFILE_OBJ) 
 
 SVCCTLD_OBJ = $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
            $(SIDDB_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) 
+           $(PROFILE_OBJ) 
 
 LSARPCD_OBJ = $(MSRPCD_OBJ) $(LSARPCD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
-           $(SIDDB_OBJ) $(LOCKING_OBJ) \
+           $(SIDDB_OBJ) \
                $(PROFILE_OBJ) 
 LSARPCD_LIBS = $(SAMBA_LIBS)
 
@@ -388,12 +389,11 @@ SPOOLSSD_OBJ = $(MSRPCD_OBJ) $(SPOOLSSD_OBJ1) \
                $(PRINTING_OBJ) \
            $(SIDDB_OBJ) \
            $(RPC_SRVUTIL_OBJ) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ)
+           $(PROFILE_OBJ)
 SPOOLSSD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
 
 NETLOGOND_OBJ = $(MSRPCD_OBJ) $(NETLOGOND_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
-           $(LOCKING_OBJ) \
            $(SIDDB_OBJ) \
                $(UNIXPASSDB_OBJ) $(LIBSTATUS_OBJ) $(PROFILE_OBJ) 
 
@@ -411,7 +411,6 @@ NETLOGONNT5LDAPD_LIBS = $(SAMBA_LIBS) $(SAMRNT5LDAPLIB) \
 
 SAMRD_OBJ = $(MSRPCD_OBJ) $(SAMRD_OBJ1) \
            $(RPC_SRVUTIL_OBJ) \
-           $(LOCKING_OBJ) \
            $(SIDDB_OBJ) \
                $(PROFILE_OBJ) 
 
@@ -451,6 +450,7 @@ SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
            web/swat.o libsmb/passchange.o $(LOCKING_OBJ) \
            rpc_server/srv_lookup.o \
            $(SIDDB_OBJ) \
+           $(PRINTING_OBJ) \
            $(UNIXPASSDB_OBJ) \
            $(STUB_UID_OBJ)
 
@@ -1015,9 +1015,9 @@ bin/testprns: $(SAMBALIB) $(TESTPRNS_OBJ) bin/.dummy
        @echo Linking $@
        @$(LINK) -o $@ $(TESTPRNS_OBJ) $(SAMBALIB) $(LIBS)
 
-bin/smbstatus: $(SAMBALIB) $(STATUS_OBJ) bin/.dummy
+bin/smbstatus: $(SAMBALIB) $(UBIQXLIB) $(STATUS_OBJ) bin/.dummy
        @echo Linking $@
-       @$(LINK) -o $@ $(STATUS_OBJ) $(SAMBALIB) $(LIBS)
+       @$(LINK) -o $@ $(STATUS_OBJ) $(SAMBALIB) $(UBIQXLIB) $(LIBS)
 
 bin/smbpasswd: $(SMBPASSWD_LIBS) $(SMBPASSWD_OBJ) bin/.dummy
        @echo Linking $@
@@ -1171,10 +1171,10 @@ rpc_client_proto:
          -f script/mkproto.awk `echo $(RPC_CLIENT_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/rpc_client_proto.h
 
 etags:
-       etags `find . -name "*.[ch]"`
+       etags `find . -name "*.[ch]" | grep -v /CVS/`
 
 ctags:
-       ctags `find . -name "*.[ch]"`
+       ctags `find . -name "*.[ch]" | grep -v /CVS/`
 
 realclean: clean
        -rm -f config.log $(PROGS) $(SPROGS) bin/.dummy
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 7089936160dd78995a00ac19e5548f74d08fd831..5f8c428df87dd0efb6b4a0d799469e2cc2f97d98 100644 (file)
@@ -1513,7 +1513,7 @@ static void wait_keyboard(void)
 
                timeout.tv_sec = 20;
                timeout.tv_usec = 0;
-               sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,NULL, &timeout);
+               sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,NULL,&timeout);
       
                if (FD_ISSET(fileno(stdin),&fds))
                        return;
index 3fad6674fb874fd0850d76e2e09551206c228483..28945612ce73a1a6af3f3b969b5ead927a4aba6c 100644 (file)
@@ -609,7 +609,7 @@ static void wait_keyboard(char *buffer)
 
       timeout.tv_sec = 20;
       timeout.tv_usec = 0;
-      selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL, &timeout);
+      selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL,&timeout);
       
       if (FD_ISSET(fileno(stdin),&fds))
        return;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 1d52dcb2e4cc1cadea8addf89eaaffd338bd9b3b..4a6613712dfa8b3d58898cfc5a33e6e9e3c63abd 100644 (file)
@@ -989,65 +989,6 @@ if test x"$samba_cv_USE_SETUIDX" = x"yes"; then
 fi
 fi
 
-################################################
-# look for a method of setting the effective gid
-setegid=no;
-if test $setegid = no; then
-AC_CACHE_CHECK([for setresgid],samba_cv_USE_SETRESGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETRESUID 1
-#define USE_SETRESGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
-           samba_cv_USE_SETRESGID=yes,samba_cv_USE_SETRESGID=no,samba_cv_USE_SETRESGID=cross)])
-if test x"$samba_cv_USE_SETRESGID" = x"yes"; then
-    setegid=yes;AC_DEFINE(USE_SETRESGID)
-fi
-fi
-
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setregid],samba_cv_USE_SETREGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETREUID 1
-#define USE_SETREGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
-           samba_cv_USE_SETREGID=yes,samba_cv_USE_SETREGID=no,samba_cv_USE_SETREGID=cross)])
-if test x"$samba_cv_USE_SETREGID" = x"yes"; then
-    setegid=yes;AC_DEFINE(USE_SETREGID)
-fi
-fi
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setegid],samba_cv_USE_SETEGID,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETEUID 1
-#define USE_SETEGID 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
-           samba_cv_USE_SETEGID=yes,samba_cv_USE_SETEGID=no,samba_cv_USE_SETEGID=cross)])
-if test x"$samba_cv_USE_SETEGID" = x"yes"; then
-    setegid=yes;AC_DEFINE(USE_SETEGID)
-fi
-fi
-
-if test $setegid = no; then
-AC_CACHE_CHECK([for setgidx],samba_cv_USE_SETGIDX,[
-AC_TRY_RUN([
-#define AUTOCONF_TEST 1
-#define USE_SETUIDX 1
-#define USE_SETGIDX 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/util_sec.c"],
-           samba_cv_USE_SETGIDX=yes,samba_cv_USE_SETGIDX=no,samba_cv_USE_SETGIDX=cross)])
-if test x"$samba_cv_USE_SETGIDX" = x"yes"; then
-    setegid=yes;AC_DEFINE(USE_SETGIDX)
-fi
-fi
 
 AC_CACHE_CHECK([for shared mmap],samba_cv_HAVE_SHARED_MMAP,[
 AC_TRY_RUN([#include "${srcdir-.}/tests/shared_mmap.c"],
@@ -1935,22 +1876,6 @@ else
     echo "no"
 fi
 
-# sometimes getopt_long cannot parse same arguments twice
-# e.g. on certain versions of CygWin32
-AC_CACHE_CHECK([for working getopt_long],samba_cv_HAVE_GETOPT_LONG,[
-AC_TRY_RUN([#include <getopt.h>
-main() {
-    int i, x = 0; char *argv[] = { "x", "--xx" };
-    struct option o[] = {{"xx", 0, 0, 1}, {0,0,0,0}};
-    getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0; optind = 0;
-    getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0;
-    exit(x == 2 ? 0 : 1);
-}], samba_cv_HAVE_GETOPT_LONG=yes,samba_cv_HAVE_GETOPT_LONG=no,
-    samba_cv_HAVE_GETOPT_LONG=cross)])
-if test x"$samba_cv_HAVE_GETOPT_LONG" = x"yes"; then
-    AC_DEFINE(HAVE_GETOPT_LONG)
-fi
-
 echo "checking configure summary"
 AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
            echo "configure OK";,
index af9d6be961b213ad27e2ea901773923583dde142..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
-*.lo
\ No newline at end of file
+.libs
+*.lo
index b423e99519879fed4894998a79ae6fd54a6d0a0e..2dd66f466da2819909f47f2a675e9301f6dd5bec 100644 (file)
@@ -1,2 +1,3 @@
+.libs
 config.h
 stamp-h
index b6f79c03dde7258e50784f0f9c291104d1e2fcbf..7c6fbe5509b09e69517ddbc1fcf2c95f42c887a0 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef _CHARSET_H
+#define _CHARSET_H
+
 /* 
    Unix SMB/Netbios implementation.
    Version 1.9.
@@ -73,3 +76,16 @@ extern void charset_initialise(void);
 #define CODEPAGE_VERSION_OFFSET 0
 #define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2
 #define CODEPAGE_LENGTH_OFFSET 4
+
+/* Version id for dynamically loadable unicode map files. */
+#define UNICODE_MAP_FILE_VERSION_ID 0x8001
+/* Version 0x80000001 unicode map file header size. */
+#define UNICODE_MAP_HEADER_SIZE 30
+#define UNICODE_MAP_CODEPAGE_ID_SIZE 20
+/* Offsets for unicode map file header entries. */
+#define UNICODE_MAP_VERSION_OFFSET 0
+#define UNICODE_MAP_CLIENT_CODEPAGE_OFFSET 2
+#define UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET 22
+#define UNICODE_MAP_UNICODE_TO_CP_LENGTH_OFFSET 26
+
+#endif /* _CHARSET_H */
index df74da0b41592d68f664d5d2f1aed6073733ed57..ad7c1a8645d178d5fc6bbfd658bdcd828466491a 100644 (file)
@@ -22,8 +22,8 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifndef _DEBUG_H
-#define _DEBUG_H
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
 
 /* -------------------------------------------------------------------------- **
  * Debugging code.  See also debug.c
index b5294a50840c0f1fad7f4d6cb3f446ceeeee8c36..f9b924be3b1300e50bfef287a55171aafb876066 100644 (file)
  */
 
 #ifndef SMB_INO_T
-#  ifdef HAVE_INO64_T
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)
 #    define SMB_INO_T ino64_t
 #  else
 #    define SMB_INO_T ino_t
 #endif
 
 #ifndef LARGE_SMB_INO_T
-#  if defined(HAVE_INO64_T) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
+#  if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
 #    define LARGE_SMB_INO_T 1
 #  endif
 #endif
 #endif
 
 #ifndef SMB_OFF_T
-#  ifdef HAVE_OFF64_T
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)
 #    define SMB_OFF_T off64_t
 #  else
 #    define SMB_OFF_T off_t
 #  endif
 #endif
 
+/* this should really be a 64 bit type if possible */
+#define br_off SMB_BIG_UINT
+
 #define SMB_OFF_T_BITS (sizeof(SMB_OFF_T)*8)
 
 /*
  */
 
 #ifndef LARGE_SMB_OFF_T
-#  if defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
+#  if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
 #    define LARGE_SMB_OFF_T 1
 #  endif
 #endif
  */
 
 #ifndef SMB_STRUCT_STAT
-#  if defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
 #    define SMB_STRUCT_STAT struct stat64
 #  else
 #    define SMB_STRUCT_STAT struct stat
 #  endif
 #endif
 
+/*
+ * Type for dirent structure.
+ */
+
+#ifndef SMB_STRUCT_DIRENT
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_DIRENT64)
+#    define SMB_STRUCT_DIRENT struct dirent64
+#  else
+#    define SMB_STRUCT_DIRENT struct dirent
+#  endif
+#endif
+
 /*
  * Defines for 64 bit fcntl locks.
  */
 
 #ifndef SMB_STRUCT_FLOCK
-#  if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
 #    define SMB_STRUCT_FLOCK struct flock64
 #  else
 #    define SMB_STRUCT_FLOCK struct flock
 #endif
 
 #ifndef SMB_F_SETLKW
-#  if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
 #    define SMB_F_SETLKW F_SETLKW64
 #  else
 #    define SMB_F_SETLKW F_SETLKW
 #endif
 
 #ifndef SMB_F_SETLK
-#  if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
 #    define SMB_F_SETLK F_SETLK64
 #  else
 #    define SMB_F_SETLK F_SETLK
 #endif
 
 #ifndef SMB_F_GETLK
-#  if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+#  if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
 #    define SMB_F_GETLK F_GETLK64
 #  else
 #    define SMB_F_GETLK F_GETLK
 #if defined(HAVE_LONGLONG)
 #define SMB_BIG_UINT unsigned long long
 #define SMB_BIG_INT long long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
 #else
 #define SMB_BIG_UINT unsigned long
 #define SMB_BIG_INT long
+#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
 #endif
 
 #ifndef MIN
@@ -600,6 +617,7 @@ extern int errno;
 #include "../tdb/tdb.h"
 #include "talloc.h"
 #include "interfaces.h"
+#include "hash.h"
 
 #ifdef HAVE_FNMATCH
 #include <fnmatch.h>
@@ -621,6 +639,8 @@ extern int errno;
 #include "kanji.h"
 #include "charset.h"
 
+#include "msdfs.h"
+
 #ifdef WITH_PROFILE
 #include "profile.h"
 #endif
@@ -629,6 +649,38 @@ extern int errno;
 #define MAXCODEPAGELINES 256
 #endif
 
+/*
+ * Type for wide character dirent structure.
+ * Only d_name is defined by POSIX.
+ */
+
+typedef struct smb_wdirent {
+       wpstring        d_name;
+} SMB_STRUCT_WDIRENT;
+
+/*
+ * Type for wide character passwd structure.
+ */
+
+typedef struct smb_wpasswd {
+       wfstring       pw_name;
+       char           *pw_passwd;
+       uid_t          pw_uid;
+       gid_t          pw_gid;
+       wpstring       pw_gecos;
+       wpstring       pw_dir;
+       wpstring       pw_shell;
+} SMB_STRUCT_WPASSWD;
+
+/* Defines for wisXXX functions. */
+#define UNI_UPPER    0x1
+#define UNI_LOWER    0x2
+#define UNI_DIGIT    0x4
+#define UNI_XDIGIT   0x8
+#define UNI_SPACE    0x10
+
+#include "../lib/surs.h"
+
 /***** automatically generated prototypes *****/
 #include "ldapdb.h"
 #include "proto.h"
@@ -817,16 +869,44 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
 #define bzero(a,b) memset((a),'\0',(b))
 #endif
 
-#ifdef REPLACE_GETPASS
-#define getpass(prompt) getsmbpass((prompt))
+/*
+ * Some older systems seem not to have MAXHOSTNAMELEN
+ * defined.
+ */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 254
+#endif
+
+/* yuck, I'd like a better way of doing this */
+#define DIRP_SIZE (256 + 32)
+
+/*
+ * glibc on linux doesn't seem to have MSG_WAITALL
+ * defined. I think the kernel has it though..
+ */
+
+#ifndef MSG_WAITALL
+#define MSG_WAITALL 0
+#endif
+
+/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
+   given the socket IO pattern that Samba uses */
+#ifdef TCP_NODELAY
+#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
+#else
+#define DEFAULT_SOCKET_OPTIONS ""
 #endif
+
+/* Load header file for libdl stuff */
+
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
+#endif
+
 #ifdef USE_RENEWABLE_AFS_TICKET
 #include "afsticket.h"
 #endif /* USE_RENEWABLE_AFS_TICKET */
 
-/* yuck, I'd like a better way of doing this */
-#define DIRP_SIZE (256 + 32)
 /* change initialization ... support for IRIX cc */
 #define VUSER_KEY vuser_key key; key.pid=conn->smbd_pid; key.vuid=vuid
 #endif /* _INCLUDES_H */
index 410d898a7bea7482a63fbfc53f765cee282de8eb..4cc879070561036948977301986bf141052b4fa5 100644 (file)
@@ -167,17 +167,17 @@ void pwd_set_nullpwd(struct pwd_info *pwd);
 void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
 void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
 void pwd_set_lm_nt_16(struct pwd_info *pwd,
-                               const uchar lm_pwd[16],
-                               const uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+                     const uchar lm_pwd[16], const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+                     uchar nt_pwd[16]);
 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
 void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
-               const char *user, const char *server, const char *domain,
-                                       uchar sess_key[16]);
+                        const char *user, const char *server,
+                        const char *domain, uchar sess_key[16]);
 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
-                               uchar sess_key[16]);
+                       uchar sess_key[16]);
 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len);
+                      uchar * nt_owf, size_t * nt_owf_len);
 
 /*The following definitions come from  libsmb/smbdes.c  */
 
@@ -203,6 +203,9 @@ void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24]);
 void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
                       uchar p24[24]);
 void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+BOOL make_oem_passwd_hash(uchar data[516],
+                         const char *pwrd, int new_pw_len,
+                         const uchar old_pw_hash[16], BOOL unicode);
 void SMBOWFencrypt_ntv2(const uchar kr[16],
                        const uchar * srv_chal, int srv_chal_len,
                        const uchar * cli_chal, int cli_chal_len,
@@ -219,9 +222,6 @@ void ntv2_owf_gen(const uchar owf[16],
 void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]);
 void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
 void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-BOOL make_oem_passwd_hash(uchar data[516],
-                         const char *pwrd, int new_pw_len,
-                         const uchar old_pw_hash[16], BOOL unicode);
 BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
 BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
 BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
@@ -342,63 +342,65 @@ BOOL create_user_creds( prs_struct *ps,
 
 /*The following definitions come from  rpc_parse/parse_net.c  */
 
-BOOL make_log_info(DOM_LOG_INFO *log,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name);
-BOOL smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps, int depth);
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
-                               const char *logon_srv, const char *comp_name,
-                               DOM_CRED *clnt_cred);
-BOOL smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name,
-                               DOM_CRED *cred);
-BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO * log,
+                  const char *logon_srv, const char *acct_name,
+                  uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+                    int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+                    const char *logon_srv, const char *comp_name,
+                    DOM_CRED * clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+                      int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+                   const char *logon_srv, const char *acct_name,
+                   uint16 sec_chan, const char *comp_name, DOM_CRED * cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+                     int depth);
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth);
 BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 * q_l,
                        const char *srv_name,
                        uint32 function_code,
                        uint32 query_level, uint32 switch_value);
 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
                        uint32 switch_value,
                        NETLOGON_INFO * logon_info, uint32 status);
 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_q_req_chal(NET_Q_REQ_CHAL * q_c,
                     const char *logon_srv, const char *logon_clnt,
                     DOM_CHAL * clnt_chal);
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
                       int depth);
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
                       int depth);
 BOOL make_q_auth(NET_Q_AUTH * q_a,
                 const char *logon_srv, const char *acct_name,
                 uint16 sec_chan, const char *comp_name, DOM_CHAL * clnt_chal);
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth);
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth);
 BOOL make_q_auth_2(NET_Q_AUTH_2 * q_a,
                   const char *logon_srv, const char *acct_name,
                   uint16 sec_chan, const char *comp_name,
                   DOM_CHAL * clnt_chal, uint32 clnt_flgs);
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
                     int depth);
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
                     int depth);
 BOOL make_q_srv_pwset(NET_Q_SRV_PWSET * q_s,
                      const char *logon_srv, const char *acct_name,
                      uint16 sec_chan, const char *comp_name,
                      DOM_CRED * cred, char nt_cypher[16]);
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
                        int depth);
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
                        int depth);
 BOOL make_id_info1(NET_ID_INFO_1 * id, const char *domain_name,
                   uint32 param_ctrl,
@@ -433,12 +435,12 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -447,9 +449,9 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
-                         const char *padding, const DOM_SID * dom_sid);
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
+                         const char *padding, const DOM_SID *dom_sid);
 BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
                         NTTIME * logon_time,
                         NTTIME * logoff_time,
@@ -472,11 +474,11 @@ BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
                         uint32 user_flgs,
                         char sess_key[16],
                         char *logon_srv,
-                        char *logon_dom, char *padding, DOM_SID * dom_sid);
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+                        char *logon_dom, char *padding, DOM_SID *dom_sid);
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
                       int depth);
 BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
-               const NET_USER_INFO_CTR *ctr);
+                                  const NET_USER_INFO_CTR * ctr);
 BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const NTTIME * logon_time,
                          const NTTIME * logoff_time,
@@ -484,12 +486,12 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -498,10 +500,10 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
                          const char *padding,
-                         const DOM_SID * dom_sid, const char *other_sids);
+                         const DOM_SID *dom_sid, const char *other_sids);
 BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
                         NTTIME * logon_time,
                         NTTIME * logoff_time,
@@ -525,45 +527,44 @@ BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
                         char sess_key[16],
                         char *logon_srv,
                         char *logon_dom,
-                        char *padding, DOM_SID * dom_sid, char *other_sids);
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+                        char *padding, DOM_SID *dom_sid, char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
                       int depth);
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
                        int depth);
 BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
                      const DOM_CRED * srv_creds,
-                     uint16 switch_value,
-                     void *id, uint32 status);
+                     uint16 switch_value, void *id, uint32 status);
 BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 void free_net_user_info_ctr(NET_USER_INFO_CTR * ctr);
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
                        int depth);
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
                         int depth);
 BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF * r_s,
                       const DOM_CRED * srv_cred, uint32 status);
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
                         int depth);
 BOOL make_q_sam_sync(NET_Q_SAM_SYNC * q_s,
                     const char *srv_name,
                     const char *cli_name,
                     DOM_CRED * cli_creds, uint32 database_id);
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
                       int depth);
 BOOL make_sam_delta_hdr(SAM_DELTA_HDR * delta, uint16 type, uint32 rid);
 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name,
                           uint32 user_rid, uint32 group_rid,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * desc,
+                          const UNISTR2 *home_dir,
+                          const UNISTR2 *dir_drive,
+                          const UNISTR2 *log_scr,
+                          const UNISTR2 *desc,
                           uint32 acb_info,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str, const UNISTR2 * mung_dial);
+                          const UNISTR2 *prof_path,
+                          const UNISTR2 *wkstas,
+                          const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
 BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
                     const DOM_CRED * srv_cred,
                     uint32 sync_context,
@@ -572,7 +573,7 @@ BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
                     SAM_DELTA_HDR * hdr_deltas,
                     SAM_DELTA_CTR * deltas, uint32 status);
 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
-                      NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth);
+                      NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_ntlmssp.c  */
 
index 98486546aaf3e12988500249f557703ca2778bab..bd75d4e3858599c096b11dfeb64c85cf14d82a60 100644 (file)
 /* max number of directories open at once */
 /* note that with the new directory code this no longer requires a
    file handle per directory, but large numbers do use more memory */
-#define MAX_OPEN_DIRECTORIES 64
+#define MAX_OPEN_DIRECTORIES 256
+
+/* max number of directory handles */
+/* As this now uses the bitmap code this can be
+   quite large. */
+#define MAX_DIRECTORY_HANDLES 2048
+
+/* maximum number of file caches per smbd */
+#define MAX_WRITE_CACHES 10
 
 /* define what facility to use for syslog */
 #ifndef SYSLOG_FACILITY
@@ -66,6 +74,9 @@
 /* separators for lists */
 #define LIST_SEP " \t,;:\n\r"
 
+/* wchar separators for lists */
+#define LIST_SEP_W wchar_list_sep
+
 #ifndef LOCKDIR
 /* this should have been set in the Makefile */
 #define LOCKDIR "/tmp/samba"
 #define GUEST_ACCOUNT "nobody"
 #endif
 
-/* do you want smbd to send a 1 byte packet to nmbd to trigger it to start 
-   when smbd starts? */
-#ifndef PRIME_NMBD
-#define PRIME_NMBD 1
-#endif
-
 /* the default pager to use for the client "more" command. Users can
    override this with the PAGER environment variable */
 #ifndef PAGER
 /* the following control timings of various actions. Don't change 
    them unless you know what you are doing. These are all in seconds */
 #define DEFAULT_SMBD_TIMEOUT (60*60*24*7)
-#define SMBD_RELOAD_CHECK (60)
+#define SMBD_RELOAD_CHECK (180)
 #define IDLE_CLOSED_TIMEOUT (60)
 #define DPTR_IDLE_TIMEOUT (120)
-#define SMBD_SELECT_LOOP (10)
+#define SMBD_SELECT_TIMEOUT (60)
+#define SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS (10)
 #define NMBD_SELECT_LOOP (10)
 #define BROWSE_INTERVAL (60)
 #define REGISTRATION_INTERVAL (10*60)
 /* shall we support browse requests via a FIFO to nmbd? */
 #define ENABLE_FIFO 1
 
-/* how long to wait for a socket connect to happen */
-#define LONG_CONNECT_TIMEOUT 30
-#define SHORT_CONNECT_TIMEOUT 5
-
-/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
-   given the socket IO pattern that Samba uses*/
-#ifdef TCP_NODELAY
-#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
-#else
-#define DEFAULT_SOCKET_OPTIONS ""
-#endif
+/* how long (in miliseconds) to wait for a socket connect to happen */
+#define LONG_CONNECT_TIMEOUT 30000
+#define SHORT_CONNECT_TIMEOUT 5000
 
 /* the default netbios keepalive timeout */
 #define DEFAULT_KEEPALIVE 300
 
 #define OPLOCK_BREAK_TIMEOUT 30
 
-/* how many times do we try to resend the oplock break request - useful
-   for buggy MS clients */
-#define OPLOCK_BREAK_RESENDS 3
-
 /* Timout (in seconds) to add to the oplock break timeout
    to wait for the smbd to smbd message to return. */
 
 /* name of directory that netatalk uses to store macintosh resource forks */
 #define APPLEDOUBLE ".AppleDouble/"
 
+/*
+ * Default passwd chat script.
+ */
+
+#define DEFAULT_PASSWD_CHAT "*new*password* %n\\n *new*password* %n\\n *changed*"
+
+/* Minimum length of allowed password when changing UNIX password. */
+#define MINPASSWDLENGTH 5
+
 #endif
index ac580c2265952542300f80a1d8cb6294afcd012d..0b5a86e3a3ca0f0601352eb6d0b9bffa124afc50 100644 (file)
@@ -165,7 +165,7 @@ int bitmap_find(struct bitmap *bm, unsigned ofs);
 
 char *unix2dos_format(char *str,BOOL overwrite);
 char *dos2unix_format(char *str, BOOL overwrite);
-void interpret_character_set(char *str);
+void interpret_character_set(char *str, int codepage);
 
 /*The following definitions come from  lib/charset.c  */
 
@@ -231,6 +231,7 @@ int dos_unlink(char *fname);
 int dos_open(char *fname,int flags,mode_t mode);
 DIR *dos_opendir(char *dname);
 char *dos_readdirname(DIR *p);
+int dos_chown(char *fname, uid_t uid, gid_t gid);
 int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf);
 int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf);
 int dos_mkdir(char *dname,mode_t mode);
@@ -271,6 +272,15 @@ void getopt_dummy(void);
 
 char *getsmbpass(char *prompt)    ;
 
+/*The following definitions come from  lib/hash.c  */
+
+BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func);
+int string_hash(int hash_size, const char *key);
+hash_element *hash_lookup(hash_table *table, char *key);
+hash_element *hash_insert(hash_table *table, char *value, char *key);
+void hash_remove(hash_table *table, hash_element *hash_elem);
+void hash_clear(hash_table *table);
+
 /*The following definitions come from  lib/hmacmd5.c  */
 
 void hmac_md5_init_rfc2104(uchar*  key, int key_len, HMACMD5Context *ctx);
@@ -302,7 +312,6 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
 /*The following definitions come from  lib/kanji.c  */
 
 void interpret_coding_system(char *str);
-BOOL is_multibyte_codepage(void);
 void initialize_multibyte_vectors( int client_codepage);
 
 /*The following definitions come from  lib/md4.c  */
@@ -596,17 +605,17 @@ void pwd_set_nullpwd(struct pwd_info *pwd);
 void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
 void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
 void pwd_set_lm_nt_16(struct pwd_info *pwd,
-                               const uchar lm_pwd[16],
-                               const uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+                     const uchar lm_pwd[16], const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+                     uchar nt_pwd[16]);
 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
 void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
-               const char *user, const char *server, const char *domain,
-                                       uchar sess_key[16]);
+                        const char *user, const char *server,
+                        const char *domain, uchar sess_key[16]);
 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
-                               uchar sess_key[16]);
+                       uchar sess_key[16]);
 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len);
+                      uchar * nt_owf, size_t * nt_owf_len);
 
 /*The following definitions come from  lib/smbrun.c  */
 
@@ -636,6 +645,9 @@ void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24]);
 void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
                       uchar p24[24]);
 void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+BOOL make_oem_passwd_hash(uchar data[516],
+                         const char *pwrd, int new_pw_len,
+                         const uchar old_pw_hash[16], BOOL unicode);
 void SMBOWFencrypt_ntv2(const uchar kr[16],
                        const uchar * srv_chal, int srv_chal_len,
                        const uchar * cli_chal, int cli_chal_len,
@@ -652,9 +664,6 @@ void ntv2_owf_gen(const uchar owf[16],
 void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]);
 void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
 void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-BOOL make_oem_passwd_hash(uchar data[516],
-                         const char *pwrd, int new_pw_len,
-                         const uchar old_pw_hash[16], BOOL unicode);
 BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
 BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
 BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
@@ -687,9 +696,9 @@ const vuser_key *get_sec_ctx(void);
 
 /*The following definitions come from  lib/sursalgdomonly.c  */
 
-BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id,
                                BOOL create);
-BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+BOOL surs_algdomonly_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid,
                                BOOL create);
 
 /*The following definitions come from  lib/sursalgnt5ldap.c  */
@@ -701,8 +710,8 @@ BOOL surs_nt5ldap_unixid_to_sam_sid(LDAPDB *hds, uint32 id, uint32 type,
 
 /*The following definitions come from  lib/surs.c  */
 
-BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create);
-BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create);
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id, BOOL create);
+BOOL surs_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid, BOOL create);
 
 /*The following definitions come from  lib/surstdb.c  */
 
@@ -715,6 +724,7 @@ BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
 
 int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval);
 int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval);
+int sys_usleep(long usecs);
 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf);
 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf);
@@ -726,6 +736,7 @@ int sys_creat(const char *path, mode_t mode);
 int sys_open(const char *path, int oflag, mode_t mode);
 FILE *sys_fopen(const char *path, const char *type);
 void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset);
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp);
 int sys_waitpid(pid_t pid,int *status,int options);
 char *sys_getwd(char *s);
 int sys_chown(const char *fname,uid_t uid,gid_t gid);
@@ -735,13 +746,26 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable );
 BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable );
 long sys_random(void);
 void sys_srandom(unsigned int seed);
+int groups_max(void);
 int sys_getgroups(int setlen, gid_t *gidset);
-struct passwd *copy_passwd_struct(struct passwd *pass);
+int sys_setgroups(int setlen, gid_t *gidset);
 struct passwd *sys_getpwnam(const char *name);
 struct passwd *sys_getpwuid(uid_t uid);
+int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
+int wsys_creat(const smb_ucs2_t *wfname, mode_t mode);
+int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode);
+FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type);
+DIR *wsys_opendir(const smb_ucs2_t *wfname);
+smb_ucs2_t *wsys_getwd(smb_ucs2_t *s);
+int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid);
+int wsys_chroot(const smb_ucs2_t *wfname);
+FILE *sys_popen(const char *command, const char *mode, BOOL paranoid);
+int sys_pclose( FILE *fp);
 
 /*The following definitions come from  lib/talloc.c  */
 
+TALLOC_CTX *talloc_init(void);
 void *talloc(TALLOC_CTX *t, size_t size);
 void talloc_destroy(TALLOC_CTX *t);
 
@@ -807,45 +831,37 @@ char *tmpdir(void);
 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t * groups);
 uint32 get_number(const char *tmp);
 char *Atoic(char *p, int *n, char *c);
-uint32 *add_num_to_list(uint32 ** num, int *count, int val);
-char *get_numlist(char *p, uint32 ** num, int *count);
-void putip(void *dest, void *src);
+uint32 *add_num_to_list(uint32 **num, int *count, int val);
+char *get_numlist(char *p, uint32 **num, int *count);
 BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf);
 int file_rename(char *from, char *to);
 time_t file_modtime(char *fname);
 BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st);
 SMB_OFF_T file_size(char *file_name);
 char *attrib_string(uint16 mode);
-void unix_format(char *fname);
-void dos_format(char *fname);
 void show_msg(char *buf);
-int smb_len(char *buf);
-void _smb_setlen(char *buf, int len);
 void smb_setlen(char *buf, int len);
 int set_message(char *buf, int num_words, int num_bytes, BOOL zero);
-int smb_buflen(char *buf);
-char *smb_buf(char *buf);
-int smb_offset(char *p, char *buf);
 void dos_clean_name(char *s);
+void unix_clean_name(char *s);
+BOOL reduce_name(char *s, char *dir, BOOL widelinks);
+void expand_mask(char *Mask, BOOL doext);
 void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
                     int mode, time_t date);
 void close_low_fds(void);
 int set_blocking(int fd, BOOL set);
-int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew);
 SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n, char *header,
                        int headlen, int align);
 void msleep(int t);
-BOOL get_file_match(const char *dirname, const char *regexp,
-                   uint32 * total, char ***list);
-BOOL do_match(char *str, const char *regexp, int case_sig);
-BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2);
+BOOL unix_do_match(char *str, char *regexp, BOOL case_sig);
+BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2);
 void become_daemon(void);
 BOOL yesno(char *p);
 int set_filelen(int fd, SMB_OFF_T len);
+BOOL Memcpy(void *to, const void *from, size_t size);
 void *Realloc(void *p, size_t size);
 void safe_free(void *p);
 BOOL get_myname(char *my_name, struct in_addr *ip);
-BOOL ip_equal(struct in_addr ip1, struct in_addr ip2);
 int interpret_protocol(char *str, int def);
 uint32 interpret_addr(char *str);
 struct in_addr *interpret_addr2(char *str);
@@ -885,8 +901,7 @@ int str_checksum(const char *s);
 void zero_free(void *p, size_t size);
 int set_maxfiles(int requested_max);
 void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
-BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
-                  char *key_name);
+BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name);
 char *get_trusted_serverlist(const char *domain);
 uint16 pwdb_acct_ctrl_from_ad(NTDS_USER_FLAG_ENUM adac);
 char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
@@ -901,11 +916,13 @@ void pwdb_set_time_last_changed(char *p, int max_len, time_t t);
 void pwdb_set_must_change_time(char *p, int max_len, time_t t);
 void pwdb_set_last_set_time(char *p, int max_len, time_t t);
 void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl);
-BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl);
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl);
+char *smbd_mktemp(char *template);
 void *memdup(const void *p, size_t size);
 char *myhostname(void);
 char *passdb_path(char *name);
 char *lock_path(char *name);
+char *parent_dirname(const char *path);
 const char *get_sid_name_use_str(uint32 sid_name_use);
 
 /*The following definitions come from  lib/util_file.c  */
@@ -923,6 +940,7 @@ int getfileline(void *vp, char *linebuf, int linebuf_size);
 char *fgets_slash(char *s2,int maxlen,FILE *f);
 BOOL file_modified(const char *filename, time_t *lastmodified);
 void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified);
+SMB_OFF_T get_file_size(char *file_name);
 
 /*The following definitions come from  lib/util_hnd.c  */
 
@@ -1069,27 +1087,29 @@ BOOL trim_string(char *s,const char *front,const char *back);
 BOOL strhasupper(const char *s);
 BOOL strhaslower(const char *s);
 size_t count_chars(const char *s,char c);
+BOOL str_is_all(const char *s,char c);
 char *safe_strcpy(char *dest,const char *src, size_t maxlength);
 char *safe_strcat(char *dest, const char *src, size_t maxlength);
-char *StrCpy(char *dest,const char *src);
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength);
 char *StrnCpy(char *dest,const char *src,size_t n);
-char *strncpyn(char *dest, char *src,size_t n, char c);
+char *strncpyn(char *dest, const char *src,size_t n, char c);
 size_t strhex_to_str(char *p, size_t len, const char *strhex);
 BOOL in_list(char *s,char *list,BOOL casesensitive);
-BOOL string_init(char **dest,const char *src);
 void string_free(char **s);
 BOOL string_set(char **dest,const char *src);
-void string_sub(char *s,const char *pattern,const char *insert);
+void string_sub(char *s,const char *pattern,const char *insert, size_t len);
+void fstring_sub(char *s,const char *pattern,const char *insert);
+void pstring_sub(char *s,const char *pattern,const char *insert);
 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
 void split_at_first_component(char *path, char *front, char sep, char *back);
 void split_at_last_component(char *path, char *front, char sep, char *back);
 char *bit_field_to_str(uint32 type, struct field_info *bs);
 char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default);
+char *octal_string(int i);
 char *string_truncate(char *s, int length);
 
 /*The following definitions come from  lib/util_unistr.c  */
 
-int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
 char *ascii_to_unibuf(char *dest, const char *src, int maxlen);
 const char* unibuf_to_ascii(char *dest, const char *src, int maxlen);
 void ascii_to_unistr(uint16 *dest, const char *src, int maxlen);
@@ -1114,6 +1134,79 @@ void unistr2_free(UNISTR2 *name);
 int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt);
 BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2);
 
+/*The following definitions come from  lib/util_wunistr.c  */
+
+int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
+char *dos_unistrn2(uint16 *src, int len);
+char *dos_unistr2(uint16 *src);
+char *dos_unistr2_to_str(UNISTR2 *str);
+char *dos_buffer2_to_str(BUFFER2 *str);
+char *dos_buffer2_to_multistr(BUFFER2 *str);
+size_t dos_struni2(char *dst, const char *src, size_t max_len);
+char *dos_unistr(char *buf);
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
+BOOL load_dos_unicode_map(int codepage);
+BOOL load_unix_unicode_map(const char *unix_char_set);
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+                                 size_t dst_len, smb_ucs2_t *cp_to_ucs2);
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len);
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len);
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+size_t strlen_w(const smb_ucs2_t *src);
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength);
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len);
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2);
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s);
+int isupper_w( smb_ucs2_t val);
+int islower_w( smb_ucs2_t val);
+int isdigit_w( smb_ucs2_t val);
+int isxdigit_w( smb_ucs2_t val);
+int isspace_w( smb_ucs2_t val);
+smb_ucs2_t toupper_w( smb_ucs2_t val );
+smb_ucs2_t tolower_w( smb_ucs2_t val );
+void set_first_token_w(smb_ucs2_t *ptr);
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize);
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep);
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t);
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n);
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n);
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2);
+void strlower_w(smb_ucs2_t *s);
+void strupper_w(smb_ucs2_t *s);
+void strnorm_w(smb_ucs2_t *s);
+BOOL strisnormal_w(smb_ucs2_t *s);
+void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc);
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n);
+size_t str_charnum_w(const smb_ucs2_t *s);
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back);
+BOOL strhasupper_w(const smb_ucs2_t *s);
+BOOL strhaslower_w(const smb_ucs2_t *s);
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c);
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c);
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n);
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c);
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex);
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive);
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_free_w(smb_ucs2_t **s);
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert);
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert);
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back);
+smb_ucs2_t *octal_string_w(int i);
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length);
+
 /*The following definitions come from  lib/vagent.c  */
 
 void init_sock_redir(struct vagent_ops*va);
@@ -1146,15 +1239,35 @@ BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct **usr);
 BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
 BOOL vuid_init_db(void);
 
+/*The following definitions come from  locking/brlock.c  */
+
+void brl_init(int read_only);
+BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+             uint16 smbpid, pid_t pid, uint16 tid,
+             br_off start, br_off size, 
+             enum brl_type lock_type);
+BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+               uint16 smbpid, pid_t pid, uint16 tid,
+               br_off start, br_off size);
+BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, 
+                 uint16 smbpid, pid_t pid, uint16 tid,
+                 br_off start, br_off size, 
+                 enum brl_type lock_type);
+void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum);
+int brl_forall(BRLOCK_FN(fn));
+
 /*The following definitions come from  locking/locking.c  */
 
+void locking_close_file(files_struct *fsp);
 BOOL is_locked(files_struct *fsp,connection_struct *conn,
-              SMB_OFF_T count,SMB_OFF_T offset, int lock_type);
+              SMB_OFF_T count,SMB_OFF_T offset, 
+              enum brl_type lock_type);
 BOOL do_lock(files_struct *fsp,connection_struct *conn,
-             SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
+             SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
              int *eclass,uint32 *ecode);
 BOOL do_unlock(files_struct *fsp,connection_struct *conn,
-               SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode);
+               SMB_OFF_T count,SMB_OFF_T offset, 
+              int *eclass,uint32 *ecode);
 BOOL locking_init(int read_only);
 BOOL locking_end(void);
 BOOL lock_share_entry(connection_struct *conn,
@@ -1169,7 +1282,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
 BOOL remove_share_oplock(files_struct *fsp);
 BOOL downgrade_share_oplock(files_struct *fsp);
 BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock);
-int share_mode_forall(void (*fn)(share_mode_entry *, char *));
+int share_mode_forall(SHAREMODE_FN(fn));
 
 /*The following definitions come from  lsarpcd/lsarpcd.c  */
 
@@ -1221,6 +1334,31 @@ uint32 _lsa_open_secret(const POLICY_HND * hnd,
                        const UNISTR2 * secret_name, uint32 des_access,
                        POLICY_HND * hnd_secret);
 
+/*The following definitions come from  msdfs/msdfs.c  */
+
+BOOL dfs_redirect(char* pathname, connection_struct* conn);
+BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn);
+int setup_dfs_referral(char* pathname, int max_referral_level, 
+                       char** ppdata);
+int dfs_path_error(char* inbuf, char* outbuf);
+int setup_dfs_referral(char* pathname, int max_referral_level, 
+                      char** ppdata);
+void unistr_to_dos(char* dst,char* src)               ;
+
+/*The following definitions come from  msdfs/msdfs_tdb.c  */
+
+BOOL msdfs_open(BOOL update);
+BOOL add_junction_entry(struct junction_map* junction);
+BOOL get_junction_entry(struct junction_map* junction);
+BOOL isDfsShare(char* svc,char* vol);
+void msdfs_close(void);
+void msdfs_end(void);
+
+/*The following definitions come from  msdfs/parse_dfs_map.c  */
+
+void load_dfsmaps(void);
+void load_dfsmaps(void);
+
 /*The following definitions come from  msrpc/msrpcd.c  */
 
 void exit_server(char *reason);
@@ -1646,7 +1784,6 @@ void expire_workgroups_and_servers(time_t t);
 /*The following definitions come from  param/loadparm.c  */
 
 void lp_talloc_free(void);
-struct vfs_options *lp_vfsoptions(int i) ;
 char *lp_logfile(void);
 char *lp_smbrun(void);
 char *lp_configfile(void);
@@ -1658,9 +1795,12 @@ char *lp_smb_alias_file(void);
 char *lp_serverstring(void);
 char *lp_printcapname(void);
 char *lp_lockdir(void);
+char *lp_utmpdir(void);
 char *lp_rootdir(void);
+char *lp_source_environment(void);
 char *lp_defaultservice(void);
 char *lp_msg_command(void);
+char *lp_dfree_command(void);
 char *lp_hosts_equiv(void);
 char *lp_auto_services(void);
 char *lp_passwd_program(void);
@@ -1679,16 +1819,17 @@ char *lp_ntusrname_map(void);
 char *lp_remote_announce(void);
 char *lp_remote_browse_sync(void);
 char *lp_wins_server(void);
-char *lp_wins_hook(void);
 char *lp_interfaces(void);
 char *lp_socket_address(void);
 char *lp_nis_home_map_name(void);
 char *lp_netbios_aliases(void);
 char *lp_driverfile(void);
 char *lp_panic_action(void);
+char *lp_adduser_script(void);
+char *lp_deluser_script(void);
+char *lp_wins_hook(void);
 char *lp_nt_forms(void);
 char *lp_nt_drivers_file(void);
-char *lp_dfs_map(void);
 char *lp_ldap_server(void);
 char *lp_ldap_suffix(void);
 char *lp_ldap_bind_as(void);
@@ -1746,7 +1887,9 @@ BOOL lp_passwd_chat_debug(void);
 BOOL lp_ole_locking_compat(void);
 BOOL lp_nt_smb_support(void);
 BOOL lp_nt_pipe_support(void);
+BOOL lp_nt_acl_support(void);
 BOOL lp_stat_cache(void);
+BOOL lp_host_msdfs(void);
 int lp_os_level(void);
 int lp_max_ttl(void);
 int lp_max_wins_ttl(void);
@@ -1817,6 +1960,10 @@ char *lp_veto_files(int );
 char *lp_hide_files(int );
 char *lp_veto_oplocks(int );
 char *lp_driverlocation(int );
+char *lp_dfsmap(int );
+BOOL lp_dfsmap_loaded(int );
+BOOL lp_preexec_close(int );
+BOOL lp_rootpreexec_close(int );
 BOOL lp_revalidate(int );
 BOOL lp_casesensitive(int );
 BOOL lp_preservecase(int );
@@ -1835,8 +1982,10 @@ BOOL lp_map_hidden(int );
 BOOL lp_map_archive(int );
 BOOL lp_locking(int );
 BOOL lp_strict_locking(int );
+BOOL lp_utmp(int );
 BOOL lp_share_modes(int );
 BOOL lp_oplocks(int );
+BOOL lp_level2_oplocks(int );
 BOOL lp_onlyuser(int );
 BOOL lp_manglednames(int );
 BOOL lp_widelinks(int );
@@ -1851,14 +2000,21 @@ BOOL lp_dos_filetimes(int );
 BOOL lp_dos_filetime_resolution(int );
 BOOL lp_fake_dir_create_times(int );
 BOOL lp_blocking_locks(int );
-int lp_create_mode(int );
+BOOL lp_inherit_perms(int );
+int lp_create_mask(int );
 int lp_force_create_mode(int );
-int lp_dir_mode(int );
+int _lp_security_mask(int );
+int _lp_force_security_mode(int );
+int lp_dir_mask(int );
 int lp_force_dir_mode(int );
+int _lp_dir_security_mask(int );
+int _lp_force_dir_security_mode(int );
 int lp_max_connections(int );
 int lp_defaultcase(int );
 int lp_minprintspace(int );
 int lp_printing(int );
+int lp_oplock_contention_limit(int );
+int lp_write_cache_size(int );
 char lp_magicchar(int );
 char *lp_mysql_host(void);
 char *lp_mysql_user(void);
@@ -1869,6 +2025,7 @@ BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
 int lp_add_service(char *pszService, int iDefaultService);
 BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
 BOOL lp_file_list_changed(void);
+void set_dfsmap_loaded(int i,BOOL b);
 void *lp_local_ptr(int snum, void *ptr);
 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue);
 BOOL lp_is_default(int snum, struct parm_struct *parm);
@@ -1878,11 +2035,15 @@ void lp_add_one_printer(char *name,char *comment);
 BOOL lp_loaded(void);
 void lp_killunused(BOOL (*snumused)(int ));
 BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc);
+void lp_resetnumservices(void);
 int lp_numservices(void);
-void lp_dump(FILE *f, BOOL show_defaults);
+void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint);
 void lp_dump_one(FILE *f, BOOL show_defaults, int snum);
 int lp_servicenumber(char *pszServiceName);
 char *volume_label(int snum);
+int lp_server_role(void);
+BOOL lp_domain_master(void);
+BOOL lp_preferred_master(void);
 void lp_remove_service(int snum);
 void lp_copy_service(int snum, char *new_name);
 int lp_default_server_announce(void);
@@ -1891,9 +2052,10 @@ int lp_minor_announce_version(void);
 void lp_set_name_resolve_order(char *new_order);
 void lp_set_kernel_oplocks(BOOL val);
 BOOL lp_kernel_oplocks(void);
-int lp_server_role(void);
-BOOL lp_domain_master(void);
-BOOL lp_preferred_master(void);
+int lp_security_mask(int snum);
+int lp_force_security_mode(int snum);
+int lp_dir_security_mask(int snum);
+int lp_force_dir_security_mode(int snum);
 
 /*The following definitions come from  param/params.c  */
 
@@ -3311,63 +3473,65 @@ BOOL smb_io_unistr3(char *desc,  UNISTR3 *name, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_net.c  */
 
-BOOL make_log_info(DOM_LOG_INFO *log,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name);
-BOOL smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps, int depth);
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
-                               const char *logon_srv, const char *comp_name,
-                               DOM_CRED *clnt_cred);
-BOOL smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name,
-                               DOM_CRED *cred);
-BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO * log,
+                  const char *logon_srv, const char *acct_name,
+                  uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+                    int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+                    const char *logon_srv, const char *comp_name,
+                    DOM_CRED * clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+                      int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+                   const char *logon_srv, const char *acct_name,
+                   uint16 sec_chan, const char *comp_name, DOM_CRED * cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+                     int depth);
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth);
 BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 * q_l,
                        const char *srv_name,
                        uint32 function_code,
                        uint32 query_level, uint32 switch_value);
 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
                        uint32 switch_value,
                        NETLOGON_INFO * logon_info, uint32 status);
 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_q_req_chal(NET_Q_REQ_CHAL * q_c,
                     const char *logon_srv, const char *logon_clnt,
                     DOM_CHAL * clnt_chal);
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
                       int depth);
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
                       int depth);
 BOOL make_q_auth(NET_Q_AUTH * q_a,
                 const char *logon_srv, const char *acct_name,
                 uint16 sec_chan, const char *comp_name, DOM_CHAL * clnt_chal);
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth);
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth);
 BOOL make_q_auth_2(NET_Q_AUTH_2 * q_a,
                   const char *logon_srv, const char *acct_name,
                   uint16 sec_chan, const char *comp_name,
                   DOM_CHAL * clnt_chal, uint32 clnt_flgs);
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
                     int depth);
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
                     int depth);
 BOOL make_q_srv_pwset(NET_Q_SRV_PWSET * q_s,
                      const char *logon_srv, const char *acct_name,
                      uint16 sec_chan, const char *comp_name,
                      DOM_CRED * cred, char nt_cypher[16]);
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
                        int depth);
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
                        int depth);
 BOOL make_id_info1(NET_ID_INFO_1 * id, const char *domain_name,
                   uint32 param_ctrl,
@@ -3402,12 +3566,12 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -3416,9 +3580,9 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
-                         const char *padding, const DOM_SID * dom_sid);
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
+                         const char *padding, const DOM_SID *dom_sid);
 BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
                         NTTIME * logon_time,
                         NTTIME * logoff_time,
@@ -3441,11 +3605,11 @@ BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
                         uint32 user_flgs,
                         char sess_key[16],
                         char *logon_srv,
-                        char *logon_dom, char *padding, DOM_SID * dom_sid);
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+                        char *logon_dom, char *padding, DOM_SID *dom_sid);
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
                       int depth);
 BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
-               const NET_USER_INFO_CTR *ctr);
+                                  const NET_USER_INFO_CTR * ctr);
 BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const NTTIME * logon_time,
                          const NTTIME * logoff_time,
@@ -3453,12 +3617,12 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -3467,10 +3631,10 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
                          const char *padding,
-                         const DOM_SID * dom_sid, const char *other_sids);
+                         const DOM_SID *dom_sid, const char *other_sids);
 BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
                         NTTIME * logon_time,
                         NTTIME * logoff_time,
@@ -3494,45 +3658,44 @@ BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
                         char sess_key[16],
                         char *logon_srv,
                         char *logon_dom,
-                        char *padding, DOM_SID * dom_sid, char *other_sids);
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+                        char *padding, DOM_SID *dom_sid, char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
                       int depth);
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
                        int depth);
 BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
                      const DOM_CRED * srv_creds,
-                     uint16 switch_value,
-                     void *id, uint32 status);
+                     uint16 switch_value, void *id, uint32 status);
 BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 void free_net_user_info_ctr(NET_USER_INFO_CTR * ctr);
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
                        int depth);
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
                         int depth);
 BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF * r_s,
                       const DOM_CRED * srv_cred, uint32 status);
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
                         int depth);
 BOOL make_q_sam_sync(NET_Q_SAM_SYNC * q_s,
                     const char *srv_name,
                     const char *cli_name,
                     DOM_CRED * cli_creds, uint32 database_id);
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
                       int depth);
 BOOL make_sam_delta_hdr(SAM_DELTA_HDR * delta, uint16 type, uint32 rid);
 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name,
                           uint32 user_rid, uint32 group_rid,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * desc,
+                          const UNISTR2 *home_dir,
+                          const UNISTR2 *dir_drive,
+                          const UNISTR2 *log_scr,
+                          const UNISTR2 *desc,
                           uint32 acb_info,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str, const UNISTR2 * mung_dial);
+                          const UNISTR2 *prof_path,
+                          const UNISTR2 *wkstas,
+                          const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
 BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
                     const DOM_CRED * srv_cred,
                     uint32 sync_context,
@@ -3541,30 +3704,29 @@ BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
                     SAM_DELTA_HDR * hdr_deltas,
                     SAM_DELTA_CTR * deltas, uint32 status);
 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
-                      NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth);
+                      NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_netsec.c  */
 
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
-                               fstring domain,
-                               fstring myname);
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
-                               const uchar sig[8],
-                               const uchar data1[8],
-                               const uchar data3[8],
-                               const uchar data8[8]);
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+                             fstring domain, fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+                               prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+                                prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+                             const uchar sig[8],
+                             const uchar data1[8],
+                             const uchar data3[8], const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+                               prs_struct *ps, int depth);
 BOOL netsec_encode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len);
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
 BOOL netsec_decode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len);
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
 
 /*The following definitions come from  rpc_parse/parse_ntlmssp.c  */
 
@@ -3712,21 +3874,23 @@ BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER * rav,
 
 /*The following definitions come from  rpc_parse/parse_sec.c  */
 
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
-void free_sec_acl(SEC_ACL *t);
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
-                       DOM_SID *owner_sid, DOM_SID *grp_sid,
-                               SEC_ACL *sacl, SEC_ACL *dacl);
-void free_sec_desc(SEC_DESC *t);
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
-void free_sec_desc_buf(SEC_DESC_BUF *buf);
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+                 SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace);
+void free_sec_acl(SEC_ACL * t);
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+                 DOM_SID *owner_sid, DOM_SID *grp_sid,
+                 SEC_ACL * sacl, SEC_ACL * dacl);
+void free_sec_desc(SEC_DESC * t);
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data);
+void free_sec_desc_buf(SEC_DESC_BUF * buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+                    int depth);
 
 /*The following definitions come from  rpc_parse/parse_vuid.c  */
 
@@ -3803,11 +3967,11 @@ BOOL rpc_local(rpcsrv_struct * l, char *data, int len, const char *name);
 
 /*The following definitions come from  rpc_server/srv_reg.c  */
 
-BOOL api_reg_rpc(rpcsrv_struct *p);
+BOOL api_reg_rpc(rpcsrv_struct * p);
 
 /*The following definitions come from  rpc_server/srv_samr.c  */
 
-BOOL api_samr_rpc(rpcsrv_struct *p);
+BOOL api_samr_rpc(rpcsrv_struct * p);
 
 /*The following definitions come from  rpc_server/srv_spoolss.c  */
 
@@ -3819,7 +3983,7 @@ BOOL api_srvsvc_rpc(rpcsrv_struct * p);
 
 /*The following definitions come from  rpc_server/srv_svcctl.c  */
 
-BOOL api_svcctl_rpc(rpcsrv_struct *p);
+BOOL api_svcctl_rpc(rpcsrv_struct * p);
 
 /*The following definitions come from  rpc_server/srv_wkssvc.c  */
 
@@ -4206,14 +4370,13 @@ uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
 
 BOOL tdb_lookup_user(TDB_CONTEXT * tdb, SAM_USER_INFO_21 * usr);
 uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
-                              uint16 * unknown_0,
-                              uint16 *unknown_1,
-                              uint32 * unknown_2);
+                              uint16 *unknown_0,
+                              uint16 *unknown_1, uint32 *unknown_2);
 uint32 _samr_query_usergroups(const POLICY_HND *pol,
-                             uint32 * num_groups, DOM_GID ** gids);
+                             uint32 *num_groups, DOM_GID ** gids);
 uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
-                              const uint32 * ptr_sid, const DOM_SID2 * sid,
-                              uint32 * num_aliases, uint32 ** rid);
+                              const uint32 *ptr_sid, const DOM_SID2 * sid,
+                              uint32 *num_aliases, uint32 **rid);
 uint32 _samr_open_user(const POLICY_HND *domain_pol,
                       uint32 access_mask, uint32 user_rid,
                       POLICY_HND *user_pol);
@@ -4224,10 +4387,10 @@ uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
 uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
                           SAM_USERINFO_CTR * ctr);
 uint32 _samr_create_user(const POLICY_HND *domain_pol,
-                        const UNISTR2 * uni_username,
+                        const UNISTR2 *uni_username,
                         uint16 acb_info, uint32 access_mask,
                         POLICY_HND *user_pol,
-                        uint32 * unknown_0, uint32 * user_rid);
+                        uint32 *unknown_0, uint32 *user_rid);
 uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
 
 /*The following definitions come from  smbd/afsticket.c  */
@@ -4240,6 +4403,7 @@ pid_t get_renewed_ticket(connection_struct* conn);
 BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
 void remove_pending_lock_requests_by_fid(files_struct *fsp);
 void remove_pending_lock_requests_by_mid(int mid);
+BOOL blocking_locks_pending(void);
 void process_blocking_lock_queue(time_t t);
 
 /*The following definitions come from  smbd/challenge.c  */
@@ -4261,8 +4425,7 @@ BOOL update_smbpassword_file(const char *user, const char *password);
 
 /*The following definitions come from  smbd/close.c  */
 
-void close_file(files_struct *fsp, BOOL normal_close);
-void close_directory(files_struct *fsp);
+int close_file(files_struct *fsp, BOOL normal_close);
 
 /*The following definitions come from  smbd/conn.c  */
 
@@ -4282,13 +4445,8 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
 
 /*The following definitions come from  smbd/dfree.c  */
 
-SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
-
-/*The following definitions come from  smbd/dfs.c  */
-
-BOOL init_dfs_table(void);
-int under_dfs(connection_struct *conn, const char *path,
-                               char *local_path, size_t local_plen);
+SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query, 
+                           SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
 
 /*The following definitions come from  smbd/dir.c  */
 
@@ -4298,13 +4456,12 @@ char *dptr_wcard(int key);
 BOOL dptr_set_wcard(int key, char *wcard);
 BOOL dptr_set_attr(int key, uint16 attr);
 uint16 dptr_attr(int key);
-void dptr_close(int key);
+void dptr_close(int *key);
 void dptr_closecnum(connection_struct *conn);
 void dptr_idlecnum(connection_struct *conn);
-void dptr_closepath(char *path,int pid);
-int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid);
+void dptr_closepath(char *path,uint16 spid);
+int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid);
 BOOL dptr_fill(char *buf1,unsigned int key);
-BOOL dptr_zero(char *buf);
 void *dptr_fetch(char *buf,int *num);
 void *dptr_fetch_lanman2(int dptr_num);
 BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype);
@@ -4321,7 +4478,7 @@ void DirCacheFlush(int snum);
 
 /*The following definitions come from  smbd/dosmode.c  */
 
-mode_t unix_mode(connection_struct *conn,int dosmode);
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname);
 int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
 int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st);
 int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
@@ -4336,20 +4493,21 @@ int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int
 /*The following definitions come from  smbd/fileio.c  */
 
 SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos);
+BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
 ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
-ssize_t write_file(files_struct *fsp,char *data,size_t n);
-void sys_sync_file(int fd);
+ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n);
+void delete_write_cache(files_struct *fsp);
+void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T filesize);
+ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
+void sys_fsync_file(connection_struct *conn, files_struct *fsp);
 
 /*The following definitions come from  smbd/filename.c  */
 
 void print_stat_cache_statistics(void);
-BOOL unix_dfs_convert(char *name,connection_struct *conn,
-                               char *saved_last_component, 
-                               BOOL *bad_path, SMB_STRUCT_STAT *pst);
-BOOL unix_convert(char *name,connection_struct *conn,
-                               char *saved_last_component, 
-                               BOOL *bad_path, SMB_STRUCT_STAT *pst);
+BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, 
+                  BOOL *bad_path, SMB_STRUCT_STAT *pst);
 BOOL check_name(char *name,connection_struct *conn);
+BOOL reset_stat_cache( void );
 
 /*The following definitions come from  smbd/files.c  */
 
@@ -4374,16 +4532,17 @@ void file_chain_restore(void);
 /*The following definitions come from  smbd/ipc.c  */
 
 void send_trans_reply(char *outbuf,
-                               prs_struct *rdata,
-                               prs_struct *rparam,
-                               uint16 *setup, int lsetup, int max_data_ret,
-                               BOOL pipe_data_outstanding);
-int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize);
+                     prs_struct *rdata,
+                     prs_struct *rparam,
+                     uint16 *setup, int lsetup, int max_data_ret,
+                     BOOL pipe_data_outstanding);
+int reply_trans(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int bufsize);
 
 /*The following definitions come from  smbd/lanman.c  */
 
-int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
-                    int tdscnt,int tpscnt,int mdrcnt,int mprcnt);
+int api_reply(connection_struct * conn, uint16 vuid, char *outbuf, char *data,
+             char *params, int tdscnt, int tpscnt, int mdrcnt, int mprcnt);
 
 /*The following definitions come from  smbd/mangle.c  */
 
@@ -4392,7 +4551,7 @@ BOOL is_8_3( char *fname, BOOL check_case );
 void reset_mangled_cache( void );
 BOOL check_mangled_cache( char *s );
 void mangle_name_83( char *s);
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum);
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum);
 
 /*The following definitions come from  smbd/message.c  */
 
@@ -4418,6 +4577,7 @@ BOOL disk_quotas(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT
 /*The following definitions come from  smbd/nttrans.c  */
 
 void fail_next_srvsvc_open(void);
+BOOL should_fail_next_srvsvc_open(const char *pipename);
 int reply_ntcreate_and_X(connection_struct *conn,
                         char *inbuf,char *outbuf,int length,int bufsize);
 int reply_ntcancel(connection_struct *conn,
@@ -4425,30 +4585,36 @@ int reply_ntcancel(connection_struct *conn,
 int reply_nttranss(connection_struct *conn,
                   char *inbuf,char *outbuf,int length,int bufsize);
 void remove_pending_change_notify_requests_by_fid(files_struct *fsp);
-void process_pending_change_notify_queue(time_t t);
+void remove_pending_change_notify_requests_by_filename(files_struct *fsp);
+BOOL process_pending_change_notify_queue(time_t t);
+BOOL change_notifies_pending(void);
 int reply_nttrans(connection_struct *conn,
                  char *inbuf,char *outbuf,int length,int bufsize);
 
 /*The following definitions come from  smbd/open.c  */
 
 void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u);
-uint16 fd_attempt_close(files_struct *fsp);
-void open_file_shared(files_struct *fsp, connection_struct *conn,
-                          char *fname, int share_mode, int ofun, 
-                          mode_t mode, int oplock_request, int *Access,
-                          int *action);
+uint16 fd_attempt_close(files_struct *fsp, int *err_ret);
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
+                     mode_t mode,int oplock_request, int *Access,int *action);
+int open_file_stat(files_struct *fsp,connection_struct *conn,
+                  char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action);
 int open_directory(files_struct *fsp,connection_struct *conn,
                   char *fname, int smb_ofun, mode_t unixmode, int *action);
 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
 
 /*The following definitions come from  smbd/oplock.c  */
 
+int32 get_number_of_exclusive_open_oplocks(void);
 BOOL setup_kernel_oplock_pipe(void);
 BOOL open_oplock_ipc(void);
 BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout);
-BOOL set_file_oplock(files_struct *fsp);
+BOOL set_file_oplock(files_struct *fsp, int oplock_type);
+void release_file_oplock(files_struct *fsp);
+BOOL remove_oplock(files_struct *fsp);
 int setup_oplock_select_set( fd_set *fds);
 BOOL process_local_message(char *buffer, int buf_size);
+BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token);
 BOOL request_oplock_break(share_mode_entry *share_entry, 
                           SMB_DEV_T dev, SMB_INO_T inode);
 BOOL attempt_close_oplocked_file(files_struct *fsp);
@@ -4458,24 +4624,24 @@ void check_kernel_oplocks(void);
 
 void add_session_user(char *user);
 BOOL password_ok(const char *orig_user, const char *domain,
-                               const char *smb_apasswd, int smb_apasslen,
-                               const char *smb_ntpasswd, int smb_ntpasslen,
-                               struct passwd *pwd,
-                               NET_USER_INFO_3 *info3);
+                const char *smb_apasswd, int smb_apasslen,
+                const char *smb_ntpasswd, int smb_ntpasslen,
+                struct passwd *pwd, NET_USER_INFO_3 * info3);
 BOOL authorise_login(int snum, char *user, char *domain,
-                               char *password, int pwlen, 
-                               BOOL *guest,BOOL *force,
-                               const vuser_key *key);
+                    char *password, int pwlen,
+                    BOOL *guest, BOOL *force, const vuser_key * key);
+BOOL check_user_equiv_line(char *buf, const char *user, const char *remote,
+                          BOOL *plus_allowed, BOOL *ret);
 BOOL check_hosts_equiv(char *user);
 
 /*The following definitions come from  smbd/pipes.c  */
 
-int reply_open_pipe_and_X(connection_struct *conn,
-                         char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
+int reply_open_pipe_and_X(connection_struct * conn,
+                         char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_write(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_write_and_X(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_read_and_X(char *inbuf, char *outbuf, int length, int bufsize);
+int reply_pipe_close(connection_struct * conn, char *inbuf, char *outbuf);
 
 /*The following definitions come from  smbd/predict.c  */
 
@@ -4487,10 +4653,12 @@ void invalidate_read_prediction(int fd);
 
 BOOL push_oplock_pending_smb_message(char *buf, int msg_len);
 BOOL receive_next_smb(char *inbuf, int bufsize, int timeout);
+void respond_to_all_remaining_local_messages(void);
 void process_smb(char *inbuf, char *outbuf);
 char *smb_fn_name(int type);
 void construct_reply_common(char *inbuf,char *outbuf);
 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
+void check_reload(int t);
 void smbd_process(void);
 
 /*The following definitions come from  smbd/reply.c  */
@@ -4533,33 +4701,32 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf,
                   int dum_size, int dum_buffsize);
 int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf,
                   int length, int dum_buffsiz);
-int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
-              int dum_size, int dum_buffsize);
+int reply_read(connection_struct * conn, char *inbuf, char *outbuf, int size,
+              int dum_buffsize);
 int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                     int length, int bufsize);
 int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
-                   int dum_size, int dum_buffsize);
+                   int size, int dum_buffsize);
 int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
-                     int dum_size, int dum_buffsize);
-int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize);
+                     int size, int dum_buffsize);
+int reply_write(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize);
 int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                      int length, int bufsize);
-int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize);
-int reply_flush(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize);
+int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize);
+int reply_flush(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize);
 int reply_exit(connection_struct * conn,
               char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
-int reply_close(connection_struct * conn,
-               char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
+int reply_close(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize);
 int reply_writeclose(connection_struct * conn,
-                    char *inbuf, char *outbuf, int dum_size,
-                    int dum_buffsize);
+                    char *inbuf, char *outbuf, int size, int dum_buffsize);
 int reply_lock(connection_struct * conn,
               char *inbuf, char *outbuf, int length, int dum_buffsize);
 int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf,
-                int dum_size, int dum_buffsize);
+                int size, int dum_buffsize);
 int reply_tdis(connection_struct * conn,
               char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
 int reply_echo(connection_struct * conn,
@@ -4576,6 +4743,7 @@ int reply_printwrite(connection_struct * conn, char *inbuf, char *outbuf,
                     int dum_size, int dum_buffsize);
 int reply_mkdir(connection_struct * conn, char *inbuf, char *outbuf,
                int dum_size, int dum_buffsize);
+BOOL rmdir_internals(connection_struct * conn, char *directory);
 int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
                int dum_size, int dum_buffsize);
 int rename_internals(connection_struct * conn,
@@ -4587,18 +4755,22 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
               int dum_size, int dum_buffsize);
 int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf,
                 int dum_size, int dum_buffsize);
+SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
+                        BOOL *err);
+SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
+                         BOOL *err);
 int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
                   int length, int bufsize);
 int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf,
                   int length, int bufsize);
 int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
-                   int dum_size, int dum_buffsize);
+                   int size, int dum_buffsize);
 int reply_writebs(connection_struct * conn, char *inbuf, char *outbuf,
                  int dum_size, int dum_buffsize);
 int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf,
-                  int dum_size, int dum_buffsize);
+                  int size, int dum_buffsize);
 int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf,
-                  int dum_size, int dum_buffsize);
+                  int size, int dum_buffsize);
 
 /*The following definitions come from  smbd/server.c  */
 
@@ -4646,6 +4818,8 @@ BOOL unbecome_user(void );
 
 int vfs_init_default(connection_struct *conn);
 BOOL vfs_init_custom(connection_struct *conn);
+BOOL vfs_directory_exist(connection_struct *conn, char *dname,
+                         SMB_STRUCT_STAT *st);
 BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
 ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
 SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, 
@@ -4658,7 +4832,7 @@ char *vfs_readdirname(connection_struct *conn, void *p);
 int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service,
                          char *user);
 void vfswrap_dummy_disconnect(void);
-SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize, 
+SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                               SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
 DIR *vfswrap_opendir(char *fname);
 struct dirent *vfswrap_readdir(DIR *dirp);
@@ -4671,13 +4845,11 @@ ssize_t vfswrap_read(int fd, char *data, size_t n);
 ssize_t vfswrap_write(int fd, char *data, size_t n);
 SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence);
 int vfswrap_rename(char *old, char *new);
-void vfswrap_sync_file(int fd);
+void vfswrap_fsync(int fd);
 int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf);
 int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf);
 int vfswrap_lstat(char *path, 
                  SMB_STRUCT_STAT *sbuf);
-BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, 
-                       int type);
 int vfswrap_unlink(char *path);
 int vfswrap_chmod(char *path, mode_t mode);
 int vfswrap_utime(char *path, struct utimbuf *times);
index cf48383cca5c0eed8f5d95caa706e37ecee1cfb8..cd1f0a44fbc362c428a0d2618f4d401080861dcc 100644 (file)
@@ -242,109 +242,140 @@ BOOL smb_io_unistr3(char *desc,  UNISTR3 *name, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_netsec.c  */
 
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
-                               fstring domain,
-                               fstring myname);
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
-                               const uchar sig[8],
-                               const uchar data1[8],
-                               const uchar data3[8],
-                               const uchar data8[8]);
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+                             fstring domain, fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+                               prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+                                prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+                             const uchar sig[8],
+                             const uchar data1[8],
+                             const uchar data3[8], const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+                               prs_struct *ps, int depth);
 BOOL netsec_encode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len);
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
 BOOL netsec_decode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len);
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len);
 
 /*The following definitions come from  rpc_parse/parse_reg.c  */
 
-BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
-                               uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hkcr(char *desc,  REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hkcr(char *desc,  REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
-                               uint16 unknown_0, uint32 access_mask);
-BOOL reg_io_q_open_hklm(char *desc,  REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hklm(char *desc,  REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
-BOOL reg_io_q_flush_key(char *desc,  REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_flush_key(char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
-                               char *key_name, char *key_class,
-                               SEC_ACCESS *sam_access,
-                               SEC_DESC_BUF *sec_buf,
-                               int sec_len, SEC_DESC *sec);
-BOOL reg_io_q_create_key(char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_key(char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
-                               char *name);
-BOOL reg_io_q_delete_val(char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_val(char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
-                               char *name);
-BOOL reg_io_q_delete_key(char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_key(char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
-                               uint32 max_class_len);
-BOOL reg_io_q_query_key(char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_query_key(char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd);
-BOOL reg_io_q_unk_1a(char *desc,  REG_Q_UNK_1A *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_unk_1a(char *desc,  REG_R_UNK_1A *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
-                               uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hku(char *desc,  REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hku(char *desc,  REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL reg_io_q_close(char *desc,  REG_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL reg_io_r_close(char *desc,  REG_R_CLOSE *r_u, prs_struct *ps, int depth);
-BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
-                               uint32 sec_info,
-                               uint32 buf_len, SEC_DESC *sec_desc);
-BOOL reg_io_q_set_key_sec(char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, 
-                               uint32 sec_info,
-                               uint32 buf_len, SEC_DESC_BUF *sec_buf);
-BOOL reg_io_q_get_key_sec(char *desc,  REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_get_key_sec(char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
-                               uint8 major, uint8 minor);
-BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth);
-BOOL make_reg_r_info(REG_R_INFO *r_r,
-                               uint32 *type, BUFFER2 *buf,
-                               uint32 status);
-BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
-                               uint32 val_idx, uint32 max_val_len,
-                               uint32 max_buf_len);
-BOOL reg_io_q_enum_val(char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_val(char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
-                               char *val_name, uint32 type,
-                               BUFFER3 *val);
-BOOL reg_io_q_create_val(char *desc,  REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_val(char *desc,  REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx);
-BOOL reg_io_q_enum_key(char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_key(char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth);
-BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
-                               char *key_name, uint32 access_mask);
-BOOL reg_io_q_open_entry(char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
-BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
-                               POLICY_HND *pol, uint32 status);
-BOOL reg_io_r_open_entry(char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
-BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
-                               const char *msg, uint32 timeout, uint16 flags);
-BOOL reg_io_q_shutdown(char *desc,  REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_shutdown(char *desc,  REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR * q_o,
+                         uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR * r_q, prs_struct *ps,
+                       int depth);
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR * r_r, prs_struct *ps,
+                       int depth);
+BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+                         uint16 unknown_0, uint32 access_mask);
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+                       int depth);
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+                       int depth);
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY * q_u, POLICY_HND *pol);
+BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY * r_q, prs_struct *ps,
+                       int depth);
+BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY * r_r, prs_struct *ps,
+                       int depth);
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY * q_c, POLICY_HND *hnd,
+                          char *key_name, char *key_class,
+                          SEC_ACCESS * sam_access,
+                          SEC_DESC_BUF * sec_buf,
+                          int sec_len, SEC_DESC * sec);
+BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY * r_q, prs_struct *ps,
+                        int depth);
+BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY * r_r, prs_struct *ps,
+                        int depth);
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE * q_c, POLICY_HND *hnd,
+                          char *name);
+BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE * r_q, prs_struct *ps,
+                        int depth);
+BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE * r_r, prs_struct *ps,
+                        int depth);
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY * q_c, POLICY_HND *hnd,
+                          char *name);
+BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY * r_q, prs_struct *ps,
+                        int depth);
+BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY * r_r, prs_struct *ps,
+                        int depth);
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY * q_o, POLICY_HND *hnd,
+                         uint32 max_class_len);
+BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY * r_q, prs_struct *ps,
+                       int depth);
+BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY * r_r, prs_struct *ps,
+                       int depth);
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A * q_o, POLICY_HND *hnd);
+BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A * r_q, prs_struct *ps,
+                    int depth);
+BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A * r_r, prs_struct *ps,
+                    int depth);
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU * q_o, uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU * r_q, prs_struct *ps,
+                      int depth);
+BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU * r_r, prs_struct *ps,
+                      int depth);
+BOOL make_reg_q_close(REG_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL reg_io_q_close(char *desc, REG_Q_CLOSE * q_u, prs_struct *ps, int depth);
+BOOL reg_io_r_close(char *desc, REG_R_CLOSE * r_u, prs_struct *ps, int depth);
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC * q_i, POLICY_HND *pol,
+                           uint32 sec_info,
+                           uint32 buf_len, SEC_DESC * sec_desc);
+BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth);
+BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth);
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC * q_i, POLICY_HND *pol,
+                           uint32 sec_info,
+                           uint32 buf_len, SEC_DESC_BUF * sec_buf);
+BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth);
+void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC * r_i, POLICY_HND *pol,
+                           uint32 buf_len, uint8 *buf, uint32 status);
+BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth);
+BOOL make_reg_q_info(REG_Q_INFO * q_i, POLICY_HND *pol, const char *val_name,
+                    uint8 major, uint8 minor);
+BOOL reg_io_q_info(char *desc, REG_Q_INFO * r_q, prs_struct *ps, int depth);
+BOOL make_reg_r_info(REG_R_INFO * r_r,
+                    uint32 *type, BUFFER2 * buf, uint32 status);
+BOOL reg_io_r_info(char *desc, REG_R_INFO * r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE * q_i, POLICY_HND *pol,
+                        uint32 val_idx, uint32 max_val_len,
+                        uint32 max_buf_len);
+BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE * q_q, prs_struct *ps,
+                      int depth);
+BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE * r_q, prs_struct *ps,
+                      int depth);
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE * q_i, POLICY_HND *pol,
+                          char *val_name, uint32 type, BUFFER3 * val);
+BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE * q_q, prs_struct *ps,
+                        int depth);
+BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE * r_q, prs_struct *ps,
+                        int depth);
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY * q_i, POLICY_HND *pol,
+                        uint32 key_idx);
+BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY * q_q, prs_struct *ps,
+                      int depth);
+BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY * r_q, prs_struct *ps,
+                      int depth);
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY * r_q, POLICY_HND *pol,
+                          char *key_name, uint32 access_mask);
+BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY * r_q, prs_struct *ps,
+                        int depth);
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY * r_r,
+                          POLICY_HND *pol, uint32 status);
+BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY * r_r, prs_struct *ps,
+                        int depth);
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN * q_i,
+                        const char *msg, uint32 timeout, uint16 flags);
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_q, prs_struct *ps,
+                      int depth);
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_q, prs_struct *ps,
+                      int depth);
 
 /*The following definitions come from  rpc_parse/parse_rpc.c  */
 
@@ -397,46 +428,46 @@ BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER * rav,
 
 /*The following definitions come from  rpc_parse/parse_samr.c  */
 
-BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND * hnd);
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd);
 BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND * q_u,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
-                              POLICY_HND * pol, const char *dom_name);
+                              POLICY_HND *pol, const char *dom_name);
 BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
-                              DOM_SID * dom_sid, uint32 status);
+                              DOM_SID *dom_sid, uint32 status);
 BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u,
-                           const POLICY_HND * dom_pol, const DOM_SID * sid);
+                           const POLICY_HND *dom_pol, const DOM_SID *sid);
 BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D * q_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
-                            const POLICY_HND * connect_pol, uint32 flags,
-                            const DOM_SID * sid);
+                            const POLICY_HND *connect_pol, uint32 flags,
+                            const DOM_SID *sid);
 BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
-                                  POLICY_HND * user_pol);
+                                  POLICY_HND *user_pol);
 BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
-                                prs_struct * ps, int depth);
+                                prs_struct *ps, int depth);
 BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
-                                prs_struct * ps, int depth);
+                                prs_struct *ps, int depth);
 BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
-                              const POLICY_HND * user_pol, uint32 sec_info);
+                              const POLICY_HND *user_pol, uint32 sec_info);
 BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
-                               POLICY_HND * domain_pol, uint16 switch_value);
+                               POLICY_HND *domain_pol, uint16 switch_value);
 BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_unk_info3(SAM_UNK_INFO_3 * u_3);
 BOOL make_unk_info6(SAM_UNK_INFO_6 * u_6);
 BOOL make_unk_info7(SAM_UNK_INFO_7 * u_7);
@@ -447,24 +478,24 @@ BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
                                uint16 switch_value, SAM_UNK_CTR * ctr,
                                uint32 status);
 BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_sam_entry(SAM_ENTRY * sam, uint32 len_sam_name, uint32 rid);
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND * pol,
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
                                uint32 start_idx,
                                uint16 acb_mask, uint16 unk_1, uint32 size);
 BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS * r_u,
                                uint32 next_idx, uint32 num_sam_entries);
 BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
-                             prs_struct * ps, int depth);
-BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND * pol,
+                             prs_struct *ps, int depth);
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
                                uint16 switch_level, uint32 start_idx,
                                uint32 max_entries);
 BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_sam_dispinfo_1(SAM_DISPINFO_1 * sam, uint32 *num_entries,
                         uint32 *data_size, uint32 start_idx,
                         SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
@@ -485,254 +516,254 @@ BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
                                uint16 switch_level, SAM_DISPINFO_CTR * ctr,
                                uint32 status);
 BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
-                           const POLICY_HND * hnd,
+                           const POLICY_HND *hnd,
                            uint32 access_mask, uint32 rid);
 BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP * q_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP * r_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL make_samr_group_info1(GROUP_INFO1 * gr1,
                           char *acct_name, char *acct_desc,
                           uint32 num_members);
 BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL make_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc);
 BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
-                                 POLICY_HND * pol, const char *acct_desc);
+                                 POLICY_HND *pol, const char *acct_desc);
 BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
-                                 POLICY_HND * hnd);
+                                 POLICY_HND *hnd);
 BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
-                             POLICY_HND * pol, uint32 rid);
+                             POLICY_HND *pol, uint32 rid);
 BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
-                           prs_struct * ps, int depth);
-BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND * pol,
+                           prs_struct *ps, int depth);
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
                              uint32 status);
 BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
-                             POLICY_HND * pol, uint32 rid);
+                             POLICY_HND *pol, uint32 rid);
 BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
-                           prs_struct * ps, int depth);
-BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND * pol,
+                           prs_struct *ps, int depth);
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
                              uint32 status);
 BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
-                              POLICY_HND * pol, GROUP_INFO_CTR * ctr);
+                              POLICY_HND *pol, GROUP_INFO_CTR * ctr);
 BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status);
 BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
-                                POLICY_HND * pol, uint16 switch_level);
+                                POLICY_HND *pol, uint16 switch_level);
 BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
                                 GROUP_INFO_CTR * ctr, uint32 status);
 BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
-                              prs_struct * ps, int depth);
-BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND * hnd);
+                              prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd);
 BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
                                uint32 num_entries, uint32 *rid,
                                uint32 *attr, uint32 status);
 BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u);
 BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
-                                 POLICY_HND * hnd);
+                                 POLICY_HND *hnd);
 BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
                                  uint32 num_gids, DOM_GID * gid,
                                  uint32 status);
 BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
-                 prs_struct * ps, int depth);
+                 prs_struct *ps, int depth);
 BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
-                             const POLICY_HND * pol,
+                             const POLICY_HND *pol,
                              uint32 start_idx, uint32 size);
 BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
                              uint32 next_idx, uint32 num_sam_entries);
 BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
-                                const POLICY_HND * pol,
+                                const POLICY_HND *pol,
                                 uint32 start_idx, uint32 size);
 BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS * q_e,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS * r_u,
                                 uint32 next_idx, uint32 num_sam_entries);
 BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
-                                 POLICY_HND * pol, uint32 start_idx,
+                                 POLICY_HND *pol, uint32 start_idx,
                                  uint32 size);
 BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES * r_u,
                                  uint32 next_idx, uint32 num_sam_entries);
 BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc);
 BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
-                                const POLICY_HND * pol, uint16 switch_level);
+                                const POLICY_HND *pol, uint16 switch_level);
 BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
                                 ALIAS_INFO_CTR * ctr, uint32 status);
 BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
-                              const POLICY_HND * hnd, ALIAS_INFO_CTR * ctr);
+                              const POLICY_HND *hnd, ALIAS_INFO_CTR * ctr);
 BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO * q_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
-                                  const POLICY_HND * hnd,
+                                  const POLICY_HND *hnd,
                                   uint32 num_sids,
                                   uint32 *ptr_sid, DOM_SID2 * sid);
 BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
-                                prs_struct * ps, int depth);
+                                prs_struct *ps, int depth);
 void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u);
 BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
                                   uint32 num_rids, uint32 *rid,
                                   uint32 status);
 BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
-                 prs_struct * ps, int depth);
+                 prs_struct *ps, int depth);
 BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
-                                prs_struct * ps, int depth);
-BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND * pol,
+                                prs_struct *ps, int depth);
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND *pol,
                            uint32 unknown_0, uint32 rid);
 BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
-                         prs_struct * ps, int depth);
+                         prs_struct *ps, int depth);
 BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
-                            const POLICY_HND * pol, uint32 flags,
+                            const POLICY_HND *pol, uint32 flags,
                             uint32 num_rids, const uint32 *rid);
 BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u);
 BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
                             uint32 num_names, UNIHDR * hdr_name,
-                            UNISTR2 * uni_name, uint32 *type);
+                            UNISTR2 *uni_name, uint32 *type);
 BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u);
-BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND * hnd);
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd);
 BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
-                                 POLICY_HND * hnd, const char *acct_desc);
+                                 POLICY_HND *hnd, const char *acct_desc);
 BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
-                               prs_struct * ps, int depth);
-BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND * hnd,
-                             DOM_SID * sid);
+                               prs_struct *ps, int depth);
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
+                             DOM_SID *sid);
 BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
-                           prs_struct * ps, int depth);
-BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND * hnd,
-                             DOM_SID * sid);
+                           prs_struct *ps, int depth);
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
+                             DOM_SID *sid);
 BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
-                                 POLICY_HND * hnd);
+                                 POLICY_HND *hnd);
 BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
                                  uint32 status);
 BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
-                               prs_struct * ps, int depth);
+                               prs_struct *ps, int depth);
 BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
-                               const POLICY_HND * hnd);
+                               const POLICY_HND *hnd);
 BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
                                uint32 num_sids, DOM_SID2 * sid,
                                uint32 status);
 BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u,
-                             const POLICY_HND * pol, uint32 flags,
+                             const POLICY_HND *pol, uint32 flags,
                              uint32 num_names, char **name);
 BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 void samr_free_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_l);
 BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_u,
                              uint32 num_rids,
                              const uint32 *rid, const uint32 *type,
                              uint32 status);
 BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_l);
 BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
-                                POLICY_HND * hnd);
+                                POLICY_HND *hnd);
 BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
-                              prs_struct * ps, int depth);
+                              prs_struct *ps, int depth);
 BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
-                          const POLICY_HND * pol,
+                          const POLICY_HND *pol,
                           uint32 access_mask, uint32 rid);
 BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER * q_u,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
-                        prs_struct * ps, int depth);
+                        prs_struct *ps, int depth);
 BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
-                            POLICY_HND * pol,
+                            POLICY_HND *pol,
                             const char *name,
                             uint32 acb_info, uint32 access_mask);
 BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
-                          prs_struct * ps, int depth);
+                          prs_struct *ps, int depth);
 BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
-                               POLICY_HND * hnd, uint16 switch_value);
+                               POLICY_HND *hnd, uint16 switch_value);
 BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr,
                          const uint8 lm_pwd[16], const uint8 nt_pwd[16]);
 BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info);
 BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 * usr,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_sam_user_info11(SAM_USER_INFO_11 * usr,
                          NTTIME * expiry,
                          char *mach_acct,
                          uint32 rid_user, uint32 rid_group, uint16 acct_ctrl);
 BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_sam_user_info24(SAM_USER_INFO_24 * usr,
                          const char newpass[516], uint16 passlen);
 BOOL make_sam_user_info23W(SAM_USER_INFO_23 * usr, const NTTIME * logon_time,  /* all zeros */
@@ -741,16 +772,8 @@ BOOL make_sam_user_info23W(SAM_USER_INFO_23 * usr, const NTTIME * logon_time,      /*
                           const NTTIME * pass_last_set_time,   /* all zeros */
                           const NTTIME * pass_can_change_time, /* all zeros */
                           const NTTIME * pass_must_change_time,        /* all zeros */
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * desc,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str,
-                          const UNISTR2 * mung_dial, uint32 user_rid,  /* 0x0000 0000 */
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name, const UNISTR2 *home_dir, const UNISTR2 *dir_drive, const UNISTR2 *log_scr, const UNISTR2 *prof_path, const UNISTR2 *desc, const UNISTR2 *wkstas, const UNISTR2 *unk_str, const UNISTR2 *mung_dial, uint32 user_rid,        /* 0x0000 0000 */
                           uint32 group_rid,
                           uint32 acb_info,
                           uint32 unknown_3,
@@ -780,16 +803,16 @@ BOOL make_sam_user_info21W(SAM_USER_INFO_21 * usr,
                           const NTTIME * pass_last_set_time,
                           const NTTIME * pass_can_change_time,
                           const NTTIME * pass_must_change_time,
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * desc,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str,
-                          const UNISTR2 * mung_dial,
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name,
+                          const UNISTR2 *home_dir,
+                          const UNISTR2 *dir_drive,
+                          const UNISTR2 *log_scr,
+                          const UNISTR2 *prof_path,
+                          const UNISTR2 *desc,
+                          const UNISTR2 *wkstas,
+                          const UNISTR2 *unk_str,
+                          const UNISTR2 *mung_dial,
                           const uchar lm_pwd[16],
                           const uchar nt_pwd[16],
                           uint32 user_rid,
@@ -824,7 +847,7 @@ BOOL make_sam_user_info21A(SAM_USER_INFO_21 * usr,
                           LOGON_HRS * hrs,
                           uint32 unknown_5, uint32 unknown_6);
 BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR * ctr,
                                    uint16 switch_value,
                                    const SAM_USER_INFO_21 * usr);
@@ -834,48 +857,48 @@ void free_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr);
 BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
                                SAM_USERINFO_CTR * ctr, uint32 status);
 BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
-                             POLICY_HND * hnd,
+                             POLICY_HND *hnd,
                              uint16 switch_value, void *info);
 BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u);
 BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status);
 BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
-                              POLICY_HND * hnd,
+                              POLICY_HND *hnd,
                               uint16 switch_value, SAM_USERINFO_CTR * ctr);
 BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u);
 BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status);
 BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
-                            prs_struct * ps, int depth);
+                            prs_struct *ps, int depth);
 BOOL make_samr_q_connect(SAMR_Q_CONNECT * q_u,
                         const char *srv_name, uint32 access_mask);
 BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT * q_u,
-                      prs_struct * ps, int depth);
+                      prs_struct *ps, int depth);
 BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
-                      prs_struct * ps, int depth);
+                      prs_struct *ps, int depth);
 BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON * q_u);
 BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON * q_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON * r_u,
-                           prs_struct * ps, int depth);
+                           prs_struct *ps, int depth);
 BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
                                const char *srv_name);
 BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512]);
 BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD * pwd,
-                       prs_struct * ps, int depth);
+                       prs_struct *ps, int depth);
 BOOL make_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16]);
 BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH * hsh,
-                     prs_struct * ps, int depth);
+                     prs_struct *ps, int depth);
 BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
                                const char *dest_host, const char *user_name,
                                const char nt_newpass[516],
@@ -883,28 +906,30 @@ BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
                                const char lm_newpass[516],
                                const uchar lm_oldhash[16]);
 BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status);
 BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
-                             prs_struct * ps, int depth);
+                             prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_sec.c  */
 
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
-void free_sec_acl(SEC_ACL *t);
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
-                       DOM_SID *owner_sid, DOM_SID *grp_sid,
-                               SEC_ACL *sacl, SEC_ACL *dacl);
-void free_sec_desc(SEC_DESC *t);
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
-void free_sec_desc_buf(SEC_DESC_BUF *buf);
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+                 SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace);
+void free_sec_acl(SEC_ACL * t);
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+                 DOM_SID *owner_sid, DOM_SID *grp_sid,
+                 SEC_ACL * sacl, SEC_ACL * dacl);
+void free_sec_desc(SEC_DESC * t);
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data);
+void free_sec_desc_buf(SEC_DESC_BUF * buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+                    int depth);
 
 /*The following definitions come from  rpc_parse/parse_spoolss.c  */
 
@@ -1183,72 +1208,87 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD * r_n,
 
 /*The following definitions come from  rpc_parse/parse_svc.c  */
 
-BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
-                                   const char *server, const char *database,
-                                   uint32 des_access);
-BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_open_sc_man(char *desc,  SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
-                                    POLICY_HND *hnd,
-                                    const char *server,
-                                    uint32 des_access);
-BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_open_service(char *desc,  SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
-                               uint32 unk);
-BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth);
-BOOL svc_io_r_stop_service(char *desc,  SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth);
-BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
-                               uint32 argc,
-                               char **argv);
-BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth);
-BOOL svc_io_r_start_service(char *desc,  SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth);
-BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
-                               uint32 service_type, uint32 start_type,
-                               uint32 error_control,
-                               char* bin_path_name, char* load_order_grp, 
-                               uint32 tag_id,
-                               char* dependencies, char* service_start_name,
-                               char* disp_name);
-BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
-                               uint32 service_type, uint32 service_state,
-                               uint32 buf_size, uint32 resume_hnd );
-BOOL svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c, 
-                               ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
-                               uint32 num_svcs, ENUM_HND *resume_hnd,
-                               uint32 dos_status);
-BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth);
-BOOL svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth);
-BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
-                               uint32 buf_size);
-BOOL svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, 
-                               QUERY_SERVICE_CONFIG *cfg,
-                               uint32 buf_size);
-BOOL svc_io_r_query_svc_config(char *desc,  SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth);
-BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL svc_io_q_close(char *desc,  SVC_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth);
-BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
-                               uint32 service_type, uint32 start_type,
-                               uint32 unknown_0,
-                               uint32 error_control,
-                               char* bin_path_name, char* load_order_grp, 
-                               uint32 tag_id,
-                               char* dependencies, char* service_start_name,
-                               char* password,
-                               char* disp_name);
-BOOL svc_io_q_change_svc_config(char *desc,  SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth);
-BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c, 
-                               uint32 unknown_0, uint32 status);
-BOOL svc_io_r_change_svc_config(char *desc,  SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth);
-BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN * q_u,
+                           const char *server, const char *database,
+                           uint32 des_access);
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN * q_u, prs_struct *ps,
+                         int depth);
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN * r_u, prs_struct *ps,
+                         int depth);
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE * q_u,
+                            POLICY_HND *hnd,
+                            const char *server, uint32 des_access);
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE * q_u,
+                          prs_struct *ps, int depth);
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE * r_u,
+                          prs_struct *ps, int depth);
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE * q_c, POLICY_HND *hnd,
+                            uint32 unk);
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE * q_s,
+                          prs_struct *ps, int depth);
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE * r_s,
+                          prs_struct *ps, int depth);
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE * q_c, POLICY_HND *hnd,
+                             uint32 argc, char **argv);
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE * q_s,
+                           prs_struct *ps, int depth);
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE * r_s,
+                           prs_struct *ps, int depth);
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG * q_u,
+                           uint32 service_type, uint32 start_type,
+                           uint32 error_control,
+                           char *bin_path_name, char *load_order_grp,
+                           uint32 tag_id,
+                           char *dependencies, char *service_start_name,
+                           char *disp_name);
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG * q_u,
+                         prs_struct *ps, int depth);
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS * q_c,
+                                POLICY_HND *hnd, uint32 service_type,
+                                uint32 service_state, uint32 buf_size,
+                                uint32 resume_hnd);
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS * q_u,
+                              prs_struct *ps, int depth);
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS * r_c,
+                                ENUM_SRVC_STATUS * svcs,
+                                uint32 more_buf_size, uint32 num_svcs,
+                                ENUM_HND * resume_hnd, uint32 dos_status);
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS * svc,
+                              prs_struct *ps, int depth);
+BOOL svc_io_svc_status(char *desc, SVC_STATUS * svc, prs_struct *ps,
+                      int depth);
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG * q_c,
+                                POLICY_HND *hnd, uint32 buf_size);
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG * q_u,
+                              prs_struct *ps, int depth);
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG * r_c,
+                                QUERY_SERVICE_CONFIG * cfg, uint32 buf_size);
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG * r_u,
+                              prs_struct *ps, int depth);
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME * q_u,
+                             prs_struct *ps, int depth);
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME * r_u,
+                             prs_struct *ps, int depth);
+BOOL make_svc_q_close(SVC_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE * q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE * r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG * q_u,
+                                 POLICY_HND *hnd, uint32 service_type,
+                                 uint32 start_type, uint32 unknown_0,
+                                 uint32 error_control, char *bin_path_name,
+                                 char *load_order_grp, uint32 tag_id,
+                                 char *dependencies,
+                                 char *service_start_name, char *password,
+                                 char *disp_name);
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG * q_u,
+                               prs_struct *ps, int depth);
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG * r_c,
+                                 uint32 unknown_0, uint32 status);
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG * r_u,
+                               prs_struct *ps, int depth);
+BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 * q_u,
                        prs_struct *ps, int depth);
-BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 * r_u,
                        prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_wks.c  */
index 3b2f2c32d6d23779b758cd9d7359e304777c8231..2c3d2eda01fb362cd8c642c9c77e8dbc6105c23f 100644 (file)
@@ -42,4 +42,9 @@
 #define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
 #define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
 
+#define wpstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wpstring))
+#define wpstrcat(d,s) safe_strcat_w((d),(s),sizeof(wpstring))
+#define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
+#define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
+
 #endif
index 84dfb2758eea1b06dd3f8af73885af49ce214fce..412b8b97871034aaa14e9aea5068dc71c80cc398 100644 (file)
@@ -282,8 +282,7 @@ typedef struct nttime_info
        uint32 low;
        uint32 high;
 
-}
-NTTIME;
+} NTTIME;
 
 /* Allowable account control bits */
 #define ACB_DISABLED   0x0001  /* 1 = User account disabled */
@@ -378,8 +377,7 @@ typedef struct sid_info
         */
        uint32 sub_auths[MAXSUBAUTHS];  /* pointer to sub-authorities. */
 
-}
-DOM_SID;
+} DOM_SID;
 
 
 typedef struct group_name_info
@@ -392,7 +390,8 @@ typedef struct group_name_info
        uint32 type;
        uint32 unix_id;
 
-} DOM_NAME_MAP;
+}
+DOM_NAME_MAP;
 
 /* map either local aliases, domain groups or builtin aliases */
 typedef enum
@@ -413,7 +412,8 @@ typedef struct local_grp_member_info
        uint8 sid_use;          /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
        fstring name;           /* matches with sid: must be of the form "DOMAIN\account" */
 
-} LOCAL_GRP_MEMBER;
+}
+LOCAL_GRP_MEMBER;
 
 /* enumerate these to get list of local groups */
 
@@ -424,7 +424,8 @@ typedef struct local_grp_info
        fstring comment;
        uint32 rid;             /* alias rid */
 
-} LOCAL_GRP;
+}
+LOCAL_GRP;
 
 /*** query a domain group, get a list of these: shows who is in that group ***/
 
@@ -436,7 +437,8 @@ typedef struct domain_grp_member_info
        uint32 rid;             /* rid of domain group member */
        uint8 sid_use;          /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
 
-} DOMAIN_GRP_MEMBER;
+}
+DOMAIN_GRP_MEMBER;
 
 /*** enumerate these to get list of domain groups ***/
 
@@ -448,7 +450,8 @@ typedef struct domain_grp_info
        uint32 rid;             /* group rid */
        uint8 attr;             /* attributes forced to be set to 0x7: SE_GROUP_xxx */
 
-} DOMAIN_GRP;
+}
+DOMAIN_GRP;
 
 /* DOM_CHAL - challenge info */
 typedef struct chal_info
@@ -461,8 +464,7 @@ DOM_CHAL;
 typedef struct time_info
 {
        uint32 time;
-}
-UTIME;
+} UTIME;
 
 /* DOM_CREDs - timestamped client or server credentials */
 typedef struct cred_info
@@ -481,7 +483,18 @@ typedef struct
        int32 wr_error;         /* Cached errors */
        BOOL wr_mode;           /* write through mode) */
        BOOL wr_discard;        /* discard all further data */
-} write_bmpx_struct;
+}
+write_bmpx_struct;
+
+typedef struct write_cache
+{
+       SMB_OFF_T file_size;
+       SMB_OFF_T offset;
+       size_t alloc_size;
+       size_t data_size;
+       char *data;
+}
+write_cache;
 
 /*
  * Structure used to indirect fd's from the files_struct.
@@ -502,7 +515,8 @@ typedef struct file_fd_struct
        int fd_writeonly;
        int real_open_flags;
        BOOL delete_on_close;
-} file_fd_struct;
+}
+file_fd_struct;
 
 typedef struct files_struct
 {
@@ -514,23 +528,25 @@ typedef struct files_struct
        SMB_OFF_T size;
        mode_t mode;
        uint16 vuid;
-       char *mmap_ptr;
-       SMB_OFF_T mmap_size;
        write_bmpx_struct *wbmpx_ptr;
+       write_cache *wcp;
        struct timeval open_time;
        int share_mode;
        time_t pending_modtime;
+       int oplock_type;
+       int sent_oplock_break;
        BOOL open;
        BOOL can_lock;
        BOOL can_read;
        BOOL can_write;
        BOOL print_file;
        BOOL modified;
-       BOOL granted_oplock;
-       BOOL sent_oplock_break;
        BOOL is_directory;
+       BOOL directory_delete_on_close;
+       BOOL stat_open;
        char *fsp_name;
-} files_struct;
+}
+files_struct;
 
 /*
  * Structure used to keep directory state information around.
@@ -554,7 +570,8 @@ typedef struct
 {
        char *name;
        BOOL is_wild;
-} name_compare_entry;
+}
+name_compare_entry;
 
 /* Include VFS stuff */
 
@@ -576,8 +593,8 @@ typedef struct connection_struct
        BOOL read_only;
        BOOL admin_user;
 #ifdef USE_RENEWABLE_AFS_TICKET
-        pid_t afs_ticket_pid;
-#endif /* USE_RENEWABLE_AFS_TICKET */
+       pid_t afs_ticket_pid;
+#endif                         /* USE_RENEWABLE_AFS_TICKET */
 
        char *dirpath;
        char *connectpath;
@@ -608,7 +625,8 @@ typedef struct connection_struct
        name_compare_entry *veto_list;  /* Per-share list of files to veto (never show). */
        name_compare_entry *veto_oplock_list;   /* Per-share list of files to refuse oplocks on. */
 
-} connection_struct;
+}
+connection_struct;
 
 /* Domain controller authentication protocol info */
 struct dcinfo
@@ -635,7 +653,8 @@ typedef struct
        time_t time;
        char user[30];
        char file[100];
-} print_queue_struct;
+}
+print_queue_struct;
 
 enum
 { LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR };
@@ -644,7 +663,8 @@ typedef struct
 {
        fstring message;
        int status;
-} print_status_struct;
+}
+print_status_struct;
 
 /* used for server information: client, nameserv and ipc */
 struct server_info_struct
@@ -678,6 +698,12 @@ typedef struct
 share_mode_entry;
 
 
+#define SHAREMODE_FN_CAST() \
+       void (*)(share_mode_entry *, char*)
+
+#define SHAREMODE_FN(fn) \
+       void (*fn)(share_mode_entry *, char*)
+
 /* each implementation of the share mode code needs
    to support the following operations */
 struct share_ops
@@ -911,6 +937,17 @@ struct aliasdb_ops
        BOOL (*getuseraliasntnam) (const char *, LOCAL_GRP **, int *);
 };
 
+/*
+ * Flags for local user manipulation.
+ */
+
+#define LOCAL_ADD_USER 0x1
+#define LOCAL_DELETE_USER 0x2
+#define LOCAL_DISABLE_USER 0x4
+#define LOCAL_ENABLE_USER 0x8
+#define LOCAL_TRUST_ACCOUNT 0x10
+#define LOCAL_SET_NO_PASSWORD 0x20
+
 /* this is used for smbstatus */
 
 struct connect_record
@@ -998,12 +1035,25 @@ typedef enum
 }
 parm_class;
 
+/* passed to br lock code */
+enum brl_type
+{ READ_LOCK, WRITE_LOCK };
+
 struct enum_list
 {
        int value;
        char *name;
 };
 
+#define BRLOCK_FN_CAST() \
+       void (*)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+                                enum brl_type lock_type, \
+                                br_off start, br_off size)
+#define BRLOCK_FN(fn) \
+       void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+                                enum brl_type lock_type, \
+                                br_off start, br_off size)
+
 struct parm_struct
 {
        char *label;
@@ -1019,7 +1069,8 @@ struct parm_struct
                int ivalue;
                char *svalue;
                char cvalue;
-       } def;
+       }
+       def;
 };
 
 struct bitmap
@@ -1028,17 +1079,18 @@ struct bitmap
        int n;
 };
 
-#define FLAG_BASIC 1           /* fundamental options */
-#define FLAG_HIDE  2           /* options that should be hidden in SWAT */
-#define FLAG_PRINT 4           /* printing options */
-#define FLAG_GLOBAL 8          /* local options that should be globally settable in SWAT */
+#define FLAG_BASIC     0x01    /* fundamental options */
+#define FLAG_SHARE     0x02    /* file sharing options */
+#define FLAG_PRINT     0x04    /* printing options */
+#define FLAG_GLOBAL    0x08    /* local options that should be globally settable in SWAT */
 #define FLAG_DEPRECATED 0x10   /* options that should no longer be used */
+#define FLAG_HIDE      0x20    /* options that should be hidden in SWAT */
+#define FLAG_DOS_STRING 0x40   /* convert from UNIX to DOS codepage when reading this string. */
 
 #ifndef LOCKING_VERSION
 #define LOCKING_VERSION 4
 #endif /* LOCKING_VERSION */
 
-
 /* the basic packet size, assuming no words or bytes */
 #define smb_size 39
 
@@ -1200,6 +1252,9 @@ struct bitmap
 #define NT_TRANSACT_QUERY_SECURITY_DESC    6
 #define NT_TRANSACT_GET_DFS_REFERRAL    0x10
 
+/* Relevant IOCTL codes */
+#define IOCTL_QUERY_JOB_INFO      0x530060
+
 /* these are the trans2 sub fields for primary requests */
 #define smb_tpscnt smb_vwv0
 #define smb_tdscnt smb_vwv1
@@ -1287,6 +1342,11 @@ struct bitmap
 
 /* this is used on a TConX. I'm not sure the name is very helpful though */
 #define SMB_SUPPORT_SEARCH_BITS        0x0001
+#define SMB_SHARE_IN_DFS               0x0002
+
+/* Named pipe write mode flags. Used in writeX calls. */
+#define PIPE_RAW_MODE 0x4
+#define PIPE_START_MESSAGE 0x8
 
 /* these are the constants used in the above call. */
 /* DesiredAccess */
@@ -1301,6 +1361,8 @@ struct bitmap
 #define FILE_READ_ATTRIBUTES  0x080
 #define FILE_WRITE_ATTRIBUTES 0x100
 
+#define FILE_ALL_ATTRIBUTES   0x1FF
+
 /* Generic access masks & rights. */
 #define SPECIFIC_RIGHTS_MASK 0x00FFFFL
 #define STANDARD_RIGHTS_MASK 0xFF0000L
@@ -1309,7 +1371,31 @@ struct bitmap
 #define WRITE_DAC_ACCESS     (1L<<18)
 #define WRITE_OWNER_ACCESS   (1L<<19)
 #define SYNCHRONIZE_ACCESS   (1L<<20)
+
 #define SYSTEM_SECURITY_ACCESS (1L<<24)
+#define GENERIC_ALL_ACCESS   (1<<28)
+#define GENERIC_EXECUTE_ACCESS  (1<<29)
+#define GENERIC_WRITE_ACCESS   (1<<30)
+#define GENERIC_READ_ACCESS   (((unsigned)1)<<31)
+
+#define FILE_ALL_STANDARD_ACCESS 0x1F0000
+
+/* Mapping of access rights to UNIX perms. */
+#if 0                          /* Don't use all here... JRA. */
+#define UNIX_ACCESS_RWX (FILE_ALL_ATTRIBUTES|FILE_ALL_STANDARD_ACCESS)
+#else
+#define UNIX_ACCESS_RWX (UNIX_ACCESS_R|UNIX_ACCESS_W|UNIX_ACCESS_X)
+#endif
+
+#define UNIX_ACCESS_R (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+                       FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_READ_DATA)
+#define UNIX_ACCESS_W (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+                       FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|\
+                       FILE_APPEND_DATA|FILE_WRITE_DATA)
+#define UNIX_ACCESS_X (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
+                       FILE_EXECUTE|FILE_READ_ATTRIBUTES)
+
+#define UNIX_ACCESS_NONE (WRITE_OWNER_ACCESS)
 
 /* Flags field. */
 #define REQUEST_OPLOCK 2
@@ -1377,10 +1463,17 @@ struct bitmap
 #define RENAME_REPLACE_IF_EXISTS 1
 
 /* Filesystem Attributes. */
-#define FILE_CASE_SENSITIVE_SEARCH 0x1
-#define FILE_CASE_PRESERVED_NAMES 0x2
-#define FILE_UNICODE_ON_DISK 0x4
-#define FILE_PERISITANT_ACLS 0x8
+#define FILE_CASE_SENSITIVE_SEARCH 0x01
+#define FILE_CASE_PRESERVED_NAMES 0x02
+#define FILE_UNICODE_ON_DISK 0x04
+/* According to cifs9f, this is 4, not 8 */
+/* Acconding to testing, this actually sets the security attribute! */
+#define FILE_PERSISTENT_ACLS 0x08
+/* These entries added from cifs9f --tsb */
+#define FILE_FILE_COMPRESSION 0x08
+#define FILE_VOLUME_QUOTAS 0x10
+#define FILE_DEVICE_IS_MOUNTED 0x20
+#define FILE_VOLUME_IS_COMPRESSED 0x8000
 
 /* ChangeNotify flags. */
 #define FILE_NOTIFY_CHANGE_FILE_NAME   0x001
@@ -1535,6 +1628,8 @@ char *strdup(char *s);
 #define FLAGS2_32_BIT_ERROR_CODES     0x4000
 #define FLAGS2_UNICODE_STRINGS        0x8000
 
+#define FLAGS2_WIN2K_SIGNATURE        0xC852 /* Hack alert ! For now... JRA. */
+
 /* Capabilities.  see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
 
 #define CAP_RAW_MODE          0x00000001
@@ -1574,12 +1669,12 @@ enum server_types
 /* printing types */
 enum printing_types
 { PRINT_BSD, PRINT_SYSV, PRINT_AIX, PRINT_HPUX,
-       PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ
+       PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ, PRINT_CUPS
 };
 
 /* Remote architectures we know about. */
 enum remote_arch_types
-{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA };
+{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA };
 
 /* case handling */
 enum case_handling
@@ -1618,6 +1713,11 @@ enum ssl_version_enum
 #define DEFAULT_CLIENT_CODE_PAGE MSDOS_LATIN_1_CODEPAGE
 #endif /* KANJI */
 
+/* Global val set if multibyte codepage. */
+extern int global_is_multibyte_codepage;
+
+#define get_character_len(x) (global_is_multibyte_codepage ? skip_multibyte_char((x)) : 0)
+
 /* 
  * Size of buffer to use when moving files across filesystems. 
  */
@@ -1629,6 +1729,12 @@ enum ssl_version_enum
 extern int unix_ERR_class;
 extern int unix_ERR_code;
 
+/*
+ * Used in chaining code.
+ */
+
+extern int chain_size;
+
 /*
  * Map the Core and Extended Oplock requesst bits down
  * to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
@@ -1672,6 +1778,15 @@ extern int unix_ERR_code;
 #define CORE_OPLOCK_GRANTED (1<<5)
 #define EXTENDED_OPLOCK_GRANTED (1<<15)
 
+/*
+ * Return values for oplock types.
+ */
+
+#define NO_OPLOCK_RETURN 0
+#define EXCLUSIVE_OPLOCK_RETURN 1
+#define BATCH_OPLOCK_RETURN 2
+#define LEVEL_II_OPLOCK_RETURN 3
+
 /*
  * Loopback command offsets.
  */
@@ -1684,8 +1799,9 @@ extern int unix_ERR_code;
 
 /*
  * Oplock break command code to send over the udp socket.
+ * The same message is sent for both exlusive and level II breaks. 
  * 
- * Form of this is :
+ * The form of this is :
  *
  *  0     2       6        10       14    14+devsize 14+devsize+inodesize
  *  +----+--------+--------+--------+-------+--------+
@@ -1695,12 +1811,14 @@ extern int unix_ERR_code;
 
 #define OPLOCK_BREAK_CMD 0x1
 #define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_SEC_OFFSET 6
-#define OPLOCK_BREAK_USEC_OFFSET 10
-#define OPLOCK_BREAK_DEV_OFFSET 14
+#define OPLOCK_BREAK_SEC_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
+#define OPLOCK_BREAK_USEC_OFFSET (OPLOCK_BREAK_SEC_OFFSET + sizeof(time_t))
+#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_USEC_OFFSET + sizeof(long))
 #define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
 #define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
 
+#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
+
 /*
  * Capabilities abstracted for different systems.
  */
@@ -1737,8 +1855,7 @@ typedef struct
        uint32 pid;
        uint16 vuid;
 
-}
-vuser_key;
+} vuser_key;
 
 struct use_info
 {
@@ -1768,7 +1885,8 @@ typedef struct
 
        NET_USER_INFO_3 usr;
 
-} user_struct;
+}
+user_struct;
 
 struct current_user
 {
@@ -1780,6 +1898,21 @@ struct current_user
        gid_t *groups;
 };
 
+/*
+ * Reasons for cache flush.
+ */
+
+#define NUM_FLUSH_REASONS 8    /* Keep this in sync with the enum below. */
+enum flush_reason_enum
+{ SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
+       OPLOCK_RELEASE_FLUSH, CLOSE_FLUSH, SYNC_FLUSH, SIZECHANGE_FLUSH
+};
+
+/* Defines for the sent_oplock_break field above. */
+#define NO_BREAK_SENT 0
+#define EXCLUSIVE_BREAK_SENT 1
+#define LEVEL_II_BREAK_SENT 2
+
 /* A netbios name structure. */
 struct nmb_name
 {
@@ -1873,7 +2006,8 @@ typedef struct subst_creds
        fstring myhostname;
        fstring remote_machine;
 
-} CREDS_SUBST;
+}
+CREDS_SUBST;
 
 #include "rpc_creds.h"
 
@@ -1924,7 +2058,8 @@ typedef struct netsec_creds
 
        uchar sess_key[16];     /* NETLOGON session key */
 
-} netsec_creds;
+}
+netsec_creds;
 
 struct policy;
 struct bitmap;
index 10e13bb884e3d009a7a60612efee8af6f9b16de9..c65812ebdf6bd742ba43d953146a282988ce0f04 100644 (file)
 
 /* for readability... */
 #define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
-#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
-#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
-#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
-#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
+#define IS_DOS_DIR(test_mode)      (((test_mode) & aDIR) != 0)
+#define IS_DOS_ARCHIVE(test_mode)  (((test_mode) & aARCH) != 0)
+#define IS_DOS_SYSTEM(test_mode)   (((test_mode) & aSYSTEM) != 0)
+#define IS_DOS_HIDDEN(test_mode)   (((test_mode) & aHIDDEN) != 0)
 
 /* memory-allocation-helpers (idea and names from glib) */
 #define g_new(type, count) \
 
 #define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
 
+/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
+#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)
+#define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2))
+
+/* Note that chain_size must be available as an extern int to this macro. */
+#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
+
+#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|((PVAL(buf,1)&1)<<16))
+#define _smb_setlen(buf,len) buf[0] = 0; buf[1] = (len&0x10000)>>16; \
+        buf[2] = (len&0xFF00)>>8; buf[3] = len&0xFF;
+
+/*********************************************************
+* Routine to check if a given string matches exactly.
+* Case can be significant or not.
+**********************************************************/
+
+#define exact_match(str, regexp, case_sig) \
+  ((case_sig?strcmp(str,regexp):strcasecmp(str,regexp)) == 0)
+
+/*******************************************************************
+find the difference in milliseconds between two struct timeval
+values
+********************************************************************/
+
+#define TvalDiff(tvalold,tvalnew) \
+  (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 +  \
+        ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
+
+/****************************************************************************
+true if two IP addresses are equal
+****************************************************************************/
+
+#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
+
+/****************************************************************************
+ Used by dptr_zero.
+****************************************************************************/
+
+#define DPTR_MASK ((uint32)(((uint32)1)<<31))
+
+/****************************************************************************
+ Return True if the offset is at zero.
+****************************************************************************/
+
+#define dptr_zero(buf) ((IVAL(buf,1)&~DPTR_MASK) == 0)
+
+/*******************************************************************
+copy an IP address from one buffer to another
+********************************************************************/
+
+#define putip(dest,src) memcpy(dest,src,4)
+
+/****************************************************************************
+ Make a filename into unix format.
+****************************************************************************/
+
+#define unix_format(fname) string_replace(fname,'\\','/')
+
+/****************************************************************************
+ Make a file into DOS format.
+****************************************************************************/
+
+#define dos_format(fname) string_replace(fname,'/','\\')
+
+
 #endif /* _SMB_MACROS_H */
index d4ca8823ca15716c59a5641ca8bd87b3cd23320f..885e7d486b20dec4df8786861ee393011f699d55 100644 (file)
@@ -75,6 +75,10 @@ struct vfs_connection_struct {
     BOOL read_only;
     BOOL admin_user;
 
+    /* Handle on dlopen() call */
+
+    void *dl_handle;
+
     /* Paths */
 
     pstring dirpath;
@@ -106,7 +110,7 @@ struct vfs_ops {
     int (*connect)(struct vfs_connection_struct *conn, char *service, 
                   char *user);
     void (*disconnect)(void);
-    SMB_BIG_UINT (*disk_free)(char *path, SMB_BIG_UINT *bsize, 
+    SMB_BIG_UINT (*disk_free)(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                              SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
     
     /* Directory operations */
@@ -125,18 +129,15 @@ struct vfs_ops {
     ssize_t (*write)(int fd, char *data, size_t n);
     SMB_OFF_T (*lseek)(int filedes, SMB_OFF_T offset, int whence);
     int (*rename)(char *old, char *new);
-    void (*sync)(int fd);
+    void (*fsync)(int fd);
     int (*stat)(char *fname, SMB_STRUCT_STAT *sbuf);
     int (*fstat)(int fd, SMB_STRUCT_STAT *sbuf);
     int (*lstat)(char *path, SMB_STRUCT_STAT *sbuf);
-    BOOL (*lock)(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
     int (*unlink)(char *path);
     int (*chmod)(char *path, mode_t mode);
     int (*utime)(char *path, struct utimbuf *times);
 };
 
-/* VFS options for configuration file */
-
 struct vfs_options {
     struct vfs_options *prev, *next;
     char *name;
index 1ab6832045ee4fecf9360d1cefa82097687a373f..a8165824f832efe1bff6822e15559a726c37489c 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.[pl]o
 *.po32
 
index 0fa383d84a534b338702cc4d6e760a05b65214b1..01f559750fa92b9e6eed1769c354ab8e8b1234c9 100644 (file)
@@ -38,12 +38,14 @@ static int masked_match(char *tok, char *slash, char *s)
 }
 
 /* string_match - match string against token */
-static int string_match(char *tok,char *s)
+static int string_match(char *tok,char *s, char *invalid_char)
 {
-       int     tok_len;
-       int     str_len;
+       size_t     tok_len;
+       size_t     str_len;
        char   *cut;
 
+       *invalid_char = '\0';
+
        /* Return True if a token has the magic value "ALL". Return
         * FAIL if the token is "FAIL". If the token starts with a "."
         * (domain name), return True if it matches the last fields of
@@ -108,6 +110,10 @@ static int string_match(char *tok,char *s)
        } else if ((cut = strchr(tok, '/')) != 0) {     /* netnumber/netmask */
                if (isdigit((int)s[0]) && masked_match(tok, cut, s))
                        return (True);
+       } else if (strchr(tok, '*') != 0) {
+               *invalid_char = '*';
+       } else if (strchr(tok, '?') != 0) {
+               *invalid_char = '?';
        }
        return (False);
 }
@@ -118,15 +124,26 @@ static int client_match(char *tok,char *item)
 {
     char **client = (char **)item;
     int     match;
+       char invalid_char = '\0';
 
     /*
      * Try to match the address first. If that fails, try to match the host
      * name if available.
      */
 
-    if ((match = string_match(tok, client[1])) == 0)
-       if (client[0][0] != 0)
-           match = string_match(tok, client[0]);
+    if ((match = string_match(tok, client[1], &invalid_char)) == 0) {
+               if(invalid_char)
+                       DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
+token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
+
+               if (client[0][0] != 0)
+                       match = string_match(tok, client[0], &invalid_char);
+
+               if(invalid_char)
+                       DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
+token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
+       }
+
     return (match);
 }
 
@@ -184,6 +201,15 @@ BOOL allow_access(char *deny_list,char *allow_list,
        client[0] = cname;
        client[1] = caddr;  
 
+       /* if it is loopback then always allow unless specifically denied */
+       if (strcmp(caddr, "127.0.0.1") == 0) {
+               if (deny_list && 
+                   list_match(deny_list,(char *)client,client_match)) {
+                       return False;
+               }
+               return True;
+       }
+
        /* if theres no deny list and no allow list then allow access */
        if ((!deny_list || *deny_list == 0) && 
            (!allow_list || *allow_list == 0)) {
index 93c821c52853d9af7dd092a69aecb4b412ab99a6..1813d63ff77892ae6d2f87b570605177a6c1c35f 100644 (file)
@@ -35,10 +35,10 @@ struct bitmap *bitmap_allocate(int n)
        struct bitmap *bm;
 
        bm = (struct bitmap *)malloc(sizeof(*bm));
-       bm->n = n;
 
        if (!bm) return NULL;
        
+       bm->n = n;
        bm->b = (uint32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
        if (!bm->b) {
                free(bm);
index 29ef72d7ac3e8627de0872563162639bae59ceda..2916f0cedab9e4979ca128e86a41b78e4d184a68 100644 (file)
@@ -23,7 +23,7 @@
 #define CTRLZ 26
 extern int DEBUGLEVEL;
 
-static char cvtbuf[1024];
+static char cvtbuf[sizeof(pstring)];
 
 static BOOL mapsinited = 0;
 
@@ -39,7 +39,7 @@ static void initmaps(void) {
     mapsinited = True;
 }
 
-static void update_map(char * str) {
+static void update_map(char *str) {
     char *p;
 
     for (p = str; *p; p++) {
@@ -51,47 +51,55 @@ static void update_map(char * str) {
     }
 }
 
-static void init_iso8859_1(void) {
-
+static void setupmaps(void)
+{
     int i;
     if (!mapsinited) initmaps();
 
     /* Do not map undefined characters to some accidental code */
-    for (i = 128; i < 256; i++) 
+    for (i = 128; i < 256; i++)
     {
        unix2dos[i] = CTRLZ;
        dos2unix[i] = CTRLZ;
     }
+}
 
-/* MSDOS Code Page 850 -> ISO-8859 */
-update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
-update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
-update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
-update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
-update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
-update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
-update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
-update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
-update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
-update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
-update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
-update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+static void init_iso8859_1(int codepage) {
 
+       setupmaps();
+
+    if (codepage == 437) {
+        /* MSDOS Code Page 437 -> ISO-8859-1 */
+        update_map("\xA1\xAD\xA2\x98\xA3\x9C\xA4\xED\xA5\x9D\xA6\xB3\xA7\xEE");
+        update_map("\xAA\xA6\xAB\xAE\xAC\xAA\xAE\xE9\xAF\xC4");
+        update_map("\xB0\xF8\xB1\xF1\xB2\xFD\xB5\xE6\xB7\xFA\xBA\xA7\xBC\xAC\xBD\xAB\xBF\xA8");
+        update_map("\xC0\x85\xC1\xA0\xC2\x83\xC4\x8E\xC5\x8F\xC6\x92\xC7\x80\xC8\x8A");
+        update_map("\xC9\x90\xCA\x88\xCB\x89\xCC\x8D\xCD\xA1\xCE\x8C\xCF\x8B");
+        update_map("\xD1\xA5\xD2\x96\xD3\xA2\xD4\x93\xD6\x99\xD9\x97\xDA\xA3\xDB\x96\xDC\x9A\xDF\xE1");
+        update_map("\xE0\x85\xE1\xA0\xE2\x83\xE4\x84\xE5\x86\xE6\x91\xE7\x87\xE8\x8A\xE9\x82\xEA\x88\xEB\x89\xEC\x8D\xED\xA1\xEE\x8C\xEF\x8B");
+        update_map("\xF0\xEB\xF1\xA4\xF2\x95\xF3\xA2\xF4\x93\xF6\x94\xF7\xF6\xF8\xED\xF9\x97\xFA\xA3\xFB\x96\xFC\x81\xFF\x98");
+    } else {
+        /* MSDOS Code Page 850 -> ISO-8859-1 */
+        update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
+        update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
+        update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
+        update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
+        update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
+        update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
+        update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
+        update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
+        update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
+        update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
+        update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
+        update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
+    }
 }
 
 /* Init for eastern european languages. */
 
 static void init_iso8859_2(void) {
 
-    int i;
-    if (!mapsinited) initmaps();
-
-    /* Do not map undefined characters to some accidental code */
-    for (i = 128; i < 256; i++) 
-    {
-       unix2dos[i] = CTRLZ;
-       dos2unix[i] = CTRLZ;
-    }
+       setupmaps();
 
 /*
  * Tranlation table created by Petr Hubeny <psh@capitol.cz>
@@ -100,6 +108,7 @@ static void init_iso8859_2(void) {
  */
 
 /* MSDOS Code Page 852 -> ISO-8859-2 */
+update_map("\240\377"); /* Fix for non-breaking space */
 update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365");
 update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275");
 update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363");
@@ -120,36 +129,48 @@ update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372");
 
 static void init_iso8859_5(void)
 {
-  int i;
-  if (!mapsinited) initmaps();
-
-  /* Do not map undefined characters to some accidental code */
-  for (i = 128; i < 256; i++) 
-  {
-     unix2dos[i] = CTRLZ;
-     dos2unix[i] = CTRLZ;
-  }
+       setupmaps();
 
 /* MSDOS Code Page 866 -> ISO8859-5 */
-update_map("\200\260\201\261\202\262\203\263\204\264\205\265\206\266\207\267");
-update_map("\210\270\211\271\212\272\213\273\214\274\215\275\216\276\217\277");
-update_map("\220\300\221\301\222\302\223\303\224\304\225\305\226\306\227\307");
-update_map("\230\310\231\311\232\312\233\313\234\314\235\315\236\316\237\317");
-update_map("\240\320\241\321\242\322\243\323\244\324\245\325\246\326\247\327");
-update_map("\250\330\251\331\252\332\253\333\254\334\255\335\256\336\257\337");
+update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
+update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
+update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227");
+update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237");
+update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247");
+update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257");
 update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
 update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
-update_map("\360\241\361\361\362\244\363\364\364\247\365\367\366\256\367\376");
-update_map("\374\360\377\240");
+update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
+update_map("\360\374\240\377");
+}
+
+/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
+
+static void init_iso8859_7(void)
+{
+       setupmaps();
+
+/* MSDOS Code Page 737 -> ISO-8859-7 (Greek-Hellenic) */
+
+update_map("\301\200\302\201\303\202\304\203\305\204\306\205\307\206");
+update_map("\310\207\311\210\312\211\313\212\314\213\315\214\316\215\317\216");
+update_map("\320\217\321\220\323\221\324\222\325\223\326\224\327\225");
+update_map("\330\226\331\227");
+update_map("\341\230\342\231\343\232\344\233\345\234\346\235\347\236");
+update_map("\350\237\351\240\352\241\353\242\354\243\355\244\356\245\357\246");
+update_map("\360\247\361\250\362\252\363\251\364\253\365\254\366\255\367\256");
+update_map("\370\257\371\340");
+update_map("\332\364\333\365\334\341\335\342\336\343\337\345");
+update_map("\372\344\373\350\374\346\375\347\376\351");
+update_map("\266\352");
+update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
 }
 
 /* Init for russian language (koi8) */
 
 static void init_koi8_r(void)
 {
-  if (!mapsinited) initmaps();
-
-  /* There aren't undefined characters between 128 and 255 */
+       setupmaps();
 
 /* MSDOS Code Page 866 -> KOI8-R */
 update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
@@ -170,24 +191,49 @@ update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
 update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
 }
 
+
+/* Init for ROMAN-8 (HP-UX) */
+
+static void init_roman8(void) {
+
+       setupmaps();
+
+/* MSDOS Code Page 850 -> ROMAN8 */
+update_map("\240\377\241\267\242\266\243\324\244\322\245\323\246\327\247\330");
+update_map("\250\357\253\371\255\353\256\352\257\234");
+update_map("\260\356\261\355\262\354\263\370\264\200\265\207\266\245\267\244");
+update_map("\270\255\271\250\272\317\273\234\274\276\275\365\276\237\277\275");
+update_map("\300\203\301\210\302\223\303\226\304\240\305\202\306\242\307\243");
+update_map("\310\205\311\212\312\225\313\227\314\204\315\211\316\224\317\201");
+update_map("\320\217\321\214\322\235\323\222\324\206\325\241\326\233\327\221");
+update_map("\330\216\331\215\332\231\333\232\334\220\335\213\336\341\337\342");
+update_map("\340\265\341\307\342\306\343\321\344\320\345\326\346\336\347\340");
+update_map("\350\343\351\345\352\344\355\351\357\230");
+update_map("\360\350\361\347\362\372\363\346\364\364\365\363\366\360\367\254");
+update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
+}
+
 /*
  * Convert unix to dos
  */
 char *unix2dos_format(char *str,BOOL overwrite)
 {
-    char *p;
-    char *dp;
-
-    if (!mapsinited) initmaps();
-
-      if (overwrite) {
-          for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
-          return str;
-      } else {
-          for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p];
-          *dp = 0;
-          return cvtbuf;
-      }
+  char *p;
+  char *dp;
+
+  if (!mapsinited)
+    initmaps();
+
+  if (overwrite) {
+    for (p = str; *p; p++)
+      *p = unix2dos[(unsigned char)*p];
+    return str;
+  } else {
+    for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+      *dp = unix2dos[(unsigned char)*p];
+    *dp = 0;
+    return cvtbuf;
+  }
 }
 
 /*
@@ -195,36 +241,45 @@ char *unix2dos_format(char *str,BOOL overwrite)
  */
 char *dos2unix_format(char *str, BOOL overwrite)
 {
-    char *p;
-    char *dp;
-
-    if (!mapsinited) initmaps();
-
-      if (overwrite) {
-          for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
-          return str;
-      } else {
-          for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p];
-          *dp = 0;
-          return cvtbuf;
-      }
+  char *p;
+  char *dp;
+
+  if (!mapsinited)
+    initmaps();
+
+  if (overwrite) {
+    for (p = str; *p; p++)
+      *p = dos2unix[(unsigned char)*p];
+    return str;
+  } else {
+    for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+      *dp = dos2unix[(unsigned char)*p];
+    *dp = 0;
+    return cvtbuf;
+  }
 }
 
 
 /*
  * Interpret character set.
  */
-void interpret_character_set(char *str)
+void interpret_character_set(char *str, int codepage)
 {
     if (strequal (str, "iso8859-1")) {
-        init_iso8859_1();
+        init_iso8859_1(codepage);
     } else if (strequal (str, "iso8859-2")) {
         init_iso8859_2();
     } else if (strequal (str, "iso8859-5")) {
         init_iso8859_5();
+    } else if (strequal (str, "iso8859-7")) {
+        init_iso8859_7();
     } else if (strequal (str, "koi8-r")) {
         init_koi8_r();
+    } else if (strequal (str, "roman8")) {
+        init_roman8();
     } else {
         DEBUG(0,("unrecognized character set %s\n", str));
     }
+
+    load_unix_unicode_map(str);
 }
index 8a245713584f0a36e27b8ede119c133f104b795a..6e5a4b48cbab3a28baeab82d11de096b8cd98f8f 100644 (file)
@@ -371,6 +371,8 @@ for code page %d failed. Using default client codepage 850\n",
       add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
   }
 
+  /* Try and load the unicode map. */
+  load_dos_unicode_map(client_codepage);
 }
 
 /*******************************************************************
index 8c4e025c2c7dce46706925bf540bdee31f74412a..699fb8a79d3d498094e5727fb38b51a958643d48 100644 (file)
@@ -157,26 +157,32 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
        }
        else
        {
+               POSIX_ID id;
+
                switch (type)
                {
                        case DOM_MAP_USER:
                        {
                                grp->type = SID_NAME_USER;
+                               id.type = SURS_POSIX_UID_AS_USR;
                                break;
                        }
                        case DOM_MAP_DOMAIN:
                        {
                                grp->type = SID_NAME_DOM_GRP;
+                               id.type = SURS_POSIX_GID_AS_GRP;
                                break;
                        }
                        case DOM_MAP_LOCAL:
                        {
                                grp->type = SID_NAME_ALIAS;
+                               id.type = SURS_POSIX_GID_AS_ALS;
                                break;
                        }
                }
 
-               ret = surs_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid, False);
+               id.id = grp->unix_id;
+               ret = surs_unixid_to_sam_sid(&id, &grp->sid, False);
        }
 
        sid_to_string(sid_str, &grp->sid);
@@ -776,6 +782,8 @@ static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint32 *type)
 static BOOL get_sid_and_type(const char *fullntname, uint32 expected_type,
                                DOM_NAME_MAP *gmep)
 {
+       POSIX_ID id;
+
        /*
         * check with the PDC to see if it owns the name.  if so,
         * the SID is resolved with the PDC database.
@@ -804,7 +812,29 @@ static BOOL get_sid_and_type(const char *fullntname, uint32 expected_type,
        {
                return False;
        }
-       if (!surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False))
+
+       switch (gmep->type)
+       {
+               case SID_NAME_USER:
+               {
+                       id.type = SURS_POSIX_UID_AS_USR;
+                       break;
+               }
+               case SID_NAME_DOM_GRP:
+               {
+                       id.type = SURS_POSIX_GID_AS_GRP;
+                       break;
+               }
+               case SID_NAME_ALIAS:
+               {
+                       id.type = SURS_POSIX_GID_AS_ALS;
+                       break;
+               }
+       }
+
+       id.id = gmep->unix_id;
+
+       if (!surs_unixid_to_sam_sid(&id, &gmep->sid, False))
        {
                return False;
        }
@@ -824,6 +854,7 @@ BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
        }
        if (lp_server_role() != ROLE_DOMAIN_NONE)
        {
+               POSIX_ID id;
                static fstring nt_name;
                static fstring unix_name;
                static fstring nt_domain;
@@ -861,7 +892,29 @@ BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
                 */
 
                gmep->nt_domain = global_sam_name;
-               surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False);
+
+               switch (gmep->type)
+               {
+                       case SID_NAME_USER:
+                       {
+                               id.type = SURS_POSIX_UID_AS_USR;
+                               break;
+                       }
+                       case SID_NAME_DOM_GRP:
+                       {
+                               id.type = SURS_POSIX_GID_AS_GRP;
+                               break;
+                       }
+                       case SID_NAME_ALIAS:
+                       {
+                               id.type = SURS_POSIX_GID_AS_ALS;
+                               break;
+                       }
+               }
+
+               id.id = gmep->unix_id;
+
+               surs_unixid_to_sam_sid(&id, &gmep->sid, False);
 
                return True;
        }
@@ -936,6 +989,7 @@ BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
        }
        if (lp_server_role() != ROLE_DOMAIN_NONE)
        {
+               POSIX_ID id;
                static fstring nt_name;
                static fstring unix_name;
                static fstring nt_domain;
@@ -966,10 +1020,33 @@ BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
 
                gmep->type = SID_NAME_USER;
                sid_copy(&gmep->sid, sid);
-               if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
+
+               if (!surs_sam_sid_to_unixid(&gmep->sid, &id, False))
                {
                        return False;
                }
+
+               gmep->unix_id = id.id;
+
+               switch (id.type)
+               {
+                       case SURS_POSIX_UID_AS_USR:
+                       {
+                               gmep->type= SID_NAME_USER;
+                               break;
+                       }
+                       case SURS_POSIX_GID_AS_GRP:
+                       {
+                               gmep->type= SID_NAME_DOM_GRP;
+                               break;
+                       }
+                       case SURS_POSIX_GID_AS_ALS:
+                       {
+                               gmep->type= SID_NAME_ALIAS;
+                               break;
+                       }
+               }
+
                fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
                fstrcpy(gmep->unix_name, gmep->nt_name);
                gmep->nt_domain = global_sam_name;
@@ -1018,6 +1095,7 @@ BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
        }
        if (lp_server_role() != ROLE_DOMAIN_NONE)
        {
+               POSIX_ID id;
                static fstring nt_name;
                static fstring unix_name;
                static fstring nt_domain;
@@ -1063,10 +1141,32 @@ BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
                }
 
                sid_copy(&gmep->sid, sid);
-               if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
+               if (!surs_sam_sid_to_unixid(&gmep->sid, &id, False))
                {
                        return False;
                }
+
+               gmep->unix_id = id.id;
+
+               switch (id.type)
+               {
+                       case SURS_POSIX_UID_AS_USR:
+                       {
+                               gmep->type= SID_NAME_USER;
+                               break;
+                       }
+                       case SURS_POSIX_GID_AS_GRP:
+                       {
+                               gmep->type= SID_NAME_DOM_GRP;
+                               break;
+                       }
+                       case SURS_POSIX_GID_AS_ALS:
+                       {
+                               gmep->type= SID_NAME_ALIAS;
+                               break;
+                       }
+               }
+
                fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
                fstrcpy(gmep->unix_name, gmep->nt_name);
                gmep->nt_domain = global_sam_name;
index 2098b5e3508cc40cd7818d1be033c3ace5e8d159..2bd68d309747739729d786705f14f9c41778d6ee 100644 (file)
@@ -81,6 +81,15 @@ char *dos_readdirname(DIR *p)
 }
 #endif
 
+/*******************************************************************
+ A chown() wrapper that calls dos_to_unix.
+********************************************************************/
+
+int dos_chown(char *fname, uid_t uid, gid_t gid)
+{
+  return(sys_chown(dos_to_unix(fname,False),uid,gid));
+}
+
 /*******************************************************************
  A stat() wrapper that calls dos_to_unix.
 ********************************************************************/
@@ -100,14 +109,20 @@ int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf)
 }
 
 /*******************************************************************
- Mkdir() that calls dos_to_unix.  Don't use this call unless you
- really want to access a file on disk.  Use the vfs_ops.mkdir() 
- function instead.
+ Mkdir() that calls dos_to_unix.
+ Cope with UNIXes that don't allow high order mode bits on mkdir.
+ Patch from gcarter@lanier.com.
+ Don't use this call unless you really want to access a file on 
+ disk.  Use the vfs_ops.mkdir() function instead.
 ********************************************************************/
 
 int dos_mkdir(char *dname,mode_t mode)
 {
-  return(mkdir(dos_to_unix(dname,False),mode));
+  int ret = mkdir(dos_to_unix(dname,False),mode);
+  if(!ret)
+    return(dos_chmod(dname,mode));
+  else
+    return ret;
 }
 
 /*******************************************************************
@@ -243,11 +258,19 @@ int copy_reg(char *source, const char *dest)
 
 int dos_rename(char *from, char *to)
 {
+    int rcode;  
     pstring zfrom, zto;
 
     pstrcpy (zfrom, dos_to_unix (from, False));
     pstrcpy (zto, dos_to_unix (to, False));
-    return file_rename(zfrom, zto);
+    rcode = rename (zfrom, zto);
+
+    if (errno == EXDEV) 
+    {
+      /* Rename across filesystems needed. */
+      rcode = copy_reg (zfrom, zto);        
+    }
+    return rcode;
 }
 
 /*******************************************************************
@@ -308,7 +331,7 @@ time_t dos_file_modtime(char *fname)
 
 SMB_OFF_T dos_file_size(char *file_name)
 {
-  return file_size(dos_to_unix(file_name, False));
+  return get_file_size(dos_to_unix(file_name, False));
 }
 
 /*******************************************************************
@@ -394,7 +417,7 @@ char *dos_GetWd(char *path)
     getwd_cache_init = True;
     for (i=0;i<MAX_GETWDCACHE;i++)
     {
-      string_init(&ino_list[i].dos_path,"");
+      string_set(&ino_list[i].dos_path,"");
       ino_list[i].valid = False;
     }
   }
@@ -404,7 +427,7 @@ char *dos_GetWd(char *path)
 
   if (sys_stat(".",&st) == -1)
   {
-    DEBUG(0,("Very strange, couldn't stat \".\"\n"));
+    DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
     return(dos_getwd(path));
   }
 
index fecd152f351953fbe43f53c35b6b56473c8ec037..6effaf7d7c6811854a17710f56629c3ff7a24567 100644 (file)
@@ -41,8 +41,7 @@ static void fault_report(int sig)
        DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION));
        DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
        DEBUG(0,("===============================================================\n"));
-
-       sleep(10);
+  
        smb_panic("internal error");
 
        if (cont_fn) {
@@ -52,9 +51,6 @@ static void fault_report(int sig)
 #endif
 #ifdef SIGBUS
                CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL);
-#endif
-#ifdef SIGILL
-               CatchSignal(SIGILL, SIGNAL_CAST SIG_DFL);
 #endif
                return; /* this should cause a core dump */
        }
@@ -82,9 +78,6 @@ void fault_setup(void (*fn)(void *))
 #ifdef SIGBUS
        CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
 #endif
-#ifdef SIGILL
-       CatchSignal(SIGILL,SIGNAL_CAST sig_fault);
-#endif
 }
 
 
index ab0dadebcf24d81100a4f5cf13c604387a79ea6a..a9698d4cd1b1df6f802f5feb9c8d0a92b666b31c 100644 (file)
@@ -58,8 +58,8 @@ static void do_dirrand(char *name, unsigned char *buf, int buf_len)
 {
   DIR *dp = opendir(name);
   pstring fullname;
-  size_t len_left;
-  size_t fullname_len;
+  int len_left;
+  int fullname_len;
   char *pos;
 
   pstrcpy(fullname, name);
@@ -150,7 +150,7 @@ static uint32 do_reseed(unsigned char *md4_outbuf)
 
   /* add in the root encrypted password. On any system where security is taken
      seriously this will be secret */
-  pw = getpwnam("root");
+  pw = sys_getpwnam("root");
   if (pw && pw->pw_passwd) {
          int i;
          unsigned char md4_tmp[16];
index 871a4a059c897a707ce13495c5e98b843b16ae1d..43b22c19cce37c2839b74d36c496e9d3fca07859 100644 (file)
@@ -80,6 +80,8 @@ int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
 
 #endif /* KANJI */
 
+BOOL global_is_multibyte_codepage = False;
+
 /* jis si/so sequence */
 static char jis_kso = JIS_KSO;
 static char jis_ksi = JIS_KSI;
@@ -377,7 +379,7 @@ static size_t skip_generic_multibyte_char(char c)
 ********************************************************************/
 
 /* convesion buffer */
-static char cvtbuf[1024];
+static char cvtbuf[2*sizeof(pstring)];
 
 /*******************************************************************
   EUC <-> SJIS
@@ -412,7 +414,7 @@ static char *sj_to_euc(char *from, BOOL overwrite)
   char *save;
 
   save = (char *) from;
-  for (out = cvtbuf; *from;) {
+  for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
     if (is_shift_jis (*from)) {
       int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
       *out++ = (code >> 8) & 0xff;
@@ -445,7 +447,7 @@ static char *euc_to_sj(char *from, BOOL overwrite)
   char *save;
 
   save = (char *) from;
-  for (out = cvtbuf; *from; ) {
+  for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
     if (is_euc (*from)) {
       int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
       *out++ = (code >> 8) & 0xff;
@@ -496,48 +498,51 @@ static int jis2sjis(int hi, int lo)
 
 static char *jis8_to_sj(char *from, BOOL overwrite)
 {
-    char *out;
-    int shifted;
-    char *save;
+  char *out;
+  int shifted;
+  char *save;
 
-    shifted = _KJ_ROMAN;
-    save = (char *) from;
-    for (out = cvtbuf; *from;) {
-       if (is_esc (*from)) {
-           if (is_so1 (from[1]) && is_so2 (from[2])) {
-               shifted = _KJ_KANJI;
-               from += 3;
-           } else if (is_si1 (from[1]) && is_si2 (from[2])) {
-               shifted = _KJ_ROMAN;
-               from += 3;
-           } else {                    /* sequence error */
-               goto normal;
-           }
-       } else {
-       normal:
-           switch (shifted) {
-           default:
-           case _KJ_ROMAN:
-               *out++ = *from++;
-               break;
-           case _KJ_KANJI:
-               {
-                   int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
-                   *out++ = (code >> 8) & 0xff;
-                   *out++ = code;
-                   from += 2;
-               }
-               break;
-           }
-       }
-    }
-    *out = 0;
-    if (overwrite) {
-       pstrcpy (save, (char *) cvtbuf);
-       return save;
+  shifted = _KJ_ROMAN;
+  save = (char *) from;
+  for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+    if (is_esc (*from)) {
+      if (is_so1 (from[1]) && is_so2 (from[2])) {
+        shifted = _KJ_KANJI;
+        from += 3;
+      } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+        shifted = _KJ_ROMAN;
+        from += 3;
+      } else { /* sequence error */
+        goto normal;
+      }
     } else {
-       return cvtbuf;
+
+normal:
+
+      switch (shifted) {
+      default:
+      case _KJ_ROMAN:
+        *out++ = *from++;
+        break;
+      case _KJ_KANJI:
+        {
+          int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+          *out++ = (code >> 8) & 0xff;
+          *out++ = code;
+          from += 2;
+          break;
+        }
+      }
     }
+  }
+
+  *out = 0;
+  if (overwrite) {
+    pstrcpy (save, (char *) cvtbuf);
+    return save;
+  } else {
+    return cvtbuf;
+  }
 }
 
 /*******************************************************************
@@ -547,54 +552,55 @@ static char *jis8_to_sj(char *from, BOOL overwrite)
 
 static char *sj_to_jis8(char *from, BOOL overwrite)
 {
-    char *out;
-    int shifted;
-    char *save;
+  char *out;
+  int shifted;
+  char *save;
 
-    shifted = _KJ_ROMAN;
-    save = (char *) from;
-    for (out = cvtbuf; *from; ) {
-       if (is_shift_jis (*from)) {
-           int code;
-           switch (shifted) {
-           case _KJ_ROMAN:             /* to KANJI */
-               *out++ = jis_esc;
-               *out++ = jis_so1;
-               *out++ = jis_kso;
-               shifted = _KJ_KANJI;
-               break;
-           }
-           code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
-           *out++ = (code >> 8) & 0xff;
-           *out++ = code;
-           from += 2;
-       } else {
-           switch (shifted) {
-           case _KJ_KANJI:             /* to ROMAN/KANA */
-               *out++ = jis_esc;
-               *out++ = jis_si1;
-               *out++ = jis_ksi;
-               shifted = _KJ_ROMAN;
-               break;
-           }
-           *out++ = *from++;
-       }
-    }
-    switch (shifted) {
-    case _KJ_KANJI:                    /* to ROMAN/KANA */
-       *out++ = jis_esc;
-       *out++ = jis_si1;
-       *out++ = jis_ksi;
-       shifted = _KJ_ROMAN;
-       break;
-    }
-    *out = 0;
-    if (overwrite) {
-       pstrcpy (save, (char *) cvtbuf);
-       return save;
+  shifted = _KJ_ROMAN;
+  save = (char *) from;
+  for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+    if (is_shift_jis (*from)) {
+      int code;
+      switch (shifted) {
+      case _KJ_ROMAN: /* to KANJI */
+        *out++ = jis_esc;
+        *out++ = jis_so1;
+        *out++ = jis_kso;
+        shifted = _KJ_KANJI;
+        break;
+      }
+      code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+      *out++ = (code >> 8) & 0xff;
+      *out++ = code;
+      from += 2;
     } else {
-       return cvtbuf;
+      switch (shifted) {
+      case _KJ_KANJI: /* to ROMAN/KANA */
+        *out++ = jis_esc;
+        *out++ = jis_si1;
+        *out++ = jis_ksi;
+        shifted = _KJ_ROMAN;
+        break;
+      }
+      *out++ = *from++;
     }
+  }
+
+  switch (shifted) {
+  case _KJ_KANJI: /* to ROMAN/KANA */
+    *out++ = jis_esc;
+    *out++ = jis_si1;
+    *out++ = jis_ksi;
+    shifted = _KJ_ROMAN;
+    break;
+  }
+  *out = 0;
+  if (overwrite) {
+    pstrcpy (save, (char *) cvtbuf);
+    return save;
+  } else {
+    return cvtbuf;
+  }
 }
 
 /*******************************************************************
@@ -609,7 +615,7 @@ static char *jis7_to_sj(char *from, BOOL overwrite)
 
     shifted = _KJ_ROMAN;
     save = (char *) from;
-    for (out = cvtbuf; *from;) {
+    for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
        if (is_esc (*from)) {
            if (is_so1 (from[1]) && is_so2 (from[2])) {
                shifted = _KJ_KANJI;
@@ -668,7 +674,7 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
 
     shifted = _KJ_ROMAN;
     save = (char *) from;
-    for (out = cvtbuf; *from; ) {
+    for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
        if (is_shift_jis (*from)) {
            int code;
            switch (shifted) {
@@ -736,6 +742,7 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
  Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
  return converted buffer
 ********************************************************************/
+
 static char *junet_to_sj(char *from, BOOL overwrite)
 {
     char *out;
@@ -744,7 +751,7 @@ static char *junet_to_sj(char *from, BOOL overwrite)
 
     shifted = _KJ_ROMAN;
     save = (char *) from;
-    for (out = cvtbuf; *from;) {
+    for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
        if (is_esc (*from)) {
            if (is_so1 (from[1]) && is_so2 (from[2])) {
                shifted = _KJ_KANJI;
@@ -800,7 +807,7 @@ static char *sj_to_junet(char *from, BOOL overwrite)
 
     shifted = _KJ_ROMAN;
     save = (char *) from;
-    for (out = cvtbuf; *from; ) {
+    for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
        if (is_shift_jis (*from)) {
            int code;
            switch (shifted) {
@@ -867,7 +874,7 @@ static char *hex_to_sj(char *from, BOOL overwrite)
     
     sp = (char *) from;
     dp = cvtbuf;
-    while (*sp) {
+    while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
        if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
            *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
            sp += 3;
@@ -892,7 +899,7 @@ static char *sj_to_hex(char *from, BOOL overwrite)
     
     sp = (unsigned char*) from;
     dp = (unsigned char*) cvtbuf;
-    while (*sp) {
+    while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
        if (is_kana(*sp)) {
            *dp++ = hex_tag;
            *dp++ = bin2hex (((*sp)>>4)&0x0f);
@@ -929,7 +936,7 @@ static char *cap_to_sj(char *from, BOOL overwrite)
 
     sp = (char *) from;
     dp = cvtbuf;
-    while (*sp) {
+    while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
         /*
          * The only change between this and hex_to_sj is here. sj_to_cap only
          * translates characters greater or equal to 0x80 - make sure that here
@@ -960,7 +967,7 @@ static char *sj_to_cap(char *from, BOOL overwrite)
 
     sp = (unsigned char*) from;
     dp = (unsigned char*) cvtbuf;
-    while (*sp) {
+    while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
        if (*sp >= 0x80) {
            *dp++ = hex_tag;
            *dp++ = bin2hex (((*sp)>>4)&0x0f);
@@ -1157,17 +1164,6 @@ static BOOL not_multibyte_char_1(char c)
   return False;
 }
 
-/*******************************************************************
- Function to determine if we are in a multibyte code page.
-*******************************************************************/
-
-static BOOL is_multibyte_codepage_val = False;
-
-BOOL is_multibyte_codepage(void)
-{
-  return is_multibyte_codepage_val;
-}
-
 /*******************************************************************
  Setup the function pointers for the functions that are replaced
  when multi-byte codepages are used.
@@ -1188,7 +1184,7 @@ void initialize_multibyte_vectors( int client_codepage)
     multibyte_strtok = sj_strtok;
     _skip_multibyte_char = skip_kanji_multibyte_char;
     is_multibyte_char_1 = is_kanji_multibyte_char_1;
-    is_multibyte_codepage_val = True;
+    global_is_multibyte_codepage = True;
     break;
   case HANGUL_CODEPAGE:
     multibyte_strchr = generic_multibyte_strchr;
@@ -1197,7 +1193,7 @@ void initialize_multibyte_vectors( int client_codepage)
     multibyte_strtok = generic_multibyte_strtok;
     _skip_multibyte_char = skip_generic_multibyte_char;
     is_multibyte_char_1 = hangul_is_multibyte_char_1;
-    is_multibyte_codepage_val = True;
+    global_is_multibyte_codepage = True;
     break;
   case BIG5_CODEPAGE:
     multibyte_strchr = generic_multibyte_strchr;
@@ -1206,7 +1202,7 @@ void initialize_multibyte_vectors( int client_codepage)
     multibyte_strtok = generic_multibyte_strtok;
     _skip_multibyte_char = skip_generic_multibyte_char;
     is_multibyte_char_1 = big5_is_multibyte_char_1;
-    is_multibyte_codepage_val = True;
+    global_is_multibyte_codepage = True;
     break;
   case SIMPLIFIED_CHINESE_CODEPAGE:
     multibyte_strchr = generic_multibyte_strchr;
@@ -1215,7 +1211,7 @@ void initialize_multibyte_vectors( int client_codepage)
     multibyte_strtok = generic_multibyte_strtok;
     _skip_multibyte_char = skip_generic_multibyte_char;
     is_multibyte_char_1 = simpch_is_multibyte_char_1;
-    is_multibyte_codepage_val = True;
+    global_is_multibyte_codepage = True;
     break;
   /*
    * Single char size code page.
@@ -1227,7 +1223,7 @@ void initialize_multibyte_vectors( int client_codepage)
     multibyte_strtok = (char *(*)(char *, const char *)) strtok;
     _skip_multibyte_char = skip_non_multibyte_char;
     is_multibyte_char_1 = not_multibyte_char_1;
-    is_multibyte_codepage_val = False;
+    global_is_multibyte_codepage = False;
     break; 
   }
 }
index 6fc64aafe2f3b7866da0c27e37f32af0ac766ad8..726e8c1f21aee86998cacb1a9227cd73593f908f 100644 (file)
@@ -39,7 +39,7 @@ pid_t pidfile_pid(char *name)
 
        slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
 
-       fd = open(pidFile, O_NONBLOCK | O_RDWR);
+       fd = sys_open(pidFile, O_NONBLOCK | O_RDWR, 0644);
        if (fd == -1) {
                return 0;
        }
@@ -52,7 +52,7 @@ pid_t pidfile_pid(char *name)
 
        ret = atoi(pidstr);
        
-       if (!process_exists(ret)) {
+       if (!process_exists((pid_t)ret)) {
                goto ok;
        }
 
@@ -76,14 +76,14 @@ void pidfile_create(char *name)
        int     fd;
        char    buf[20];
        pstring pidFile;
-       int pid;
+       pid_t pid;
 
        slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
 
        pid = pidfile_pid(name);
        if (pid != 0) {
                DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", 
-                        name, pidFile, pid));
+                        name, pidFile, (int)pid));
                exit(1);
        }
 
@@ -109,4 +109,3 @@ void pidfile_create(char *name)
        }
        /* Leave pid file open & locked for the duration... */
 }
-
index c6a4259417714133e9a8babf1e4bcf3ac76eb5ad..8d91c2d785c6df5d23f17f75e59e4738ea231b90 100644 (file)
@@ -70,7 +70,7 @@ Corrections by richard.kettlewell@kewill.com
   epoch = (t->tm_year - 70) * YEAR + 
     ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
 
-  y = t->tm_year;
+  y = t->tm_year + 1900;
   m = 0;
 
   for(i = 0; i < t->tm_mon; i++) {
@@ -163,16 +163,21 @@ Corrections by richard.kettlewell@kewill.com
        /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
        return(0);
 #else /* HAVE_SETGROUPS */
-       gid_t  grouplst[NGROUPS_MAX];
+       gid_t *grouplst = NULL;
+       int max_gr = groups_max();
+       int ret;
        int    i,j;
        struct group *g;
        char   *gr;
        
-       setgrent();
+       if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) {
+               DEBUG(0,("initgroups: malloc fail !\n");
+               return -1;
+       }
+
        grouplst[0] = id;
        i = 1;
-       while (i < NGROUPS_MAX && 
-              ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
+       while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
                if (g->gr_gid == id)
                        continue;
                j = 0;
@@ -188,7 +193,9 @@ Corrections by richard.kettlewell@kewill.com
                }
        }
        endgrent();
-       return(setgroups(i,grouplst));
+       ret = sys_setgroups(i,grouplst);
+       free((char *)grouplst);
+       return ret;
 #endif /* HAVE_SETGROUPS */
 }
 #endif /* HAVE_INITGROUPS */
index d80d55a556d2e04a98ed5ca8a053802852d97225..5a016cd5cd8bc38ba85b843f0e554f58aacfacb2 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "includes.h"
 
+/* need to move this from here!! need some sleep ... */
 struct current_user current_user;
 
 extern int DEBUGLEVEL;
index 0b2f40c8511ac078d23978cdf26c7f330c02a28c..7e1e8275da0fe9d26003380a0e9e07dfe57e09e9 100644 (file)
@@ -1,7 +1,8 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 1.9.
-   Groupname handling
+   Version 2.0
+
+   SURS - SID to UID Resolution System.
    Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
    
    This program is free software; you can redistribute it and/or modify
 */
 
 #include "includes.h"
+#include "surs.h"
 
 extern int DEBUGLEVEL;
 
 /******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id.  the Domain SID is,
- and can only be, our own SID.
+ converts SID + SID_NAME_USE type to a UNIX id.
  ********************************************************************/
-BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create)
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id, BOOL create)
 {
+#if 0
 #ifdef WITH_NT5LDAP
-       return surs_nt5ldap_sam_sid_to_unixid(id, type, sid, create);
+       return surs_nt5ldap_sam_sid_to_unixid(id, sid, create);
 #endif
 #if WITH_SURSTDB
-       return surs_tdb_sam_sid_to_unixid(id, type, sid, create);
+       return surs_tdb_sam_sid_to_unixid(id, sid, create);
+#endif
 #endif
-       return surs_algdomonly_sam_sid_to_unixid(sid, type, id, create);
+       return surs_algdomonly_sam_sid_to_unixid(sid, id, create);
 }
 
 /******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID.  the Domain SID is,
- and can only be, our own SID.
+ converts UNIX id + type to a SID.
  ********************************************************************/
-BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create)
+BOOL surs_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid, BOOL create)
 {
+#if 0
 #ifdef WITH_NT5LDAP
-       return surs_nt5ldap_unixid_to_sam_sid(id, type, sid, create);
+       return surs_nt5ldap_unixid_to_sam_sid(id, sid, create);
 #endif
 #if WITH_SURSTDB
-       return surs_tdb_unixid_to_sam_sid(id, type, sid, create);
+       return surs_tdb_unixid_to_sam_sid(id, sid, create);
+#endif
 #endif
-       return surs_algdomonly_unixid_to_sam_sid(id, type, sid, create);
+       return surs_algdomonly_unixid_to_sam_sid(id, sid, create);
 }
diff --git a/source/lib/surs.h b/source/lib/surs.h
new file mode 100644 (file)
index 0000000..03d978f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _SURS_H_
+#define _SURS_H_
+
+typedef enum 
+{
+       SURS_POSIX_UID_AS_USR,
+       SURS_POSIX_GID_AS_GRP,
+       SURS_POSIX_GID_AS_ALS
+} posix_type;
+
+typedef struct _surs_posix_id
+{
+       uint32 id;
+       posix_type type;
+}
+POSIX_ID;
+
+#endif /* _SURS_H_ */
index 583928872b2b96c0340071dd95d33f3d5bd1a5f5..e24b0dd58529310ac47600b86637f79a84c37fdd 100644 (file)
 
 extern int DEBUGLEVEL;
 
-/*******************************************************************
- converts a RID to a UNIX ID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_rid_to_unix_id(uint32 rid, uint32 *id, int type)
+static int sursalg_rid_posix_type(uint32 rid)
 {
-       if((id == NULL) || (rid < 1000))
-               return False;
-       rid -= 1000;
-       if((rid % RID_MULTIPLIER) != type)
-               return False;
-       *id = rid / RID_MULTIPLIER;
-       return True;
+       return ((rid-1000) % RID_MULTIPLIER);
 }
 
-/*******************************************************************
- converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_user_rid_to_uid(uint32 user_rid, uint32 *id)
+static uint32 sursalg_rid_posix_id(uint32 rid)
 {
-       return sursalg_rid_to_unix_id(user_rid, id, RID_TYPE_USER);
-}
-
-/*******************************************************************
- converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_group_rid_to_gid(uint32 group_rid, uint32 *id)
-{
-       return sursalg_rid_to_unix_id(group_rid, id, RID_TYPE_GROUP);
-}
-
-/*******************************************************************
- converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static BOOL sursalg_alias_rid_to_gid(uint32 alias_rid, uint32 *id)
-{
-       return sursalg_rid_to_unix_id(alias_rid, id, RID_TYPE_ALIAS);
+       return (rid-1000) / RID_MULTIPLIER;
 }
 
 /*******************************************************************
@@ -97,14 +69,15 @@ static uint32 sursalg_uid_to_user_rid(uint32 uid)
 }
 
 /******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id.  the Domain SID is,
+ converts SID to a UNIX id + type.  the Domain SID is,
  and can only be, our own SID.
  ********************************************************************/
-BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, POSIX_ID *id,
                                BOOL create)
 {
        DOM_SID tmp_sid;
        uint32 rid;
+       int type;
 
        sid_copy(&tmp_sid, sid);
        sid_split_rid(&tmp_sid, &rid);
@@ -113,49 +86,60 @@ BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
                return False;
        }
 
+       if((id == NULL) || (rid < 1000))
+               return False;
+
+       type = sursalg_rid_posix_type(rid);
+       id->id = sursalg_rid_posix_id(rid);
+
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
-                       return sursalg_user_rid_to_uid(rid, id);
+                       id->type = SURS_POSIX_UID_AS_USR;
+                       return True;
                }
-               case SID_NAME_ALIAS:
+               case RID_TYPE_ALIAS:
                {
-                       return sursalg_alias_rid_to_gid(rid, id);
+                       id->type = SURS_POSIX_GID_AS_ALS;
+                       return True;
                }
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_GROUP:
                {
-                       return sursalg_group_rid_to_gid(rid, id);
+                       id->type = SURS_POSIX_GID_AS_GRP;
+                       return True;
+               }
+               default:
+               {
+                       break;
                }
        }
        return False;
 }
 
 /******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID.  the Domain SID is,
+ converts UNIX id + type to a SID.  the Domain SID is,
  and can only be, our own SID.
  ********************************************************************/
-BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+BOOL surs_algdomonly_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid,
                                BOOL create)
 {
        sid_copy(sid, &global_sam_sid);
-       switch (type)
+       switch (id->type)
        {
-               case SID_NAME_USER:
+               case SURS_POSIX_UID_AS_USR:
                {
-                       sid_append_rid(sid, sursalg_uid_to_user_rid(id));
+                       sid_append_rid(sid, sursalg_uid_to_user_rid(id->id));
                        return True;
                }
-               case SID_NAME_ALIAS:
+               case SURS_POSIX_GID_AS_ALS:
                {
-                       sid_append_rid(sid, sursalg_gid_to_alias_rid(id));
+                       sid_append_rid(sid, sursalg_gid_to_alias_rid(id->id));
                        return True;
                }
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case SURS_POSIX_GID_AS_GRP:
                {
-                       sid_append_rid(sid, sursalg_gid_to_group_rid(id));
+                       sid_append_rid(sid, sursalg_gid_to_group_rid(id->id));
                        return True;
                }
        }
index c6fe9b11afba4bbf942b4953a778f36609058fa6..652e02046dbc551297f30dde6c685bd1ed2f7ad3 100644 (file)
@@ -68,14 +68,13 @@ BOOL surs_nt5ldap_unixid_to_sam_sid(LDAPDB *hds, uint32 id, uint32 type,
 
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
                        attribute = "uidNumber";
                        break;
                }
-               case SID_NAME_ALIAS:
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_GROUP:
+               case RID_TYPE_ALIAS:
                {
                        attribute = "gidNumber";
                        break;
index 2f2da61b3de2afdd6100cea1f5d6f433567e7fb6..76775830c0d7f47ec29987058e0d7e1878d46e8c 100644 (file)
@@ -415,7 +415,7 @@ static BOOL tdb_surs_lock(void)
 }
 
 /******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id.
+ converts SID + RID_TYPE_USE type to a UNIX id.
  ********************************************************************/
 BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
                                BOOL create)
@@ -431,16 +431,15 @@ BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
        }
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
                        ret = tdb_lookup_sid(sid, id);
                }
-               case SID_NAME_ALIAS:
+               case RID_TYPE_ALIAS:
                {
                        ret = tdb_lookup_sid(sid, id);
                }
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_GROUP:
                {
                        ret = tdb_lookup_sid(sid, id);
                }
@@ -460,14 +459,13 @@ BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
 
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
                        ret = tdb_store_uid(*id, sid)
                                && tdb_store_sid(sid, *id);
                }
-               case SID_NAME_ALIAS:
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_ALIAS:
+               case RID_TYPE_GROUP:
                {
                        ret = tdb_store_gid(*id, sid)
                                && tdb_store_sid(sid, *id);
@@ -480,7 +478,7 @@ BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
 }
 
 /******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID.
+ converts UNIX gid + RID_TYPE_USE type to a SID.
  ********************************************************************/
 BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
                                BOOL create)
@@ -497,13 +495,12 @@ BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
        }
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
                        ret = tdb_lookup_uid(id, sid);
                }
-               case SID_NAME_ALIAS:
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_ALIAS:
+               case RID_TYPE_GROUP:
                {
                        ret = tdb_lookup_gid(id, sid);
                }
@@ -524,14 +521,13 @@ BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
 
        switch (type)
        {
-               case SID_NAME_USER:
+               case RID_TYPE_USER:
                {
                        ret = tdb_store_uid(id, sid)
                                && tdb_store_sid(sid, id);
                }
-               case SID_NAME_ALIAS:
-               case SID_NAME_DOM_GRP:
-               case SID_NAME_WKN_GRP:
+               case RID_TYPE_ALIAS:
+               case RID_TYPE_GROUP:
                {
                        ret = tdb_store_gid(id, sid)
                                && tdb_store_sid(sid, id);
index 4d968f0e986c5a9b2740db078cde1907fe916654..933b0c7a72bd54b9b8985a423de338aa913479e0 100644 (file)
@@ -180,11 +180,15 @@ A stat() wrapper that will deal with 64 bit filesizes.
 
 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
 {
-#if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
-  return stat64(fname, sbuf);
+       int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
+       ret = stat64(fname, sbuf);
 #else
-  return stat(fname, sbuf);
+       ret = stat(fname, sbuf);
 #endif
+       /* we always want directories to appear zero size */
+       if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+       return ret;
 }
 
 /*******************************************************************
@@ -193,11 +197,15 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
 
 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
 {
-#if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
-  return fstat64(fd, sbuf);
+       int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
+       ret = fstat64(fd, sbuf);
 #else
-  return fstat(fd, sbuf);
+       ret = fstat(fd, sbuf);
 #endif
+       /* we always want directories to appear zero size */
+       if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+       return ret;
 }
 
 /*******************************************************************
@@ -206,11 +214,15 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
 
 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
 {
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
-  return lstat64(fname, sbuf);
+       int ret;
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
+       ret = lstat64(fname, sbuf);
 #else
-  return lstat(fname, sbuf);
+       ret = lstat(fname, sbuf);
 #endif
+       /* we always want directories to appear zero size */
+       if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
+       return ret;
 }
 
 /*******************************************************************
@@ -219,7 +231,7 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
 
 int sys_ftruncate(int fd, SMB_OFF_T offset)
 {
-#if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
   return ftruncate64(fd, offset);
 #else
   return ftruncate(fd, offset);
@@ -232,7 +244,7 @@ int sys_ftruncate(int fd, SMB_OFF_T offset)
 
 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
 {
-#if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
   return lseek64(fd, offset, whence);
 #else
   return lseek(fd, offset, whence);
@@ -245,8 +257,10 @@ SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
 
 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
 {
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
   return fseek64(fp, offset, whence);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
+  return fseeko64(fp, offset, whence);
 #else
   return fseek(fp, offset, whence);
 #endif
@@ -258,8 +272,10 @@ int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
 
 SMB_OFF_T sys_ftell(FILE *fp)
 {
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
   return (SMB_OFF_T)ftell64(fp);
+#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
+  return (SMB_OFF_T)ftello64(fp);
 #else
   return (SMB_OFF_T)ftell(fp);
 #endif
@@ -308,19 +324,36 @@ FILE *sys_fopen(const char *path, const char *type)
 #endif
 }
 
+#if defined(HAVE_MMAP)
+
 /*******************************************************************
  An mmap() wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
 
 void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset)
 {
-#if defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
   return mmap64(addr, len, prot, flags, fd, offset);
 #else
   return mmap(addr, len, prot, flags, fd, offset);
 #endif
 }
 
+#endif /* HAVE_MMAP */
+
+/*******************************************************************
+ A readdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
+  return readdir64(dirp);
+#else
+  return readdir(dirp);
+#endif
+}
+
 /*******************************************************************
 The wait() calls vary between systems
 ********************************************************************/
@@ -339,18 +372,19 @@ system wrapper for getwd
 ********************************************************************/
 char *sys_getwd(char *s)
 {
-       char *wd;
+    char *wd;
 #ifdef HAVE_GETCWD
-       wd = (char *)getcwd(s, sizeof (pstring));
+    wd = (char *)getcwd(s, sizeof (pstring));
 #else
-       wd = (char *)getwd(s);
+    wd = (char *)getwd(s);
 #endif
-       return wd;
+    return wd;
 }
 
 /*******************************************************************
 chown isn't used much but OS/2 doesn't have it
 ********************************************************************/
+
 int sys_chown(const char *fname,uid_t uid,gid_t gid)
 {
 #ifndef HAVE_CHOWN
@@ -447,9 +481,12 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable )
     if (cap_set_proc(cap) == -1) {
       DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
             strerror(errno)));
+      cap_free(cap);
       return False;
     }
 
+    cap_free(cap);
+
     DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
   }
 #endif
@@ -481,9 +518,12 @@ BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
     if (cap_set_proc(cap) == -1) {
       DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n", 
             strerror(errno)));
+      cap_free(cap);
       return False;
     }
 
+    cap_free(cap);
+
     DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
   }
 #endif
@@ -522,6 +562,20 @@ void sys_srandom(unsigned int seed)
 #endif
 }
 
+/**************************************************************************
+ Returns equivalent to NGROUPS_MAX - using sysconf if needed.
+****************************************************************************/
+
+int groups_max(void)
+{
+#if defined(SYSCONF_SC_NGROUPS_MAX)
+  int ret = sysconf(_SC_NGROUPS_MAX);
+  return (ret == -1) ? NGROUPS_MAX : ret;
+#else
+  return NGROUPS_MAX;
+#endif
+}
+
 /**************************************************************************
  Wrapper for getgroups. Deals with broken (int) case.
 ****************************************************************************/
@@ -550,7 +604,8 @@ int sys_getgroups(int setlen, gid_t *gidset)
     return -1;
   } 
 
-  if (setlen == 0) setlen = 1;
+  if (setlen == 0)
+    setlen = groups_max();
 
   if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
     DEBUG(0,("sys_getgroups: Malloc fail.\n"));
@@ -572,6 +627,57 @@ int sys_getgroups(int setlen, gid_t *gidset)
 #endif /* HAVE_BROKEN_GETGROUPS */
 }
 
+#ifdef HAVE_SETGROUPS
+
+/**************************************************************************
+ Wrapper for setgroups. Deals with broken (int) case. Automatically used
+ if we have broken getgroups.
+****************************************************************************/
+
+int sys_setgroups(int setlen, gid_t *gidset)
+{
+#if !defined(HAVE_BROKEN_GETGROUPS)
+  return setgroups(setlen, gidset);
+#else
+
+  GID_T *group_list;
+  int i ; 
+
+  if (setlen == 0)
+    return 0 ;
+
+  if (setlen < 0 || setlen > groups_max()) {
+    errno = EINVAL; 
+    return -1;   
+  }
+
+  /*
+   * Broken case. We need to allocate a
+   * GID_T array of size setlen.
+   */
+
+  if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
+    DEBUG(0,("sys_setgroups: Malloc fail.\n"));
+    return -1;    
+  }
+  for(i = 0; i < setlen; i++) 
+    group_list[i] = (GID_T) gidset[i]; 
+
+  if(setgroups(setlen, group_list) != 0) {
+    int saved_errno = errno;
+    free((char *)group_list);
+    errno = saved_errno;
+    return -1;
+  }
+  free((char *)group_list);
+  return 0 ;
+#endif /* HAVE_BROKEN_GETGROUPS */
+}
+
+#endif /* HAVE_SETGROUPS */
+
 /*
  * We only wrap pw_name and pw_passwd for now as these
  * are the only potentially modified fields.
@@ -581,7 +687,7 @@ int sys_getgroups(int setlen, gid_t *gidset)
  Helper function for getpwnam/getpwuid wrappers.
 ****************************************************************************/
 
-struct passwd *copy_passwd_struct(struct passwd *pass)
+static struct passwd *setup_pwret(struct passwd *pass)
 {
        static pstring pw_name;
        static pstring pw_passwd;
@@ -592,25 +698,16 @@ struct passwd *copy_passwd_struct(struct passwd *pass)
                return NULL;
        }
 
-       if (pass == &pw_ret)
-       {
-               /* catch silly error where buffer was already copied */
-               DEBUG(0,("copy_passwd_struct: can't copy internal buffer!\n"));
-               return NULL;
-       }
-
        memcpy((char *)&pw_ret, pass, sizeof(struct passwd));
 
        if (pass->pw_name)
        {
-               pw_name[0] = '\0';
                pw_ret.pw_name = pw_name;
                pstrcpy(pw_ret.pw_name, pass->pw_name);
        }
 
        if (pass->pw_passwd)
        {
-               pw_passwd[0] = '\0';
                pw_ret.pw_passwd = pw_passwd;
                pstrcpy(pw_ret.pw_passwd, pass->pw_passwd);
        }
@@ -624,7 +721,7 @@ struct passwd *copy_passwd_struct(struct passwd *pass)
 
 struct passwd *sys_getpwnam(const char *name)
 {
-       return copy_passwd_struct(getpwnam(name));
+       return setup_pwret(getpwnam(name));
 }
 
 /**************************************************************************
@@ -633,7 +730,177 @@ struct passwd *sys_getpwnam(const char *name)
 
 struct passwd *sys_getpwuid(uid_t uid)
 {
-       return copy_passwd_struct(getpwuid(uid));
+       return setup_pwret(getpwuid(uid));
+}
+
+/**************************************************************************
+ The following are the UNICODE versions of *all* system interface functions
+ called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
+ which currently are left as ascii as they are not used other than in name
+ resolution.
+****************************************************************************/
+
+/**************************************************************************
+ Wide stat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
+{
+       pstring fname;
+       return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
+}
+
+/**************************************************************************
+ Wide lstat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
+{
+       pstring fname;
+       return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
+}
+
+/**************************************************************************
+ Wide creat. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
+{
+       pstring fname;
+       return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
+}
+
+/**************************************************************************
+ Wide open. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
+{
+       pstring fname;
+       return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
+}
+
+/**************************************************************************
+ Wide fopen. Just narrow and call sys_xxx.
+****************************************************************************/
+
+FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
+{
+       pstring fname;
+       return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
+}
+
+/**************************************************************************
+ Wide opendir. Just narrow and call sys_xxx.
+****************************************************************************/
+
+DIR *wsys_opendir(const smb_ucs2_t *wfname)
+{
+       pstring fname;
+       return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
+}
+
+/**************************************************************************
+ Wide readdir. Return a structure pointer containing a wide filename.
+****************************************************************************/
+
+SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
+{
+       static SMB_STRUCT_WDIRENT retval;
+       SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
+
+       if(!dirval)
+               return NULL;
+
+       /*
+        * The only POSIX defined member of this struct is d_name.
+        */
+
+       unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
+
+       return &retval;
+}
+
+/**************************************************************************
+ Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
+****************************************************************************/
+
+smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
+{
+       pstring fname;
+       char *p = sys_getwd(fname);
+
+       if(!p)
+               return NULL;
+
+       return unix_to_unicode(s, p, sizeof(wpstring));
+}
+
+/**************************************************************************
+ Wide chown. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
+{
+       pstring fname;
+       return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
+}
+
+/**************************************************************************
+ Wide chroot. Just narrow and call sys_xxx.
+****************************************************************************/
+
+int wsys_chroot(const smb_ucs2_t *wfname)
+{
+       pstring fname;
+       return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
+}
+
+/**************************************************************************
+ Wide getpwnam. Return a structure pointer containing wide names.
+****************************************************************************/
+
+SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
+{
+       static SMB_STRUCT_WPASSWD retval;
+       fstring name;
+       struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
+
+       if(!pwret)
+               return NULL;
+
+       unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
+       retval.pw_passwd = pwret->pw_passwd;
+       retval.pw_uid = pwret->pw_uid;
+       retval.pw_gid = pwret->pw_gid;
+       unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
+       unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
+       unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
+
+       return &retval;
+}
+
+/**************************************************************************
+ Wide getpwuid. Return a structure pointer containing wide names.
+****************************************************************************/
+
+SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
+{
+       static SMB_STRUCT_WPASSWD retval;
+       struct passwd *pwret = sys_getpwuid(uid);
+
+       if(!pwret)
+               return NULL;
+
+       unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
+       retval.pw_passwd = pwret->pw_passwd;
+       retval.pw_uid = pwret->pw_uid;
+       retval.pw_gid = pwret->pw_gid;
+       unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
+       unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
+       unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
+
+       return &retval;
 }
 
 /**************************************************************************
index 4a0d8a36bcae8ad3e29daa3a88ddf010a36a7b28..21074630b546c29af0190ff0196df914b8144f5f 100644 (file)
@@ -581,8 +581,8 @@ BOOL user_ok(char *user,int snum)
        StrnCpy(valid, lp_valid_users(snum), sizeof(pstring));
        StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring));
 
-       string_sub(valid,"%S",lp_servicename(snum));
-       string_sub(invalid,"%S",lp_servicename(snum));
+       pstring_sub(valid,"%S",lp_servicename(snum));
+       pstring_sub(invalid,"%S",lp_servicename(snum));
        
        ret = !user_in_list(user,invalid);
        
@@ -592,7 +592,7 @@ BOOL user_ok(char *user,int snum)
 
        if (ret && lp_onlyuser(snum)) {
                char *user_list = lp_username(snum);
-               string_sub(user_list,"%S",lp_servicename(snum));
+               pstring_sub(user_list,"%S",lp_servicename(snum));
                ret = user_in_list(user,user_list);
        }
 
index 5f30b7eedf5a3ff92d844c3610c642ee34114ede..613eee18a59e85f8da9061b96828a28f6b14ed9a 100644 (file)
@@ -141,12 +141,12 @@ uint32 get_number(const char *tmp)
        if (strnequal(tmp, "0x", 2))
        {
                ret = strtoul(tmp, (char **)NULL, 16);
-               DEBUG(10,("get_number: %s -> 0x%x\n", tmp, ret));
+               DEBUG(10, ("get_number: %s -> 0x%x\n", tmp, ret));
        }
        else
        {
                ret = strtoul(tmp, (char **)NULL, 10);
-               DEBUG(10,("get_number: %s -> %d\n", tmp, ret));
+               DEBUG(10, ("get_number: %s -> %d\n", tmp, ret));
        }
        return ret;
 }
@@ -184,7 +184,7 @@ char *Atoic(char *p, int *n, char *c)
        return p;
 }
 
-uint32 *add_num_to_list(uint32 ** num, int *count, int val)
+uint32 *add_num_to_list(uint32 **num, int *count, int val)
 {
        (*num) = Realloc((*num), ((*count) + 1) * sizeof(uint32));
        if ((*num) == NULL)
@@ -200,7 +200,7 @@ uint32 *add_num_to_list(uint32 ** num, int *count, int val)
 /*************************************************************************
  reads a list of numbers
  *************************************************************************/
-char *get_numlist(char *p, uint32 ** num, int *count)
+char *get_numlist(char *p, uint32 **num, int *count)
 {
        int val;
 
@@ -224,14 +224,6 @@ char *get_numlist(char *p, uint32 ** num, int *count)
        return p;
 }
 
-/*******************************************************************
-copy an IP address from one buffer to another
-********************************************************************/
-void putip(void *dest, void *src)
-{
-       memcpy(dest, src, 4);
-}
-
 /*******************************************************************
   check if a file exists
 ********************************************************************/
@@ -332,22 +324,6 @@ char *attrib_string(uint16 mode)
        return (attrstr);
 }
 
-/****************************************************************************
-  make a file into unix format
-****************************************************************************/
-void unix_format(char *fname)
-{
-       string_replace(fname, '\\', '/');
-}
-
-/****************************************************************************
-  make a file into dos format
-****************************************************************************/
-void dos_format(char *fname)
-{
-       string_replace(fname, '/', '\\');
-}
-
 /*******************************************************************
   show a smb message structure
 ********************************************************************/
@@ -393,26 +369,6 @@ void show_msg(char *buf)
        dump_data(10, smb_buf(buf), bcc);
 }
 
-/*******************************************************************
-  return the length of an smb packet
-********************************************************************/
-int smb_len(char *buf)
-{
-       return (PVAL(buf, 3) | (PVAL(buf, 2) << 8) |
-               ((PVAL(buf, 1) & 1) << 16));
-}
-
-/*******************************************************************
-  set the length of an smb packet
-********************************************************************/
-void _smb_setlen(char *buf, int len)
-{
-       buf[0] = 0;
-       buf[1] = (len & 0x10000) >> 16;
-       buf[2] = (len & 0xFF00) >> 8;
-       buf[3] = len & 0xFF;
-}
-
 /*******************************************************************
   set the length and marker of an smb packet
 ********************************************************************/
@@ -432,84 +388,310 @@ void smb_setlen(char *buf, int len)
 int set_message(char *buf, int num_words, int num_bytes, BOOL zero)
 {
        if (zero)
-               memset(buf + smb_size, 0,  num_words * 2 + num_bytes);
+               memset(buf + smb_size, 0, num_words * 2 + num_bytes);
        CVAL(buf, smb_wct) = num_words;
        SSVAL(buf, smb_vwv + num_words * SIZEOFWORD, num_bytes);
        smb_setlen(buf, smb_size + num_words * 2 + num_bytes - 4);
        return (smb_size + num_words * 2 + num_bytes);
 }
 
-/*******************************************************************
-return the number of smb words
-********************************************************************/
-static int smb_numwords(char *buf)
-{
-       return (CVAL(buf, smb_wct));
-}
 
-/*******************************************************************
-return the size of the smb_buf region of a message
-********************************************************************/
-int smb_buflen(char *buf)
-{
-       return (SVAL(buf, smb_vwv0 + smb_numwords(buf) * 2));
-}
 
 /*******************************************************************
-  return a pointer to the smb_buf data area
+reduce a file name, removing .. elements.
 ********************************************************************/
-static int smb_buf_ofs(char *buf)
+void dos_clean_name(char *s)
 {
-       return (smb_size + CVAL(buf, smb_wct) * 2);
-}
+       char *p = NULL;
 
-/*******************************************************************
-  return a pointer to the smb_buf data area
-********************************************************************/
-char *smb_buf(char *buf)
-{
-       return (buf + smb_buf_ofs(buf));
-}
+       DEBUG(3, ("dos_clean_name [%s]\n", s));
 
-/*******************************************************************
-return the SMB offset into an SMB buffer
-********************************************************************/
-int smb_offset(char *p, char *buf)
-{
-       return (PTR_DIFF(p, buf + 4) + chain_size);
-}
+       /* remove any double slashes */
+       all_string_sub(s, "\\\\", "\\", 0);
 
+       while ((p = strstr(s, "\\..\\")) != NULL)
+       {
+               pstring s1;
+
+               *p = 0;
+               pstrcpy(s1, p + 3);
+
+               if ((p = strrchr(s, '\\')) != NULL)
+                       *p = 0;
+               else
+                       *s = 0;
+               pstrcat(s, s1);
+       }
+
+       trim_string(s, NULL, "\\..");
 
+       all_string_sub(s, "\\.\\", "\\", 0);
+}
 
 /*******************************************************************
-reduce a file name, removing .. elements.
+reduce a file name, removing .. elements. 
 ********************************************************************/
-void dos_clean_name(char *s)
+void unix_clean_name(char *s)
 {
        char *p = NULL;
 
-       DEBUG(3, ("dos_clean_name [%s]\n", s));
+       DEBUG(3, ("unix_clean_name [%s]\n", s));
 
        /* remove any double slashes */
-       string_sub(s, "\\\\", "\\");
+       all_string_sub(s, "//", "/", 0);
 
-       while ((p = strstr(s, "\\..\\")) != NULL)
+       /* Remove leading ./ characters */
+       if (strncmp(s, "./", 2) == 0)
+       {
+               trim_string(s, "./", NULL);
+               if (*s == 0)
+                       pstrcpy(s, "./");
+       }
+
+       while ((p = strstr(s, "/../")) != NULL)
        {
                pstring s1;
 
                *p = 0;
                pstrcpy(s1, p + 3);
 
-               if ((p = strrchr(s, '\\')) != NULL)
+               if ((p = strrchr(s, '/')) != NULL)
                        *p = 0;
                else
                        *s = 0;
                pstrcat(s, s1);
        }
 
-       trim_string(s, NULL, "\\..");
+       trim_string(s, NULL, "/..");
+}
+
+/*******************************************************************
+reduce a file name, removing .. elements and checking that 
+it is below dir in the heirachy. This uses dos_GetWd() and so must be run
+on the system that has the referenced file system.
+
+widelinks are allowed if widelinks is true
+********************************************************************/
+
+BOOL reduce_name(char *s, char *dir, BOOL widelinks)
+{
+#ifndef REDUCE_PATHS
+       return True;
+#else
+       pstring dir2;
+       pstring wd;
+       pstring base_name;
+       pstring newname;
+       char *p = NULL;
+       BOOL relative = (*s != '/');
+
+       *dir2 = *wd = *base_name = *newname = 0;
+
+       if (widelinks)
+       {
+               unix_clean_name(s);
+               /* can't have a leading .. */
+               if (strncmp(s, "..", 2) == 0 && (s[2] == 0 || s[2] == '/'))
+               {
+                       DEBUG(3, ("Illegal file name? (%s)\n", s));
+                       return (False);
+               }
+
+               if (strlen(s) == 0)
+                       pstrcpy(s, "./");
+
+               return (True);
+       }
+
+       DEBUG(3, ("reduce_name [%s] [%s]\n", s, dir));
+
+       /* remove any double slashes */
+       all_string_sub(s, "//", "/", 0);
 
-       string_sub(s, "\\.\\", "\\");
+       pstrcpy(base_name, s);
+       p = strrchr(base_name, '/');
+
+       if (!p)
+               return (True);
+
+       if (!dos_GetWd(wd))
+       {
+               DEBUG(0, ("couldn't getwd for %s %s\n", s, dir));
+               return (False);
+       }
+
+       if (dos_ChDir(dir) != 0)
+       {
+               DEBUG(0, ("couldn't chdir to %s\n", dir));
+               return (False);
+       }
+
+       if (!dos_GetWd(dir2))
+       {
+               DEBUG(0, ("couldn't getwd for %s\n", dir));
+               dos_ChDir(wd);
+               return (False);
+       }
+
+       if (p && (p != base_name))
+       {
+               *p = 0;
+               if (strcmp(p + 1, ".") == 0)
+                       p[1] = 0;
+               if (strcmp(p + 1, "..") == 0)
+                       *p = '/';
+       }
+
+       if (dos_ChDir(base_name) != 0)
+       {
+               dos_ChDir(wd);
+               DEBUG(3,
+                     ("couldn't chdir for %s %s basename=%s\n", s, dir,
+                      base_name));
+               return (False);
+       }
+
+       if (!dos_GetWd(newname))
+       {
+               dos_ChDir(wd);
+               DEBUG(2, ("couldn't get wd for %s %s\n", s, dir2));
+               return (False);
+       }
+
+       if (p && (p != base_name))
+       {
+               pstrcat(newname, "/");
+               pstrcat(newname, p + 1);
+       }
+
+       {
+               size_t l = strlen(dir2);
+               if (dir2[l - 1] == '/')
+                       l--;
+
+               if (strncmp(newname, dir2, l) != 0)
+               {
+                       dos_ChDir(wd);
+                       DEBUG(2,
+                             ("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",
+                              s, dir2, newname, (int)l));
+                       return (False);
+               }
+
+               if (relative)
+               {
+                       if (newname[l] == '/')
+                               pstrcpy(s, newname + l + 1);
+                       else
+                               pstrcpy(s, newname + l);
+               }
+               else
+                       pstrcpy(s, newname);
+       }
+
+       dos_ChDir(wd);
+
+       if (strlen(s) == 0)
+               pstrcpy(s, "./");
+
+       DEBUG(3, ("reduced to %s\n", s));
+       return (True);
+#endif
+}
+
+/****************************************************************************
+expand some *s 
+****************************************************************************/
+static void expand_one(char *Mask, int len)
+{
+       char *p1;
+       while ((p1 = strchr(Mask, '*')) != NULL)
+       {
+               int lfill = (len + 1) - strlen(Mask);
+               int l1 = (p1 - Mask);
+               pstring tmp;
+               pstrcpy(tmp, Mask);
+               memset(tmp + l1, '?', lfill);
+               pstrcpy(tmp + l1 + lfill, Mask + l1 + 1);
+               pstrcpy(Mask, tmp);
+       }
+}
+
+/****************************************************************************
+parse out a filename from a path name. Assumes dos style filenames.
+****************************************************************************/
+static char *filename_dos(char *path, char *buf)
+{
+       char *p = strrchr(path, '\\');
+
+       if (!p)
+               pstrcpy(buf, path);
+       else
+               pstrcpy(buf, p + 1);
+
+       return (buf);
+}
+
+
+/****************************************************************************
+expand a wildcard expression, replacing *s with ?s
+****************************************************************************/
+void expand_mask(char *Mask, BOOL doext)
+{
+       pstring mbeg, mext;
+       pstring dirpart;
+       pstring filepart;
+       BOOL hasdot = False;
+       char *p1;
+       BOOL absolute = (*Mask == '\\');
+
+       *mbeg = *mext = *dirpart = *filepart = 0;
+
+       /* parse the directory and filename */
+       if (strchr(Mask, '\\'))
+               split_at_last_component(Mask, dirpart, '\\', NULL);
+
+       filename_dos(Mask, filepart);
+
+       pstrcpy(mbeg, filepart);
+       if ((p1 = strchr(mbeg, '.')) != NULL)
+       {
+               hasdot = True;
+               *p1 = 0;
+               p1++;
+               pstrcpy(mext, p1);
+       }
+       else
+       {
+               pstrcpy(mext, "");
+               if (strlen(mbeg) > 8)
+               {
+                       pstrcpy(mext, mbeg + 8);
+                       mbeg[8] = 0;
+               }
+       }
+
+       if (*mbeg == 0)
+               pstrcpy(mbeg, "????????");
+       if ((*mext == 0) && doext && !hasdot)
+               pstrcpy(mext, "???");
+
+       if (strequal(mbeg, "*") && *mext == 0)
+               pstrcpy(mext, "*");
+
+       /* expand *'s */
+       expand_one(mbeg, 8);
+       if (*mext)
+               expand_one(mext, 3);
+
+       pstrcpy(Mask, dirpart);
+       if (*dirpart || absolute)
+               pstrcat(Mask, "\\");
+       pstrcat(Mask, mbeg);
+       pstrcat(Mask, ".");
+       pstrcat(Mask, mext);
+
+       DEBUG(6, ("Mask expanded to [%s]\n", Mask));
 }
 
 
@@ -539,7 +721,7 @@ void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
        else
                memcpy(buf + 1, mask2, MIN(strlen(mask2), 11));
 
-       memset(buf + 21, 0,  DIR_STRUCT_SIZE - 21);
+       memset(buf + 21, '\0', DIR_STRUCT_SIZE - 21);
        CVAL(buf, 21) = mode;
        put_dos_date(buf, 22, date);
        SSVAL(buf, 26, size & 0xFFFF);
@@ -610,19 +792,6 @@ int set_blocking(int fd, BOOL set)
 #undef FLAG_TO_SET
 }
 
-
-/*******************************************************************
-find the difference in milliseconds between two struct timeval
-values
-********************************************************************/
-int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew)
-{
-       return ((tvalnew->tv_sec - tvalold->tv_sec) * 1000 +
-               ((int)tvalnew->tv_usec - (int)tvalold->tv_usec) / 1000);
-}
-
-
-
 /****************************************************************************
 transfer some data between two fd's
 ****************************************************************************/
@@ -743,47 +912,14 @@ void msleep(int t)
        }
 }
 
-/****************************************************************************
-open the directory and look-up the matching names
-****************************************************************************/
-BOOL get_file_match(const char *dirname, const char *regexp,
-                   uint32 * total, char ***list)
-{
-       DIR *dirp;
-       char *dpname;
-
-       dirp = opendir(dirname);
-
-       if (dirp == NULL)
-       {
-               DEBUG(2, ("Error opening directory [%s]\n", dirname));
-               return False;
-       }
-
-       DEBUG(5, ("get_dir_match: %s with %s\n", dirname, regexp));
-
-       while ((dpname = readdirname(dirp)) != NULL)
-       {
-               if (do_match(dpname, regexp, False))
-               {
-                       DEBUGADD(7, ("Found: [%s]\n", dpname));
-
-                       add_chars_to_array(total, list, dpname);
-                       DEBUGADD(6, ("Added: [%s]\n", dpname));
-               }
-       }
-
-       closedir(dirp);
-
-       return True;
-}
 
 /*********************************************************
 * Recursive routine that is called by unix_mask_match.
 * Does the actual matching. This is the 'original code' 
 * used by the unix matcher.
 *********************************************************/
-static BOOL unix_do_match(char *str, char *regexp, int case_sig)
+
+BOOL unix_do_match(char *str, char *regexp, BOOL case_sig)
 {
        char *p;
 
@@ -797,8 +933,10 @@ static BOOL unix_do_match(char *str, char *regexp, int case_sig)
                                break;
 
                        case '*':
-                               /* Look for a character matching 
-                                  the one after the '*' */
+                               /*
+                                * Look for a character matching 
+                                * the one after the '*'.
+                                */
                                p++;
                                if (!*p)
                                        return True;    /* Automatic match */
@@ -809,6 +947,54 @@ static BOOL unix_do_match(char *str, char *regexp, int case_sig)
                                                   : (toupper(*p) !=
                                                      toupper(*str))))
                                                str++;
+
+                                       /*
+                                        * Patch from weidel@multichart.de. In the case of the regexp
+                                        * '*XX*' we want to ensure there are at least 2 'X' characters
+                                        * in the filename after the '*' for a match to be made.
+                                        */
+
+                                       {
+                                               int matchcount = 0;
+
+                                               /*
+                                                * Eat all the characters that match, but count how many there were.
+                                                */
+
+                                               while (*str
+                                                      && (case_sig
+                                                          ? (*p ==
+                                                             *str)
+                                                          : (toupper(*p) ==
+                                                             toupper(*str))))
+                                               {
+                                                       str++;
+                                                       matchcount++;
+                                               }
+
+                                               /*
+                                                * Now check that if the regexp had n identical characters that
+                                                * matchcount had at least that many matches.
+                                                */
+
+                                               while (
+                                                      (*(p + 1)
+                                                       && (case_sig
+                                                           ? (*(p + 1) ==
+                                                              *p)
+                                                           : (toupper
+                                                              (*(p + 1)) ==
+                                                              toupper(*p)))))
+                                               {
+                                                       p++;
+                                                       matchcount--;
+                                               }
+                                               if (matchcount <= 0)
+                                               {
+                                                       return False;
+                                               }
+                                       }
+                                       str--;  /* We've eaten the match char after the '*' */
                                        if (unix_do_match(str, p, case_sig))
                                                return True;
                                        if (!*str)
@@ -859,24 +1045,17 @@ static BOOL unix_do_match(char *str, char *regexp, int case_sig)
 * This is the 'original code' used by the unix matcher.
 *********************************************************/
 
-static BOOL unix_mask_match(char *str, char *regexp, int case_sig,
-                           BOOL trans2)
+static BOOL unix_mask_match(char *str, char *regexp, BOOL case_sig)
 {
        char *p;
        pstring p1, p2;
-       fstring ebase, eext, sbase, sext;
-
+       fstring ebase, sbase;
        BOOL matched;
 
        /* Make local copies of str and regexp */
        StrnCpy(p1, regexp, sizeof(pstring) - 1);
        StrnCpy(p2, str, sizeof(pstring) - 1);
 
-       if (!strchr(p2, '.'))
-       {
-               pstrcat(p2, ".");
-       }
-
        /* Remove any *? and ** as they are meaningless */
        for (p = p1; *p; p++)
                while (*p == '*' && (p[1] == '?' || p[1] == '*'))
@@ -889,41 +1068,10 @@ static BOOL unix_mask_match(char *str, char *regexp, int case_sig,
              ("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2,
               p1, case_sig));
 
-       if (trans2)
-       {
-               fstrcpy(ebase, p1);
-               fstrcpy(sbase, p2);
-       }
-       else
-       {
-               if ((p = strrchr(p1, '.')))
-               {
-                       *p = 0;
-                       fstrcpy(ebase, p1);
-                       fstrcpy(eext, p + 1);
-               }
-               else
-               {
-                       fstrcpy(ebase, p1);
-                       eext[0] = 0;
-               }
-
-               if (!strequal(p2, ".") && !strequal(p2, "..")
-                   && (p = strrchr(p2, '.')))
-               {
-                       *p = 0;
-                       fstrcpy(sbase, p2);
-                       fstrcpy(sext, p + 1);
-               }
-               else
-               {
-                       fstrcpy(sbase, p2);
-                       fstrcpy(sext, "");
-               }
-       }
+       fstrcpy(ebase, p1);
+       fstrcpy(sbase, p2);
 
-       matched = unix_do_match(sbase, ebase, case_sig) &&
-               (trans2 || unix_do_match(sext, eext, case_sig));
+       matched = unix_do_match(sbase, ebase, case_sig);
 
        DEBUG(8, ("unix_mask_match returning %d\n", matched));
 
@@ -934,11 +1082,17 @@ static BOOL unix_mask_match(char *str, char *regexp, int case_sig,
 * Recursive routine that is called by mask_match.
 * Does the actual matching. Returns True if matched,
 * False if failed. This is the 'new' NT style matcher.
+* The win9x_semantics parameter is needed as Win9x matching
+* is *actually different*. In Win9x, trailing '?' characters
+* will only match the *exact* number of characters. Under
+* DOS and NT they match any number. This makes no
+* sense.....
 *********************************************************/
 
-BOOL do_match(char *str, const char *regexp, int case_sig)
+static BOOL do_match(char *str, char *regexp, int case_sig,
+                    BOOL win9x_semantics)
 {
-       const char *p;
+       char *p;
 
        for (p = regexp; *p && *str;)
        {
@@ -962,15 +1116,57 @@ BOOL do_match(char *str, const char *regexp, int case_sig)
                                                   : (toupper(*p) !=
                                                      toupper(*str))))
                                                str++;
-                                       /* Now eat all characters that match, as
-                                          we want the *last* character to match. */
-                                       while (*str
-                                              && (case_sig ? (*p == *str)
-                                                  : (toupper(*p) ==
-                                                     toupper(*str))))
-                                               str++;
+
+                                       /*
+                                        * Patch from weidel@multichart.de. In the case of the regexp
+                                        * '*XX*' we want to ensure there are at least 2 'X' characters
+                                        * in the filename after the '*' for a match to be made.
+                                        */
+
+                                       {
+                                               int matchcount = 0;
+
+                                               /*
+                                                * Eat all the characters that match, but count how many there were.
+                                                */
+
+                                               while (*str
+                                                      && (case_sig
+                                                          ? (*p ==
+                                                             *str)
+                                                          : (toupper(*p) ==
+                                                             toupper(*str))))
+                                               {
+                                                       str++;
+                                                       matchcount++;
+                                               }
+
+                                               /*
+                                                * Now check that if the regexp had n identical characters that
+                                                * matchcount had at least that many matches.
+                                                */
+
+                                               while (
+                                                      (*(p + 1)
+                                                       && (case_sig
+                                                           ? (*(p + 1) ==
+                                                              *p)
+                                                           : (toupper
+                                                              (*(p + 1)) ==
+                                                              toupper(*p)))))
+                                               {
+                                                       p++;
+                                                       matchcount--;
+                                               }
+                                               if (matchcount <= 0)
+                                               {
+                                                       return False;
+                                               }
+                                       }
                                        str--;  /* We've eaten the match char after the '*' */
-                                       if (do_match(str, p, case_sig))
+                                       if (do_match
+                                           (str, p, case_sig,
+                                            win9x_semantics))
                                        {
                                                return True;
                                        }
@@ -1013,11 +1209,14 @@ BOOL do_match(char *str, const char *regexp, int case_sig)
                return (True);
        }
 
-       if (!*str && *p == '?')
+       if (!win9x_semantics)
        {
-               while (*p == '?')
-                       p++;
-               return (!*p);
+               if (!*str && *p == '?')
+               {
+                       while (*p == '?')
+                               p++;
+                       return (!*p);
+               }
        }
 
        if (!*str && (*p == '*' && p[1] == '\0'))
@@ -1037,18 +1236,39 @@ BOOL do_match(char *str, const char *regexp, int case_sig)
 * This is the new 'NT style' matcher.
 *********************************************************/
 
-BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
+BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2)
 {
        char *p;
        pstring t_pattern, t_filename, te_pattern, te_filename;
        fstring ebase, eext, sbase, sext;
 
        BOOL matched = False;
+       BOOL win9x_semantics = (get_remote_arch() == RA_WIN95) && trans2;
+
+       /* special case - if it is exactly the same then it always matches! */
+       if (exact_match(str, regexp, case_sig))
+               return True;
 
        /* Make local copies of str and regexp */
        pstrcpy(t_pattern, regexp);
        pstrcpy(t_filename, str);
 
+       if (trans2)
+       {
+
+               /* a special case for 16 bit apps */
+               if (strequal(t_pattern, "????????.???"))
+                       pstrcpy(t_pattern, "*");
+
+#if 0
+               /*
+                * Handle broken clients that send us old 8.3 format.
+                */
+               pstring_sub(t_pattern, "????????", "*");
+               pstring_sub(t_pattern, ".???", ".*");
+#endif
+       }
+
 #if 0
        /* 
         * Not sure if this is a good idea. JRA.
@@ -1065,8 +1285,9 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
 #endif
 
        /* Remove any *? and ** as they are meaningless */
-       string_sub(t_pattern, "*?", "*");
-       string_sub(t_pattern, "**", "*");
+       for (p = t_pattern; *p; p++)
+               while (*p == '*' && (p[1] == '?' || p[1] == '*'))
+                       (void)pstrcpy(&p[1], &p[2]);
 
        if (strequal(t_pattern, "*"))
                return (True);
@@ -1090,7 +1311,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                /*
                 * Remove multiple "*." patterns.
                 */
-               string_sub(te_pattern, "*.*.", "*.");
+               pstring_sub(te_pattern, "*.*.", "*.");
                num_regexp_components = count_chars(te_pattern, '.');
                num_path_components = count_chars(te_filename, '.');
 
@@ -1098,7 +1319,9 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
                 */
                if (num_regexp_components == 0)
-                       matched = do_match(te_filename, te_pattern, case_sig);
+                       matched =
+                               do_match(te_filename, te_pattern, case_sig,
+                                        win9x_semantics);
                else
                {
                        for (cp1 = te_pattern, cp2 = te_filename; cp1;)
@@ -1110,14 +1333,27 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                                if (rp)
                                        *rp = '\0';
 
-                               if (cp1[strlen(cp1) - 1] == '*')
+                               if (cp1[0] && cp1[strlen(cp1) - 1] == '*')
                                        last_wcard_was_star = True;
                                else
                                        last_wcard_was_star = False;
 
-                               if (!do_match(cp2, cp1, case_sig))
+                               if (!do_match
+                                   (cp2, cp1, case_sig, win9x_semantics))
                                        break;
 
+                               /*
+                                * Ugly ! Special case for Win9x *only*. If filename is XXXX and pattern extension
+                                * is '*' or all '?' then disallow match.
+                                */
+
+                               if (win9x_semantics)
+                               {
+                                       if (*cp2 == '\0'
+                                           && str_is_all(cp1, '?'))
+                                               break;
+                               }
+
                                cp1 = rp ? rp + 1 : NULL;
                                cp2 = fp ? fp + 1 : "";
 
@@ -1138,7 +1374,8 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
 
                                                if ((cp1 != NULL)
                                                    && do_match(cp2, cp1,
-                                                               case_sig))
+                                                               case_sig,
+                                                               win9x_semantics))
                                                {
                                                        cp2 =
                                                                fp ? fp +
@@ -1166,11 +1403,12 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                if (strequal(t_filename, "."))
                {
                        /*
-                        *  Patterns:  *.*  *. ?. ?  are valid
+                        *  Patterns:  *.*  *. ?. ? ????????.??? are valid.
                         *
                         */
                        if (strequal(t_pattern, "*.*")
                            || strequal(t_pattern, "*.")
+                           || strequal(t_pattern, "????????.???")
                            || strequal(t_pattern, "?.")
                            || strequal(t_pattern, "?"))
                                matched = True;
@@ -1178,13 +1416,14 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                else if (strequal(t_filename, ".."))
                {
                        /*
-                        *  Patterns:  *.*  *. ?. ? *.? are valid
+                        *  Patterns:  *.*  *. ?. ? *.? ????????.??? are valid.
                         *
                         */
                        if (strequal(t_pattern, "*.*")
                            || strequal(t_pattern, "*.")
                            || strequal(t_pattern, "?.")
                            || strequal(t_pattern, "?")
+                           || strequal(t_pattern, "????????.???")
                            || strequal(t_pattern, "*.?")
                            || strequal(t_pattern, "?.*"))
                                matched = True;
@@ -1242,17 +1481,17 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                                {
                                        matched =
                                                do_match(sbase, ebase,
-                                                        case_sig)
+                                                        case_sig, False)
                                                && do_match(sext, eext,
-                                                           case_sig);
+                                                           case_sig, False);
                                }
                                else
                                {
                                        /* pattern has no extension */
                                        /* Really: match complete filename with pattern ??? means exactly 3 chars */
                                        matched =
-                                               do_match(str, ebase,
-                                                        case_sig);
+                                               do_match(str, ebase, case_sig,
+                                                        False);
                                }
                        }
                        else
@@ -1267,15 +1506,16 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                                        /* pattern has extension */
                                        matched =
                                                do_match(sbase, ebase,
-                                                        case_sig)
+                                                        case_sig, False)
                                                && do_match(sext, eext,
-                                                           case_sig);
+                                                           case_sig, False);
+
                                }
                                else
                                {
                                        matched =
                                                do_match(sbase, ebase,
-                                                        case_sig);
+                                                        case_sig, False);
 #ifdef EMULATE_WEIRD_W95_MATCHING
                                        /*
                                         * Even Microsoft has some problems
@@ -1289,7 +1529,8 @@ BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
                                                fstrcat(sbase, ".");
                                                matched =
                                                        do_match(sbase, ebase,
-                                                                case_sig);
+                                                                case_sig,
+                                                                False);
                                        }
 #endif
                                }
@@ -1411,6 +1652,25 @@ this is a version of setbuffer() for those machines that only have setvbuf
 #endif
 
 
+/****************************************************************************
+ copies or initialises to zeros.  checks NULL pointers, basically.
+ returns True on an actual memcpy.
+ ****************************************************************************/
+BOOL Memcpy(void *to, const void *from, size_t size)
+{
+       if (to == NULL)
+       {
+               return False;
+       }
+       if (from == NULL)
+       {
+               memset(to, 0, size);
+               return False;
+       }
+
+       memcpy(to, from, size);
+       return True;
+}
 
 /****************************************************************************
 expand a pointer to be a particular size
@@ -1432,17 +1692,10 @@ void *Realloc(void *p, size_t size)
        else
                ret = (void *)realloc(p, size);
 
-#ifdef MEM_MAN
-       {
-               extern FILE *dbf;
-               smb_mem_write_info(ret, dbf);
-       }
-#endif
-
        if (!ret)
                DEBUG(0,
                      ("Memory allocation error: failed to expand to %d bytes\n",
-                      size));
+                      (int)size));
 
        return (ret);
 }
@@ -1500,19 +1753,6 @@ BOOL get_myname(char *my_name, struct in_addr *ip)
        return (True);
 }
 
-
-/****************************************************************************
-true if two IP addresses are equal
-****************************************************************************/
-BOOL ip_equal(struct in_addr ip1, struct in_addr ip2)
-{
-       uint32 a1, a2;
-       a1 = ntohl(ip1.s_addr);
-       a2 = ntohl(ip2.s_addr);
-       return (a1 == a2);
-}
-
-
 /****************************************************************************
 interpret a protocol description string, with a default
 ****************************************************************************/
@@ -1580,7 +1820,7 @@ uint32 interpret_addr(char *str)
                putip((char *)&res, (char *)hp->h_addr);
        }
 
-       if (res == (uint32) - 1)
+       if (res == (uint32)-1)
                return (0);
 
        return (res);
@@ -1731,23 +1971,22 @@ static char *automount_lookup(char *user_name)
                                if (object->zo_data.zo_type == ENTRY_OBJ)
                                {
                                        entry =
-                                               &object->zo_data.
-                                               objdata_u.en_data;
+                                               &object->zo_data.objdata_u.
+                                               en_data;
                                        DEBUG(5,
                                              ("NIS+ entry type: %s\n",
                                               entry->en_type));
                                        DEBUG(3,
                                              ("NIS+ result: %s\n",
-                                              entry->en_cols.
-                                              en_cols_val[1].ec_value.
-                                              ec_value_val));
+                                              entry->en_cols.en_cols_val[1].
+                                              ec_value.ec_value_val));
 
                                        pstrcpy(last_value,
                                                entry->en_cols.
                                                en_cols_val[1].ec_value.
                                                ec_value_val);
-                                       string_sub(last_value, "&",
-                                                  user_name);
+                                       pstring_sub(last_value, "&",
+                                                   user_name);
                                        fstrcpy(last_key, user_name);
                                }
                        }
@@ -1901,38 +2140,40 @@ void standard_sub_basic(char *str)
                switch (*(p + 1))
                {
                        case 'I':
-                               string_sub(p, "%I", client_connection_addr());
+                               pstring_sub(p, "%I",
+                                           client_connection_addr());
                                break;
                        case 'L':
-                               string_sub(p, "%L", local_machine);
+                               pstring_sub(p, "%L", local_machine);
                                break;
                        case 'M':
-                               string_sub(p, "%M", client_connection_name());
+                               pstring_sub(p, "%M",
+                                           client_connection_name());
                                break;
                        case 'R':
-                               string_sub(p, "%R", remote_proto);
+                               pstring_sub(p, "%R", remote_proto);
                                break;
                        case 'T':
-                               string_sub(p, "%T", timestring(False));
+                               pstring_sub(p, "%T", timestring(False));
                                break;
                        case 'a':
-                               string_sub(p, "%a", remote_arch);
+                               pstring_sub(p, "%a", remote_arch);
                                break;
                        case 'd':
                        {
                                slprintf(pidstr, sizeof(pidstr) - 1, "%d",
                                         (int)getpid());
-                               string_sub(p, "%d", pidstr);
+                               pstring_sub(p, "%d", pidstr);
                                break;
                        }
                        case 'h':
-                               string_sub(p, "%h", myhostname());
+                               pstring_sub(p, "%h", myhostname());
                                break;
                        case 'm':
-                               string_sub(p, "%m", remote_machine);
+                               pstring_sub(p, "%m", remote_machine);
                                break;
                        case 'v':
-                               string_sub(p, "%v", VERSION);
+                               pstring_sub(p, "%v", VERSION);
                                break;
                        case '$':       /* Expand environment variables */
                        {
@@ -1976,7 +2217,7 @@ void standard_sub_basic(char *str)
                                            (sizeof(envname) - 1));
                                strncpy(envname, p, copylen);
                                envname[copylen] = '\0';
-                               string_sub(p, envname, envval);
+                               pstring_sub(p, envname, envval);
                                break;
                        }
                        case '\0':
@@ -2007,8 +2248,8 @@ void standard_sub_vuser(const user_struct * vuser, char *str)
                                if ((pass = Get_Pwnam(vuser->name, False)) !=
                                    NULL)
                                {
-                                       string_sub(p, "%G",
-                                                  gidtoname(pass->pw_gid));
+                                       pstring_sub(p, "%G",
+                                                   gidtoname(pass->pw_gid));
                                }
                                else
                                {
@@ -2017,11 +2258,11 @@ void standard_sub_vuser(const user_struct * vuser, char *str)
                                break;
                        }
                        case 'N':
-                               string_sub(p, "%N",
-                                          automount_server(vuser->name));
+                               pstring_sub(p, "%N",
+                                           automount_server(vuser->name));
                                break;
                        case 'U':
-                               string_sub(p, "%U", vuser->requested_name);
+                               pstring_sub(p, "%U", vuser->requested_name);
                                break;
                        case '\0':
                                p++;
@@ -2051,7 +2292,7 @@ void standard_sub(connection_struct * conn, user_struct * vuser, char *str)
                                if ((home = get_unixhome_dir(conn->user)) !=
                                    NULL)
                                {
-                                       string_sub(p, "%H", home);
+                                       pstring_sub(p, "%H", home);
                                }
                                else
                                {
@@ -2067,21 +2308,22 @@ void standard_sub(connection_struct * conn, user_struct * vuser, char *str)
                                 * "path =" string in [homes] and so needs the
                                 * service name, not the username.  */
                        case 'p':
-                               string_sub(p, "%p",
-                                          automount_path(lp_servicename
-                                                         (SNUM(conn))));
+                               pstring_sub(p, "%p",
+                                           automount_path(lp_servicename
+                                                          (SNUM(conn))));
                                break;
                        case 'P':
-                               string_sub(p, "%P", conn->connectpath);
+                               pstring_sub(p, "%P", conn->connectpath);
                                break;
                        case 'S':
-                               string_sub(p, "%S",
-                                          lp_servicename(SNUM(conn))); break;
+                               pstring_sub(p, "%S",
+                                           lp_servicename(SNUM(conn)));
+                                       break;
                        case 'g':
-                               string_sub(p, "%g", gidtoname(conn->gid));
+                               pstring_sub(p, "%g", gidtoname(conn->gid));
                                break;
                        case 'u':
-                               string_sub(p, "%u", conn->user);
+                               pstring_sub(p, "%u", conn->user);
                                break;
 
                        case '\0':
@@ -2393,13 +2635,13 @@ a readdir wrapper which just returns the file name
 ********************************************************************/
 char *readdirname(DIR * p)
 {
-       struct dirent *ptr;
+       SMB_STRUCT_DIRENT *ptr;
        char *dname;
 
        if (!p)
                return (NULL);
 
-       ptr = (struct dirent *)readdir(p);
+       ptr = (SMB_STRUCT_DIRENT *) sys_readdir(p);
        if (!ptr)
                return (NULL);
 
@@ -2458,8 +2700,8 @@ BOOL is_in_path(char *name, name_compare_entry * namelist)
                         * 'unix style' mask match, rather than the
                         * new NT one.
                         */
-                       if (unix_mask_match(last_component, namelist->name,
-                                           case_sensitive, False))
+                       if (unix_mask_match
+                           (last_component, namelist->name, case_sensitive))
                        {
                                DEBUG(8,
                                      ("is_in_path: mask match succeeded\n"));
@@ -2667,7 +2909,7 @@ char *align4(char *q, char *base)
        int mod = PTR_DIFF(q, base) & 3;
        if (mod != 0)
        {
-               q += 4-mod;
+               q += 4 - mod;
        }
        return q;
 }
@@ -2897,16 +3139,56 @@ int set_maxfiles(int requested_max)
 {
 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
        struct rlimit rlp;
-       getrlimit(RLIMIT_NOFILE, &rlp);
-       /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
-        * account for the extra fd we need 
-        * as well as the log files and standard
-        * handles etc.  */
-       rlp.rlim_cur = MIN(requested_max, rlp.rlim_max);
-       setrlimit(RLIMIT_NOFILE, &rlp);
-       getrlimit(RLIMIT_NOFILE, &rlp);
+       int saved_current_limit;
+
+       if (getrlimit(RLIMIT_NOFILE, &rlp))
+       {
+               DEBUG(0,
+                     ("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
+                      strerror(errno)));
+               /* just guess... */
+               return requested_max;
+       }
+
+       /* 
+          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
+          * account for the extra fd we need 
+          * as well as the log files and standard
+          * handles etc. Save the limit we want to set in case
+          * we are running on an OS that doesn't support this limit (AIX)
+          * which always returns RLIM_INFINITY for rlp.rlim_max.
+        */
+
+       saved_current_limit = rlp.rlim_cur = MIN(requested_max, rlp.rlim_max);
+
+       if (setrlimit(RLIMIT_NOFILE, &rlp))
+       {
+               DEBUG(0,
+                     ("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
+                      (int)rlp.rlim_cur, strerror(errno)));
+               /* just guess... */
+               return saved_current_limit;
+       }
+
+       if (getrlimit(RLIMIT_NOFILE, &rlp))
+       {
+               DEBUG(0,
+                     ("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
+                      strerror(errno)));
+               /* just guess... */
+               return saved_current_limit;
+       }
+
+#if defined(RLIM_INFINITY)
+       if (rlp.rlim_cur == RLIM_INFINITY)
+               return saved_current_limit;
+#endif
+
+       if ((int)rlp.rlim_cur > saved_current_limit)
+               return saved_current_limit;
+
        return rlp.rlim_cur;
-#else
+#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
        /*
         * No way to know - just guess...
         */
@@ -2926,8 +3208,7 @@ void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
 /*****************************************************************
  splits out the start of the key (HKLM or HKU) and the rest of the key
  *****************************************************************/
-BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
-                  char *key_name)
+BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
 {
        pstring tmp;
 
@@ -3304,7 +3585,7 @@ time_t pwdb_get_last_set_time(const char *p)
  ********************************************************************/
 static void set_time_in_string(char *p, int max_len, char *type, time_t t)
 {
-       slprintf(p, max_len, ":%s-%08X", type, (uint32) t);
+       slprintf(p, max_len, ":%s-%08X", type, (uint32)t);
 }
 
 /*******************************************************************
@@ -3396,7 +3677,7 @@ void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl)
  Routine to get the 32 hex characters and turn them
  into a 16 byte array.
 **************************************************************/
-BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl)
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl)
 {
        if (strnequal(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32))
        {
@@ -3418,6 +3699,38 @@ BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl)
        }
 }
 
+/*****************************************************************
+like mktemp() but make sure that no % characters are used
+% characters are bad for us because of the macro subs
+ *****************************************************************/
+char *smbd_mktemp(char *template)
+{
+       char *p = mktemp(template);
+       char *p2;
+       SMB_STRUCT_STAT st;
+
+       if (!p)
+               return NULL;
+
+       while ((p2 = strchr(p, '%')))
+       {
+               p2[0] = 'A';
+               while (sys_stat(p, &st) == 0 && p2[0] < 'Z')
+               {
+                       /* damn, it exists */
+                       p2[0]++;
+               }
+               if (p2[0] == 'Z')
+               {
+                       /* oh well ... better return something */
+                       p2[0] = '%';
+                       return p;
+               }
+       }
+
+       return p;
+}
+
 /*****************************************************************
 like strdup but for memory
  *****************************************************************/
@@ -3437,11 +3750,12 @@ void *memdup(const void *p, size_t size)
 
 /*****************************************************************
 get local hostname and cache result
- *****************************************************************/  
+ *****************************************************************/
 char *myhostname(void)
 {
        static pstring ret;
-       if (ret[0] == 0) {
+       if (ret[0] == 0)
+       {
                get_myname(ret, NULL);
        }
        return ret;
@@ -3492,6 +3806,37 @@ char *lock_path(char *name)
        return fname;
 }
 
+/*******************************************************************
+ Given a filename - get its directory name
+ NB: Returned in static storage.  Caveats:
+ o  Not safe in thread environment.
+ o  Caller must not free.
+ o  If caller wishes to preserve, they should copy.
+********************************************************************/
+
+char *parent_dirname(const char *path)
+{
+       static pstring dirpath;
+       char *p;
+
+       if (!path)
+               return (NULL);
+
+       pstrcpy(dirpath, path);
+       p = strrchr(dirpath, '/');      /* Find final '/', if any */
+       if (!p)
+       {
+               pstrcpy(dirpath, ".");  /* No final "/", so dir is "." */
+       }
+       else
+       {
+               if (p == dirpath)
+                       ++p;    /* For root "/", leave "/" in place */
+               *p = '\0';
+       }
+       return dirpath;
+}
+
 struct field_info sid_name_info[] = {
        {SID_NAME_UNKNOWN, "UNKNOWN"},  /* default */
        {SID_NAME_USER, "User"},
@@ -3511,4 +3856,3 @@ const char *get_sid_name_use_str(uint32 sid_name_use)
 {
        return enum_field_to_str(sid_name_use, sid_name_info, True);
 }
-
index 44b37466c718c983cb8af5a9640c32de24a023c3..b6bd73f04544a93a728342f8b36aebba7037c3a7 100644 (file)
@@ -111,114 +111,176 @@ BOOL file_unlock(int fd, int *plock_depth)
 /****************************************************************************
 routine to do file locking
 ****************************************************************************/
+
 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
 #if HAVE_FCNTL_LOCK
-  SMB_STRUCT_FLOCK lock;
-  int ret;
-
-  if(lp_ole_locking_compat()) {
-    SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
-    SMB_OFF_T mask = (mask2<<2);
-
-    /* make sure the count is reasonable, we might kill the lockd otherwise */
-    count &= ~mask;
-
-    /* the offset is often strange - remove 2 of its bits if either of
-       the top two bits are set. Shift the top ones by two bits. This
-       still allows OLE2 apps to operate, but should stop lockd from
-       dieing */
-    if ((offset & mask) != 0)
-      offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
-  } else {
-    SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
-    SMB_OFF_T mask = (mask2<<1);
-    SMB_OFF_T neg_mask = ~mask;
-
-    /* interpret negative counts as large numbers */
-    if (count < 0)
-      count &= ~mask;
-
-    /* no negative offsets */
-    if(offset < 0)
-      offset &= ~mask;
-
-    /* count + offset must be in range */
-    while ((offset < 0 || (offset + count < 0)) && mask)
-    {
-      offset &= ~mask;
-      mask = ((mask >> 1) & neg_mask);
-    }
-  }
+       SMB_STRUCT_FLOCK lock;
+       int ret;
+#if defined(LARGE_SMB_OFF_T)
+       /*
+        * In the 64 bit locking case we store the original
+        * values in case we have to map to a 32 bit lock on
+        * a filesystem that doesn't support 64 bit locks.
+        */
+       SMB_OFF_T orig_offset = offset;
+       SMB_OFF_T orig_count = count;
+#endif /* LARGE_SMB_OFF_T */
 
-  DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+       if (lp_ole_locking_compat())
+       {
+               SMB_OFF_T mask2 = ((SMB_OFF_T) 0x3) << (SMB_OFF_T_BITS - 4);
+               SMB_OFF_T mask = (mask2 << 2);
+
+               /* make sure the count is reasonable, we might kill the lockd otherwise */
+               count &= ~mask;
+
+               /* the offset is often strange - remove 2 of its bits if either of
+                  the top two bits are set. Shift the top ones by two bits. This
+                  still allows OLE2 apps to operate, but should stop lockd from
+                  dieing */
+               if ((offset & mask) != 0)
+                       offset =
+                               (offset & ~mask) | (((offset & mask) >> 2) &
+                                                   mask2);
+       }
+       else
+       {
+               SMB_OFF_T mask2 = ((SMB_OFF_T) 0x4) << (SMB_OFF_T_BITS - 4);
+               SMB_OFF_T mask = (mask2 << 1);
+               SMB_OFF_T neg_mask = ~mask;
 
-  lock.l_type = type;
-  lock.l_whence = SEEK_SET;
-  lock.l_start = offset;
-  lock.l_len = count;
-  lock.l_pid = 0;
+               /* interpret negative counts as large numbers */
+               if (count < 0)
+                       count &= ~mask;
 
-  errno = 0;
+               /* no negative offsets */
+               if (offset < 0)
+                       offset &= ~mask;
 
-  ret = fcntl(fd,op,&lock);
-  if (errno == EFBIG)
-  {
-    if( DEBUGLVL( 0 ))
-    {
-      dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
-      dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
-      dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
-    }
-    /* 32 bit NFS file system, retry with smaller offset */
-    errno = 0;
-    lock.l_len = count & 0xffffffff;
-    ret = fcntl(fd,op,&lock);
-  }
+               /* count + offset must be in range */
+               while ((offset < 0 || (offset + count < 0)) && mask)
+               {
+                       offset &= ~mask;
+                       mask = ((mask >> 1) & neg_mask);
+               }
+       }
 
-  if (errno != 0)
-    DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
+       DEBUG(8,
+             ("fcntl_lock %d %d %.0f %.0f %d\n", fd, op, (double)offset,
+              (double)count, type));
 
-  /* a lock query */
-  if (op == SMB_F_GETLK)
-  {
-    if ((ret != -1) &&
-        (lock.l_type != F_UNLCK) && 
-        (lock.l_pid != 0) && 
-        (lock.l_pid != getpid()))
-    {
-      DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
-      return(True);
-    }
+       lock.l_type = type;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = offset;
+       lock.l_len = count;
+       lock.l_pid = 0;
 
-    /* it must be not locked or locked by me */
-    return(False);
-  }
+       errno = 0;
 
-  /* a lock set or unset */
-  if (ret == -1)
-  {
-    DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
-          (double)offset,(double)count,op,type,strerror(errno)));
+       ret = fcntl(fd, op, &lock);
+       if (errno == EFBIG)
+       {
+               if (DEBUGLVL(0))
+               {
+                       dbgtext
+                               ("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
+                                (double)offset, (double)count);
+                       dbgtext
+                               ("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
+                       dbgtext
+                               ("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
+               }
+               /* 32 bit NFS file system, retry with smaller offset */
+               errno = 0;
+               lock.l_len = count & 0x7fffffff;
+               ret = fcntl(fd, op, &lock);
+       }
 
-    /* perhaps it doesn't support this sort of locking?? */
-    if (errno == EINVAL)
-    {
-      DEBUG(3,("locking not supported? returning True\n"));
-      return(True);
-    }
+       if (errno != 0)
+               DEBUG(3,
+                     ("fcntl lock gave errno %d (%s)\n", errno,
+                      strerror(errno)));
 
-    return(False);
-  }
+       /* a lock query */
+       if (op == SMB_F_GETLK)
+       {
+               if ((ret != -1) &&
+                   (lock.l_type != F_UNLCK) &&
+                   (lock.l_pid != 0) && (lock.l_pid != getpid()))
+               {
+                       DEBUG(3,
+                             ("fd %d is locked by pid %d\n", fd,
+                              (int)lock.l_pid));
+                       return (True);
+               }
+
+               /* it must be not locked or locked by me */
+               return (False);
+       }
+
+       /* a lock set or unset */
+       if (ret == -1)
+       {
+               DEBUG(3,
+                     ("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+                      (double)offset, (double)count, op, type,
+                      strerror(errno)));
+
+               /* perhaps it doesn't support this sort of locking?? */
+               if (errno == EINVAL)
+               {
 
-  /* everything went OK */
-  DEBUG(8,("Lock call successful\n"));
+#if defined(LARGE_SMB_OFF_T)
+                       {
+                               /*
+                                * Ok - if we get here then we have a 64 bit lock request
+                                * that has returned EINVAL. Try and map to 31 bits for offset
+                                * and length and try again. This may happen if a filesystem
+                                * doesn't support 64 bit offsets (efs/ufs) although the underlying
+                                * OS does.
+                                */
+                               uint32 off_low = (orig_offset & 0xFFFFFFFF);
+                               uint32 off_high =
+                                       ((orig_offset >> 32) & 0xFFFFFFFF);
+
+                               lock.l_len = (orig_count & 0x7FFFFFFF);
+                               lock.l_start =
+                                       (SMB_OFF_T) map_lock_offset(off_high,
+                                                                   off_low);
+                               ret = fcntl(fd, op, &lock);
+                               if (ret == -1)
+                               {
+                                       if (errno == EINVAL)
+                                       {
+                                               DEBUG(3,
+                                                     ("locking not supported? returning True\n"));
+                                               return (True);
+                                       }
+                                       return False;
+                               }
+                               DEBUG(3,
+                                     ("64 -> 32 bit modified lock call successful\n"));
+                               return True;
+                       }
+#else /* LARGE_SMB_OFF_T */
+                       DEBUG(3, ("locking not supported? returning True\n"));
+                       return (True);
+#endif /* LARGE_SMB_OFF_T */
+               }
 
-  return(True);
+               return (False);
+       }
+
+       /* everything went OK */
+       DEBUG(8, ("Lock call successful\n"));
+
+       return (True);
 #else
-  return(False);
+       return (False);
 #endif
 }
+
 /***************************************************************
  locks a file for enumeration / modification.
  update to be set = True if modification is required.
@@ -477,3 +539,15 @@ void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodifi
        return (void *)f;
 }
 
+/*******************************************************************
+returns the size in bytes of the named file
+********************************************************************/
+SMB_OFF_T get_file_size(char *file_name)
+{
+       SMB_STRUCT_STAT buf;
+       buf.st_size = 0;
+       if (sys_stat(file_name, &buf) != 0)
+               return (SMB_OFF_T) - 1;
+       return (buf.st_size);
+}
+
index f7b0915c4d5734619af993926ed7c809317be3fb..f88d32598536c4fa10ddd4f46ec979dc10b5479d 100644 (file)
@@ -30,6 +30,8 @@ extern int DEBUGLEVEL;
 #endif
 #include <stdlib.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
 
 #ifdef HAVE_SYS_PRIV_H
 #include <sys/priv.h>
@@ -47,20 +49,14 @@ abort if we haven't set the uid correctly
 ****************************************************************************/
 static void assert_uid(uid_t ruid, uid_t euid)
 {
-#ifdef AUTOCONF_TEST
-#if (defined(USE_SETRESUID) || defined(USE_SETREUID) || \
-     defined(USE_SETEUID) || defined(USE_SETUIDX))
-       if ((euid != (uid_t) (-1) && geteuid() != euid) ||
-           (ruid != (uid_t) (-1) && getuid() != ruid))
-       {
-               DEBUG(0,
-                     ("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n",
-                      (int)ruid, (int)euid, (int)getuid(), (int)geteuid()));
+       if ((euid != (uid_t)-1 && geteuid() != euid) ||
+           (ruid != (uid_t)-1 && getuid() != ruid)) {
+               DEBUG(0,("Failed to set uid privileges to (%d,%d) now set to (%d,%d)\n",
+                        (int)ruid, (int)euid,
+                        (int)getuid(), (int)geteuid()));
                smb_panic("failed to set uid\n");
                exit(1);
        }
-#endif
-#endif
 }
 
 /****************************************************************************
@@ -68,21 +64,15 @@ abort if we haven't set the gid correctly
 ****************************************************************************/
 static void assert_gid(gid_t rgid, gid_t egid)
 {
-#ifdef AUTOCONF_TEST
-#if (defined(USE_SETRESGID) || defined(USE_SETREGID) || \
-     defined(USE_SETEGID) || defined(USE_SETGIDX))
-       if ((egid != (gid_t) (-1) && getegid() != egid) ||
-           (rgid != (gid_t) (-1) && getgid() != rgid))
-       {
-               DEBUG(0,
-                     ("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n",
-                      (int)rgid, (int)egid, (int)getgid(), (int)getegid(),
-                      (int)getuid(), (int)geteuid()));
+       if ((egid != (gid_t)-1 && getegid() != egid) ||
+           (rgid != (gid_t)-1 && getgid() != rgid)) {
+               DEBUG(0,("Failed to set gid privileges to (%d,%d) now set to (%d,%d) uid=(%d,%d)\n",
+                        (int)rgid, (int)egid,
+                        (int)getgid(), (int)getegid(),
+                        (int)getuid(), (int)geteuid()));
                smb_panic("failed to set gid\n");
                exit(1);
        }
-#endif
-#endif
 }
 
 /****************************************************************************
@@ -90,20 +80,20 @@ static void assert_gid(gid_t rgid, gid_t egid)
  We want to end up with ruid==euid==0
 ****************************************************************************/
 void gain_root_privilege(void)
-{
-#ifdef USE_SETRESUID
-       setresuid(0, 0, 0);
+{      
+#if USE_SETRESUID
+       setresuid(0,0,0);
 #endif
-
-#ifdef USE_SETEUID
+    
+#if USE_SETEUID
        seteuid(0);
 #endif
 
-#ifdef USE_SETREUID
+#if USE_SETREUID
        setreuid(0, 0);
 #endif
 
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
        setuidx(ID_EFFECTIVE, 0);
        setuidx(ID_REAL, 0);
 #endif
@@ -121,19 +111,19 @@ void gain_root_privilege(void)
 ****************************************************************************/
 void gain_root_group_privilege(void)
 {
-#ifdef USE_SETRESGID
-       setresgid(0, 0, 0);
+#if USE_SETRESUID
+       setresgid(0,0,0);
 #endif
 
-#ifdef USE_SETREGID
-       setregid(0, 0);
+#if USE_SETREUID
+       setregid(0,0);
 #endif
 
-#ifdef USE_SETEGID
+#if USE_SETEUID
        setegid(0);
 #endif
 
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
        setgidx(ID_EFFECTIVE, 0);
        setgidx(ID_REAL, 0);
 #endif
@@ -150,19 +140,19 @@ void gain_root_group_privilege(void)
 ****************************************************************************/
 void set_effective_uid(uid_t uid)
 {
-#ifdef USE_SETRESUID
-       setresuid(-1, uid, -1);
+#if USE_SETRESUID
+       setresuid(-1,uid,-1);
 #endif
 
-#ifdef USE_SETREUID
-       setreuid(-1, uid);
+#if USE_SETREUID
+       setreuid(-1,uid);
 #endif
 
-#ifdef USE_SETEUID
+#if USE_SETEUID
        seteuid(uid);
 #endif
 
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
        setuidx(ID_EFFECTIVE, uid);
 #endif
 
@@ -175,19 +165,19 @@ void set_effective_uid(uid_t uid)
 ****************************************************************************/
 void set_effective_gid(gid_t gid)
 {
-#ifdef USE_SETRESGID
-       setresgid(-1, gid, -1);
+#if USE_SETRESUID
+       setresgid(-1,gid,-1);
 #endif
 
-#ifdef USE_SETREGID
-       setregid(-1, gid);
+#if USE_SETREUID
+       setregid(-1,gid);
 #endif
 
-#ifdef USE_SETEGID
+#if USE_SETEUID
        setegid(gid);
 #endif
 
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
        setgidx(ID_EFFECTIVE, gid);
 #endif
 
@@ -213,10 +203,21 @@ void save_re_uid(void)
 void restore_re_uid(void)
 {
        set_effective_uid(0);
+
+#if USE_SETRESUID
+       setresuid(saved_ruid, saved_euid, -1);
+#elif USE_SETREUID
+       setreuid(saved_ruid, -1);
+       setreuid(-1,saved_euid);
+#elif USE_SETUIDX
+       setuidx(ID_REAL, saved_ruid);
+       setuidx(ID_EFFECTIVE, saved_euid);
+#else
        set_effective_uid(saved_euid);
        if (getuid() != saved_ruid)
                setuid(saved_ruid);
        set_effective_uid(saved_euid);
+#endif
 
        assert_uid(saved_ruid, saved_euid);
 }
@@ -230,22 +231,22 @@ int set_re_uid(void)
 {
        uid_t uid = geteuid();
 
-#ifdef USE_SETRESUID
+#if USE_SETRESUID
        setresuid(geteuid(), -1, -1);
 #endif
 
-#ifdef USE_SETREUID
+#if USE_SETREUID
        setreuid(0, 0);
        setreuid(uid, -1);
        setreuid(-1, uid);
 #endif
 
-#ifdef USE_SETEUID
+#if USE_SETEUID
        /* can't be done */
        return -1;
 #endif
 
-#ifdef USE_SETUIDX
+#if USE_SETUIDX
        /* can't be done */
        return -1;
 #endif
@@ -269,95 +270,100 @@ void become_user_permanently(uid_t uid, gid_t gid)
        gain_root_privilege();
        gain_root_group_privilege();
 
-#ifdef USE_SETRESGID
-       setresgid(gid, gid, gid);
+#if USE_SETRESUID
+       setresgid(gid,gid,gid);
        setgid(gid);
+       setresuid(uid,uid,uid);
+       setuid(uid);
 #endif
 
-#ifdef USE_SETREGID
-       setregid(gid, gid);
+#if USE_SETREUID
+       setregid(gid,gid);
        setgid(gid);
+       setreuid(uid,uid);
+       setuid(uid);
 #endif
 
-#ifdef USE_SETEGID
+#if USE_SETEUID
        setegid(gid);
        setgid(gid);
+       setuid(uid);
+       seteuid(uid);
+       setuid(uid);
 #endif
 
-#ifdef USE_SETGIDX
+#if USE_SETUIDX
        setgidx(ID_REAL, gid);
        setgidx(ID_EFFECTIVE, gid);
        setgid(gid);
+       setuidx(ID_REAL, uid);
+       setuidx(ID_EFFECTIVE, uid);
+       setuid(uid);
 #endif
+       
+       assert_uid(uid, uid);
+       assert_gid(gid, gid);
+}
 
-#ifdef USE_SETRESUID
-       setresuid(uid, uid, uid);
-       setuid(uid);
+
+#ifdef AUTOCONF_TEST
+/****************************************************************************
+this function just checks that we don't get ENOSYS back
+****************************************************************************/
+static int have_syscall(void)
+{
+       errno = 0;
+
+#if USE_SETRESUID
+       setresuid(-1,-1,-1);
 #endif
 
-#ifdef USE_SETREUID
-       setreuid(uid, uid);
-       setuid(uid);
+#if USE_SETREUID
+       setreuid(-1,-1);
 #endif
 
-#ifdef USE_SETEUID
-       setuid(uid);
-       seteuid(uid);
-       setuid(uid);
+#if USE_SETEUID
+       seteuid(-1);
 #endif
 
-#ifdef USE_SETUIDX
-       setuidx(ID_REAL, uid);
-       setuidx(ID_EFFECTIVE, uid);
-       setuid(uid);
+#if USE_SETUIDX
+       setuidx(ID_EFFECTIVE, -1);
 #endif
 
-       assert_uid(uid, uid);
-       assert_gid(gid, gid);
+       if (errno == ENOSYS) return -1;
+       
+       return 0;
 }
 
-#ifdef AUTOCONF_TEST
 main()
 {
-       if (getuid() != 0)
-       {
+        if (getuid() != 0) {
 #if (defined(AIX) && defined(USE_SETREUID))
                /* setreuid is badly broken on AIX 4.1, we avoid it completely */
-               fprintf(stderr, "avoiding possibly broken setreuid\n");
+                fprintf(stderr,"avoiding possibly broken setreuid\n");
                exit(1);
 #endif
 
-               /* assume that if we have the functions then they work */
-               fprintf(stderr, "not running as root: assuming OK\n");
-               exit(0);
+               /* if not running as root then at least check to see if we get ENOSYS - this 
+                  handles Linux 2.0.x with glibc 2.1 */
+                fprintf(stderr,"not running as root: checking for ENOSYS\n");
+               exit(have_syscall());
        }
 
        gain_root_privilege();
        gain_root_group_privilege();
        set_effective_gid(1);
        set_effective_uid(1);
+       save_re_uid();
+       restore_re_uid();
        gain_root_privilege();
        gain_root_group_privilege();
        become_user_permanently(1, 1);
-#if (defined(USE_SETRESUID) || defined(USE_SETREUID) || \
-     defined(USE_SETEUID) || defined(USE_SETUIDX))
        setuid(0);
-       if (getuid() == 0)
-       {
-               fprintf(stderr, "uid not set permanently\n");
+       if (getuid() == 0) {
+               fprintf(stderr,"uid not set permanently\n");
                exit(1);
        }
-#endif
-
-#if (defined(USE_SETRESGID) || defined(USE_SETREGID) || \
-     defined(USE_SETEGID) || defined(USE_SETGIDX))
-       setgid(0);
-       if (getgid() == 0)
-       {
-               fprintf(stderr, "gid not set permanently\n");
-               exit(1);
-       }
-#endif
 
        printf("OK\n");
 
index c20cbf6700c346424c69f8357df408c39a399e1d..97505a0387e855c1877ea1b9dc35d3e8fc70d7de 100644 (file)
@@ -69,8 +69,7 @@ struct
        int option;
        int value;
        int opttype;
-}
-socket_options[] =
+} socket_options[] =
 {
        {
        "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}
@@ -183,10 +182,10 @@ void set_socket_options(int fd, char *options)
                                        int on = socket_options[i].value;
                                        ret =
                                                setsockopt(fd,
-                                                          socket_options[i].
-                                                          level,
-                                                          socket_options[i].
-                                                          option,
+                                                          socket_options
+                                                          [i].level,
+                                                          socket_options
+                                                          [i].option,
                                                           (char *)&on,
                                                           sizeof(int));
                                }
@@ -246,7 +245,7 @@ ssize_t read_udp_socket(int fd, char *buf, size_t len)
        int socklen;
 
        socklen = sizeof(sock);
-       memset((char *)&sock, 0,  socklen);
+       memset((char *)&sock, 0, socklen);
        ZERO_STRUCT(lastip);
        ret =
                (ssize_t) recvfrom(fd, buf, len, 0, (struct sockaddr *)&sock,
@@ -562,7 +561,7 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout)
 
        smb_read_error = 0;
 
-       memset(buffer, 0,  smb_size + 100);
+       memset(buffer, 0, smb_size + 100);
 
        len = read_smb_length_return_keepalive(fd, buffer, timeout);
        if (len < 0)
@@ -1009,9 +1008,8 @@ char *client_addr(int fd)
 
        if (getpeername(fd, &sa, &length) < 0)
        {
-               DEBUG(0,
-                     ("getpeername failed. Error was %s\n",
-                      strerror(errno)));
+               DEBUG(0, ("getpeername failed. Error was %s\n",
+                         strerror(errno)));
                return client_addr_buf;
        }
 
@@ -1045,7 +1043,7 @@ int open_pipe_sock(char *path)
 
        if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
        {
-               DEBUG(1, ("socket connect to %s failed: %s\n",
+               DEBUG(2, ("socket connect to %s failed: %s\n",
                          sa.sun_path, strerror(errno)));
                close(sock);
                return -1;
index 6f11bf085d25ca4cb7700192e56f67ccf6b39282..7140fac989f161cfd70a7e8647be5200228d5a5f 100644 (file)
@@ -343,7 +343,7 @@ void strlower(char *s)
     else
 #endif /* KANJI_WIN95_COMPATIBILITY */
     {
-      size_t skip = skip_multibyte_char( *s );
+      size_t skip = get_character_len( *s );
       if( skip != 0 )
         s += skip;
       else
@@ -396,7 +396,7 @@ void strupper(char *s)
     else
 #endif /* KANJI_WIN95_COMPATIBILITY */
     {
-      size_t skip = skip_multibyte_char( *s );
+      size_t skip = get_character_len( *s );
       if( skip != 0 )
         s += skip;
       else
@@ -440,9 +440,20 @@ BOOL strisnormal(char *s)
 void string_replace(char *s,char oldc,char newc)
 {
   size_t skip;
+
+  /*
+   * sbcs optimization.
+   */
+  if(!global_is_multibyte_codepage) {
+    while (*s) {
+      if (oldc == *s)
+        *s = newc;
+      s++;
+    }
+  } else {
   while (*s)
   {
-    skip = skip_multibyte_char( *s );
+      skip = get_character_len( *s );
     if( skip != 0 )
       s += skip;
     else
@@ -453,6 +464,7 @@ void string_replace(char *s,char oldc,char newc)
     }
   }
 }
+}
 
 
 /*******************************************************************
@@ -462,7 +474,7 @@ char *skip_string(char *buf,size_t n)
 {
   while (n--)
     buf += strlen(buf) + 1;
-  return buf;
+  return(buf);
 }
 
 /*******************************************************************
@@ -476,11 +488,18 @@ size_t str_charnum(const char *s)
 {
   size_t len = 0;
   
+  /*
+   * sbcs optimization.
+   */
+  if(!global_is_multibyte_codepage) {
+    return strlen(s);
+  } else {
   while (*s != '\0') {
-    int skip = skip_multibyte_char(*s);
+      int skip = get_character_len(*s);
     s += (skip ? skip : 1);
     len++;
   }
+  }
   return len;
 }
 
@@ -518,7 +537,7 @@ BOOL trim_string(char *s,const char *front,const char *back)
 
   if(back_len)
   {
-    if(!is_multibyte_codepage())
+    if(!global_is_multibyte_codepage)
     {
       s_len = strlen(s);
       while ((s_len >= back_len) && 
@@ -552,12 +571,21 @@ BOOL trim_string(char *s,const char *front,const char *back)
         size_t charcount = 0;
         char *mbp = s;
 
-        while(charcount < (mb_s_len - mb_back_len))
-        {
+        /*
+         * sbcs optimization.
+         */
+        if(!global_is_multibyte_codepage) {
+          while(charcount < (mb_s_len - mb_back_len)) {
+            mbp += 1;
+            charcount++;
+          }
+        } else {
+          while(charcount < (mb_s_len - mb_back_len)) {
           size_t skip = skip_multibyte_char(*mbp);
           mbp += (skip ? skip : 1);
           charcount++;
         }
+        }
 
         /*
          * mbp now points at mb_back_len multibyte
@@ -615,7 +643,7 @@ BOOL strhasupper(const char *s)
     else
 #endif /* KANJI_WIN95_COMPATIBILITY */
     {
-      size_t skip = skip_multibyte_char( *s );
+      size_t skip = get_character_len( *s );
       if( skip != 0 )
         s += skip;
       else {
@@ -670,7 +698,7 @@ BOOL strhaslower(const char *s)
     else
 #endif /* KANJI_WIN95_COMPATIBILITY */
     {
-      size_t skip = skip_multibyte_char( *s );
+      size_t skip = get_character_len( *s );
       if( skip != 0 )
         s += skip;
       else {
@@ -720,7 +748,7 @@ size_t count_chars(const char *s,char c)
   {
     while (*s) 
     {
-      size_t skip = skip_multibyte_char( *s );
+      size_t skip = get_character_len( *s );
       if( skip != 0 )
         s += skip;
       else {
@@ -733,7 +761,59 @@ size_t count_chars(const char *s,char c)
   return(count);
 }
 
+/*******************************************************************
+Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all(const char *s,char c)
+{
+  if(s == NULL)
+    return False;
+  if(!*s)
+    return False;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+  /*
+   * For completeness we should put in equivalent code for code pages
+   * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+   * doubt anyone wants Samba to behave differently from Win95 and WinNT
+   * here. They both treat full width ascii characters as case senstive
+   * filenames (ie. they don't do the work we do here).
+   * JRA.
+   */
 
+  if(lp_client_code_page() == KANJI_CODEPAGE)
+  {
+    /* Win95 treats full width ascii characters as case sensitive. */
+    while (*s)
+    {
+      if (is_shift_jis (*s))
+        s += 2;
+      else
+      {
+        if (*s != c)
+          return False;
+        s++;
+      }
+    }
+  }
+  else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+  {
+    while (*s)
+    {
+      size_t skip = get_character_len( *s );
+      if( skip != 0 )
+        s += skip;
+      else {
+        if (*s != c)
+          return False;
+        s++;
+      }
+    }
+  }
+  return True;
+}
 
 /*******************************************************************
 safe string copy into a known length string. maxlength does not
@@ -743,11 +823,6 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
 {
     size_t len;
 
-       if (maxlength == 0)
-       {
-               return dest;
-       }
-
     if (!dest) {
         DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
         return NULL;
@@ -762,7 +837,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
 
     if (len > maxlength) {
            DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
-                    len-maxlength, src));
+                    (int)(len-maxlength), src));
            len = maxlength;
     }
       
@@ -793,7 +868,7 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
 
     if (src_len + dest_len > maxlength) {
            DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
-                    src_len + dest_len - maxlength, src));
+                    (int)(src_len + dest_len - maxlength), src));
            src_len = maxlength - dest_len;
     }
       
@@ -802,27 +877,46 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
     return dest;
 }
 
-/****************************************************************************
-this is a safer strcpy(), meant to prevent core dumps when nasty things happen
-****************************************************************************/
-char *StrCpy(char *dest,const char *src)
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+********************************************************************/
+
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
 {
-  char *d = dest;
+       size_t len, i;
 
-  /* I don't want to get lazy with these ... */
-  SMB_ASSERT(dest && src);
+       if (!dest) {
+               DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+               return NULL;
+       }
 
-  if (!dest) return(NULL);
   if (!src) {
     *dest = 0;
-    return(dest);
+               return dest;
   }
-  while ((*d++ = *src++)) ;
-  return(dest);
+
+       len = strlen(src);
+       if (len >= maxlength)
+               len = maxlength - 1;
+
+       for(i = 0; i < len; i++) {
+               int val = (src[i] & 0xff);
+               if(isupper(val) ||islower(val) || isdigit(val))
+                       dest[i] = src[i];
+               else
+                       dest[i] = '_';
+       }
+
+       dest[i] = '\0';
+
+       return dest;
 }
 
 /****************************************************************************
-like strncpy but always null terminates. Make sure there is room!
+ Like strncpy but always null terminates. Make sure there is room!
+ The variable n should always be one less than the available size.
 ****************************************************************************/
 char *StrnCpy(char *dest,const char *src,size_t n)
 {
@@ -842,7 +936,7 @@ char *StrnCpy(char *dest,const char *src,size_t n)
 like strncpy but copies up to the character marker.  always null terminates.
 returns a pointer to the character marker in the source string (src).
 ****************************************************************************/
-char *strncpyn(char *dest, char *src,size_t n, char c)
+char *strncpyn(char *dest, const char *src,size_t n, char c)
 {
        char *p;
        size_t str_len;
@@ -940,7 +1034,7 @@ static char *null_string = NULL;
 /****************************************************************************
 set a string value, allocing the space for the string
 ****************************************************************************/
-BOOL string_init(char **dest,const char *src)
+static BOOL string_init(char **dest,const char *src)
 {
   size_t l;
   if (!src)     
@@ -1003,29 +1097,42 @@ enough room!
 This routine looks for pattern in s and replaces it with 
 insert. It may do multiple replacements.
 
-any of " ; ' or ` in the insert string are replaced with _
+any of " ; ' $ or ` in the insert string are replaced with _
+if len==0 then no length check is performed
 ****************************************************************************/
-void string_sub(char *s,const char *pattern,const char *insert)
+void string_sub(char *s,const char *pattern,const char *insert, size_t len)
 {
        char *p;
-       size_t ls,lp,li, i;
+       ssize_t ls,lp,li, i;
 
        if (!insert || !pattern || !s) return;
 
-       ls = strlen(s);
-       lp = strlen(pattern);
-       li = strlen(insert);
+       ls = (ssize_t)strlen(s);
+       lp = (ssize_t)strlen(pattern);
+       li = (ssize_t)strlen(insert);
 
        if (!*pattern) return;
        
        while (lp <= ls && (p = strstr(s,pattern))) {
-               memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
+               if (len && (ls + (li-lp) >= len)) {
+                       DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
+                                (int)(ls + (li-lp) - len),
+                                pattern, (int)len));
+                       break;
+               }
+               if (li != lp) {
+                       memmove(p+li,p+lp,strlen(p+lp)+1);
+               }
                for (i=0;i<li;i++) {
                        switch (insert[i]) {
                        case '`':
                        case '"':
                        case '\'':
                        case ';':
+                       case '$':
+                       case '%':
+                       case '\r':
+                       case '\n':
                                p[i] = '_';
                                break;
                        default:
@@ -1037,6 +1144,15 @@ void string_sub(char *s,const char *pattern,const char *insert)
        }
 }
 
+void fstring_sub(char *s,const char *pattern,const char *insert)
+{
+       string_sub(s, pattern, insert, sizeof(fstring));
+}
+
+void pstring_sub(char *s,const char *pattern,const char *insert)
+{
+       string_sub(s, pattern, insert, sizeof(pstring));
+}
 
 /****************************************************************************
 similar to string_sub() but allows for any character to be substituted. 
@@ -1210,6 +1326,20 @@ char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default)
        return NULL;
 }
 
+/****************************************************************************
+write an octal as a string
+****************************************************************************/
+char *octal_string(int i)
+{
+       static char ret[64];
+       if (i == -1) {
+               return "-1";
+       }
+       slprintf(ret, sizeof(ret), "0%o", i);
+       return ret;
+}
+
+
 /****************************************************************************
 truncate a string at a specified length
 ****************************************************************************/
index 41f220ace9852ec42306b2f06704642e5c3addce..d7aa6596065c35190aeabedb2c47a0f1c6aba0ea 100644 (file)
 
 extern int DEBUGLEVEL;
 
-/*******************************************************************
- Write a string in (little-endian) unicode format. src is in
- the current DOS codepage. len is the length in bytes of the
- string pointed to by dst.
-
- the return value is the length of the string *without* the trailing 
- two bytes of zero
-********************************************************************/
-
-int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
-{
-       char *end = ascii_to_unibuf(dst, src, len);
-       return PTR_DIFF(end, dst) - (null_terminate ? 0 : 2);
-}
-
 /*******************************************************************
  Put an ASCII string into a UNICODE buffer (little endian).
  ********************************************************************/
@@ -143,7 +128,6 @@ void unistr_to_ascii(char *dest, const uint16 *src, int len)
 /*******************************************************************
  Convert a UNISTR2 structure to an ASCII string
  ********************************************************************/
-
 char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
 {
        char *destend;
diff --git a/source/lib/util_wunistr.c b/source/lib/util_wunistr.c
new file mode 100644 (file)
index 0000000..0974bad
--- /dev/null
@@ -0,0 +1,1790 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   Samba utility functions
+   Copyright (C) Andrew Tridgell 1992-1998
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 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"
+
+extern int DEBUGLEVEL;
+
+ smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
+                                                               (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
+                                                               (smb_ucs2_t)'\r', 0 };
+/*
+ * The following are the codepage to ucs2 and vica versa maps.
+ * These are dynamically loaded from a unicode translation file.
+ */
+
+static smb_ucs2_t *doscp_to_ucs2;
+static uint16 *ucs2_to_doscp;
+
+static smb_ucs2_t *unixcp_to_ucs2;
+static uint16 *ucs2_to_unixcp;
+
+/*******************************************************************
+ Write a string in (little-endian) unicode format. src is in
+ the current DOS codepage. len is the length in bytes of the
+ string pointed to by dst.
+
+ if null_terminate is True then null terminate the packet (adds 2 bytes)
+
+ the return value is the length consumed by the string, including the
+ null termination if applied
+********************************************************************/
+
+int dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+{
+       int ret = 0;
+       while (*src && (len > 2)) {
+               size_t skip = get_character_len(*src);
+               smb_ucs2_t val = (*src & 0xff);
+
+               /*
+                * If this is a multibyte character (and all DOS/Windows
+                * codepages have at maximum 2 byte multibyte characters)
+                * then work out the index value for the unicode conversion.
+                */
+
+               if (skip == 2)
+                       val = ((val << 8) | (src[1] & 0xff));
+
+               SSVAL(dst,ret,doscp_to_ucs2[val]);
+               ret += 2;
+               len -= 2;
+               if (skip)
+                       src += skip;
+               else
+                       src++;
+       }
+       if (null_terminate) {
+               SSVAL(dst,ret,0);
+               ret += 2;
+       }
+       return(ret);
+}
+
+#ifndef MAXUNI
+#define MAXUNI 1024
+#endif
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ len is the filename length (ignoring any terminating zero) in uin16
+ units. Always null terminates.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistrn2(uint16 *src, int len)
+{
+       static char lbufs[8][MAXUNI];
+       static int nexti;
+       char *lbuf = lbufs[nexti];
+       char *p;
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
+               uint16 ucs2_val = SVAL(src,0);
+               uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+static char lbufs[8][MAXUNI];
+static int nexti;
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr2(uint16 *src)
+{
+       char *lbuf = lbufs[nexti];
+       char *p;
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
+               uint16 ucs2_val = SVAL(src,0);
+               uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+/*******************************************************************
+Return a DOS codepage version of a little-endian unicode string
+********************************************************************/
+
+char *dos_unistr2_to_str(UNISTR2 *str)
+{
+       char *lbuf = lbufs[nexti];
+       char *p;
+       uint16 *src = str->buffer;
+       int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; *src && p-lbuf < max_size; src++) {
+               uint16 ucs2_val = SVAL(src,0);
+               uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+/*******************************************************************
+ Convert a UNISTR2 structure to an ASCII string
+ Warning: this version does DOS codepage.
+********************************************************************/
+#if 0
+ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
+{
+       char *destend;
+       const uint16 *src;
+       size_t len;
+       register uint16 c;
+
+       src = str->buffer;
+       len = MIN(str->uni_str_len, maxlen);
+       destend = dest + len;
+
+       while (dest < destend)
+       {
+               uint16 ucs2_val;
+               uint16 cp_val;
+
+               c = *src;
+               if (c == 0)
+               {
+                       break;
+               }
+               
+               ucs2_val = SVAL(src++,0);
+               cp_val = ucs2_to_doscp[ucs2_val];
+                               
+               if (cp_val < 256)
+                       *(dest++) = (char)cp_val;
+               else {
+                       *dest= (cp_val >> 8) & 0xff;
+                       *(dest++) = (cp_val & 0xff);
+               }
+       }
+
+       *dest = 0;
+}
+#endif
+/*******************************************************************
+Return a DOS codepage version of a NOTunicode string
+********************************************************************/
+
+char *dos_buffer2_to_str(BUFFER2 *str)
+{
+       char *lbuf = lbufs[nexti];
+       char *p;
+       uint16 *src = str->buffer;
+       int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; *src && p-lbuf < max_size; src++) {
+               uint16 ucs2_val = SVAL(src,0);
+               uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+/*******************************************************************
+ Return a dos codepage version of a NOTunicode string
+********************************************************************/
+
+char *dos_buffer2_to_multistr(BUFFER2 *str)
+{
+       char *lbuf = lbufs[nexti];
+       char *p;
+       uint16 *src = str->buffer;
+       int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; p-lbuf < max_size; src++) {
+               if (*src == 0) {
+                       *p++ = ' ';
+               } else {
+                       uint16 ucs2_val = SVAL(src,0);
+                       uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+                       if (cp_val < 256)
+                               *p++ = (char)cp_val;
+                       else {
+                               *p++ = (cp_val >> 8) & 0xff;
+                               *p++ = (cp_val & 0xff);
+                       }
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+/*******************************************************************
+ Create a null-terminated unicode string from a null-terminated DOS
+ codepage string.
+ Return number of unicode chars copied, excluding the null character.
+ Unicode strings created are in little-endian format.
+********************************************************************/
+
+size_t dos_struni2(char *dst, const char *src, size_t max_len)
+{
+       size_t len = 0;
+
+       if (dst == NULL)
+               return 0;
+
+       if (src != NULL) {
+               for (; *src && len < max_len-2; len++, dst +=2) {
+                       size_t skip = get_character_len(*src);
+                       smb_ucs2_t val = (*src & 0xff);
+
+                       /*
+                        * If this is a multibyte character (and all DOS/Windows
+                        * codepages have at maximum 2 byte multibyte characters)
+                        * then work out the index value for the unicode conversion.
+                        */
+
+                       if (skip == 2)
+                               val = ((val << 8) | (src[1] & 0xff));
+
+                       SSVAL(dst,0,doscp_to_ucs2[val]);
+                       if (skip)
+                               src += skip;
+                       else
+                               src++;
+               }
+       }
+
+       SSVAL(dst,0,0);
+
+       return len;
+}
+
+/*******************************************************************
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr(char *buf)
+{
+       char *lbuf = lbufs[nexti];
+       uint16 *src = (uint16 *)buf;
+       char *p;
+
+       nexti = (nexti+1)%8;
+
+       for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
+               uint16 ucs2_val = SVAL(src,0);
+               uint16 cp_val = ucs2_to_doscp[ucs2_val];
+
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
+       }
+
+       *p = 0;
+       return lbuf;
+}
+
+/*******************************************************************
+ Free any existing maps.
+********************************************************************/
+
+static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+       /* this handles identity mappings where we share the pointer */
+       if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
+               *pp_ucs2_to_cp = NULL;
+       }
+
+       if (*pp_cp_to_ucs2) {
+               free(*pp_cp_to_ucs2);
+               *pp_cp_to_ucs2 = NULL;
+       }
+
+       if (*pp_ucs2_to_cp) {
+               free(*pp_ucs2_to_cp);
+               *pp_ucs2_to_cp = NULL;
+       }
+}
+
+
+/*******************************************************************
+ Build a default (null) codepage to unicode map.
+********************************************************************/
+
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+  int i;
+
+  free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+  if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
+    DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
+    abort();
+  }
+
+  *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
+  for (i = 0; i < 65536; i++)
+    (*pp_cp_to_ucs2)[i] = i;
+}
+
+/*******************************************************************
+ Load a codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+{
+  pstring unicode_map_file_name;
+  FILE *fp = NULL;
+  SMB_STRUCT_STAT st;
+  smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
+  uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
+  size_t cp_to_ucs2_size;
+  size_t ucs2_to_cp_size;
+  size_t i;
+  size_t size;
+  char buf[UNICODE_MAP_HEADER_SIZE];
+
+  DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
+
+  if (*codepage == '\0')
+    goto clean_and_exit;
+
+  if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
+    DEBUG(0,("load_unicode_map: filename too long to load\n"));
+    goto clean_and_exit;
+  }
+
+  pstrcpy(unicode_map_file_name, CODEPAGEDIR);
+  pstrcat(unicode_map_file_name, "/");
+  pstrcat(unicode_map_file_name, "unicode_map.");
+  pstrcat(unicode_map_file_name, codepage);
+
+  if(sys_stat(unicode_map_file_name,&st)!=0) {
+    DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
+              unicode_map_file_name));
+    goto clean_and_exit;
+  }
+
+  size = st.st_size;
+
+  if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
+    DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
+unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
+    goto clean_and_exit;
+  }
+
+  if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
+    DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
+              unicode_map_file_name, strerror(errno)));
+    goto clean_and_exit;
+  }
+
+  if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
+    DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
+              unicode_map_file_name, strerror(errno)));
+    goto clean_and_exit;
+  }
+
+  /* Check the version value */
+  if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
+    DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
+Needed %hu, got %hu.\n",
+          unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
+          SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
+    goto clean_and_exit;
+  }
+
+  /* Check the codepage value */
+  if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
+    DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
+requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
+    goto clean_and_exit;
+  }
+
+  ucs2_to_cp_size = 2*65536;
+  if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
+    /* 
+     * This is a multibyte code page.
+     */
+    cp_to_ucs2_size = 2*65536;
+  } else {
+    /*
+     * Single byte code page.
+     */
+    cp_to_ucs2_size = 2*256;
+  }
+
+  /* 
+   * Free any old translation tables.
+   */
+
+  free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+  if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
+    DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
+    goto clean_and_exit;
+  }
+
+  if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
+    DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
+    goto clean_and_exit;
+  }
+
+  if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
+    DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
+              unicode_map_file_name, strerror(errno)));
+    goto clean_and_exit;
+  }
+
+  if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
+    DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
+              unicode_map_file_name, strerror(errno)));
+    goto clean_and_exit;
+  }
+
+  /*
+   * Now ensure the 16 bit values are in the correct endianness.
+   */
+
+  for (i = 0; i < cp_to_ucs2_size/2; i++)
+    cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
+
+  for (i = 0; i < ucs2_to_cp_size/2; i++)
+    ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
+
+  fclose(fp);
+
+  *pp_cp_to_ucs2 = cp_to_ucs2;
+  *pp_ucs2_to_cp = ucs2_to_cp;
+
+  return True;
+
+clean_and_exit:
+
+  /* pseudo destructor :-) */
+
+  if(fp != NULL)
+    fclose(fp);
+
+  free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+  default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
+
+  return False;
+}
+
+/*******************************************************************
+ Load a dos codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_dos_unicode_map(int codepage)
+{
+  fstring codepage_str;
+
+  slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
+  return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
+}
+
+/*******************************************************************
+ Load a UNIX codepage to unicode and vica-versa map.
+********************************************************************/
+
+BOOL load_unix_unicode_map(const char *unix_char_set)
+{
+  fstring upper_unix_char_set;
+
+  fstrcpy(upper_unix_char_set, unix_char_set);
+  strupper(upper_unix_char_set);
+  return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
+}
+
+/*******************************************************************
+ The following functions reproduce many of the non-UNICODE standard
+ string functions in Samba.
+********************************************************************/
+
+/*******************************************************************
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
+                                  size_t dst_len, const uint16 *ucs2_to_cp)
+{
+       size_t dst_pos;
+
+       for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
+               smb_ucs2_t val = ucs2_to_cp[*src++];
+               if(val < 256) {
+                       dst[dst_pos++] = (char)val;
+               } else {
+
+                       if(dst_pos >= dst_len - 2)
+                               break;
+
+                       /*
+                        * A 2 byte value is always written as
+                        * high/low into the buffer stream.
+                        */
+
+                       dst[dst_pos++] = (char)((val >> 8) & 0xff);
+                       dst[dst_pos++] = (char)(val & 0xff);
+               }
+       }       
+
+       dst[dst_pos] = '\0';
+
+       return dst;
+}
+
+/*******************************************************************
+ Convert a multibyte string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ dst_len is in bytes.
+********************************************************************/
+
+smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
+                                 size_t dst_len, smb_ucs2_t *cp_to_ucs2)
+{
+       size_t i;
+
+       dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
+
+       for(i = 0; (i < (dst_len  - 1)) && src[i];) {
+               size_t skip = skip_multibyte_char(*src);
+               smb_ucs2_t val = (*src & 0xff);
+
+               /*
+                * If this is a multibyte character
+                * then work out the index value for the unicode conversion.
+                */
+
+               if (skip == 2)
+                       val = ((val << 8) | (src[1] & 0xff));
+
+               dst[i++] = cp_to_ucs2[val];
+               if (skip)
+                       src += skip;
+               else
+                       src++;
+       }
+
+       dst[i] = 0;
+
+       return dst;
+}
+
+/*******************************************************************
+ Convert a UNICODE string to multibyte format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the MB  codepage format is an
+ encoded one (ie. utf8, hex). See the code in lib/kanji.c
+ for details. dst_len is in bytes.
+********************************************************************/
+
+char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
+{
+       return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
+}
+
+/*******************************************************************
+ Convert a UNIX string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the UNIX codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
+{
+       return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
+}
+
+/*******************************************************************
+ Convert a UNICODE string to DOS format. Note that the 'src' is in
+ native byte order, not little endian. Always zero terminates. 
+ dst_len is in bytes.
+********************************************************************/ 
+
+char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
+{
+       return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
+}
+
+/*******************************************************************
+ Convert a DOS string to UNICODE format. Note that the 'dst' is in
+ native byte order, not little endian. Always zero terminates.
+ This function may be replaced if the DOS codepage format is a
+ multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
+ for details. dst_len is in bytes, not ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
+{
+       return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
+}
+
+/*******************************************************************
+ Count the number of characters in a smb_ucs2_t string.
+********************************************************************/
+
+size_t strlen_w(const smb_ucs2_t *src)
+{
+  size_t len;
+
+  for(len = 0; *src; len++)
+    ;
+
+  return len;
+}
+
+/*******************************************************************
+ Safe wstring copy into a known length string. maxlength includes
+ the terminating zero. maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
+{
+    size_t ucs2_len;
+
+    if (!dest) {
+        DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
+        return NULL;
+    }
+
+    if (!src) {
+        *dest = 0;
+        return dest;
+    }
+
+       maxlength /= sizeof(smb_ucs2_t);
+
+       ucs2_len = strlen_w(src);
+
+    if (ucs2_len >= maxlength) {
+               fstring out;
+        DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
+                       (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
+                       unicode_to_unix(out,src,sizeof(out))) );
+               ucs2_len = maxlength - 1;
+    }
+
+    memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
+    dest[ucs2_len] = 0;
+    return dest;
+}
+
+/*******************************************************************
+ Safe string cat into a string. maxlength includes the terminating zero.
+ maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
+{
+    size_t ucs2_src_len, ucs2_dest_len;
+
+    if (!dest) {
+        DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
+        return NULL;
+    }
+
+    if (!src)
+        return dest;
+
+    ucs2_src_len = strlen_w(src);
+    ucs2_dest_len = strlen_w(dest);
+
+    if (ucs2_src_len + ucs2_dest_len >= maxlength) {
+               fstring out;
+               int new_len = maxlength - ucs2_dest_len - 1;
+        DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
+                       (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
+                       unicode_to_unix(out,src,sizeof(out))) );
+        ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
+    }
+
+    memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
+    dest[ucs2_dest_len + ucs2_src_len] = 0;
+    return dest;
+}
+
+/*******************************************************************
+ Compare the two strings s1 and s2.
+********************************************************************/
+
+int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+       smb_ucs2_t c1, c2;
+
+       for (;;) {
+               c1 = *s1++;
+               c2 = *s2++;
+
+               if (c1 != c2)
+                       return c1 - c2;
+
+               if (c1 == 0)
+            return 0;
+    }
+       return 0;
+}
+
+/*******************************************************************
+ Compare the first n characters of s1 to s2. len is in ucs2 units.
+********************************************************************/
+
+int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
+{
+       smb_ucs2_t c1, c2;
+
+       for (; len != 0; --len) {
+               c1 = *s1++;
+               c2 = *s2++;
+
+               if (c1 != c2)
+                       return c1 - c2;
+
+               if (c1 == 0)
+                       return 0;
+
+    }
+       return 0;
+}
+
+/*******************************************************************
+ Search string s2 from s1.
+********************************************************************/
+
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+       size_t len = strlen_w(s2);
+
+       if (!*s2)
+               return (smb_ucs2_t *)s1;
+
+       for(;*s1; s1++) {
+               if (*s1 == *s2) {
+                       if (strncmp_w(s1, s2, len) == 0)
+                               return (smb_ucs2_t *)s1;
+               }
+       }
+       return NULL; 
+}
+
+/*******************************************************************
+ Search for ucs2 char c from the beginning of s.
+********************************************************************/ 
+
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+       do {
+               if (*s == c)
+                       return (smb_ucs2_t *)s;
+       } while (*s++);
+
+       return NULL;
+}
+
+/*******************************************************************
+ Search for ucs2 char c from the end of s.
+********************************************************************/ 
+
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+       smb_ucs2_t *retval = 0;
+
+       do {
+               if (*s == c)
+                       retval = (smb_ucs2_t *)s;
+       } while (*s++);
+
+       return retval;
+}
+
+/*******************************************************************
+ Search token from s1 separated by any ucs2 char of s2.
+********************************************************************/
+
+smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+       static smb_ucs2_t *s = NULL;
+       smb_ucs2_t *q;
+
+       if (!s1) {
+               if (!s)
+                       return NULL;
+               s1 = s;
+       }
+
+       for (q = s1; *s1; s1++) {
+               smb_ucs2_t *p = strchr_w(s2, *s1);
+               if (p) {
+                       if (s1 != q) {
+                               s = s1 + 1;
+                               *s1 = '\0';
+                               return q;
+                       }
+                       q = s1 + 1;
+               }
+       }
+
+       s = NULL;
+       if (*q)
+               return q;
+
+       return NULL;
+}
+
+/*******************************************************************
+ Duplicate a ucs2 string.
+********************************************************************/
+
+smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
+{
+       size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
+       smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
+    if (newstr == NULL)
+        return NULL;
+    safe_strcpy_w(newstr, s, newlen);
+    return newstr;
+}
+
+/*******************************************************************
+ Mapping tables for UNICODE character. Allows toupper/tolower and
+ isXXX functions to work.
+********************************************************************/
+
+typedef struct {
+       smb_ucs2_t lower;
+       smb_ucs2_t upper;
+       unsigned char flags;
+} smb_unicode_table_t;
+
+static smb_unicode_table_t map_table[] = {
+#include "unicode_map_table.h"
+};
+
+/*******************************************************************
+ Is an upper case wchar.
+********************************************************************/
+
+int isupper_w( smb_ucs2_t val)
+{
+       return (map_table[val].flags & UNI_UPPER);
+}
+
+/*******************************************************************
+ Is a lower case wchar.
+********************************************************************/
+
+int islower_w( smb_ucs2_t val)
+{
+       return (map_table[val].flags & UNI_LOWER);
+}
+
+/*******************************************************************
+ Is a digit wchar.
+********************************************************************/
+
+int isdigit_w( smb_ucs2_t val)
+{
+       return (map_table[val].flags & UNI_DIGIT);
+}
+
+/*******************************************************************
+ Is a hex digit wchar.
+********************************************************************/
+
+int isxdigit_w( smb_ucs2_t val)
+{
+       return (map_table[val].flags & UNI_XDIGIT);
+}
+
+/*******************************************************************
+ Is a space wchar.
+********************************************************************/
+
+int isspace_w( smb_ucs2_t val)
+{
+       return (map_table[val].flags & UNI_SPACE);
+}
+
+/*******************************************************************
+ Convert a wchar to upper case.
+********************************************************************/
+
+smb_ucs2_t toupper_w( smb_ucs2_t val )
+{
+       return map_table[val].upper;
+}
+
+/*******************************************************************
+ Convert a wchar to lower case.
+********************************************************************/
+
+smb_ucs2_t tolower_w( smb_ucs2_t val )
+{
+       return map_table[val].lower;
+}
+
+static smb_ucs2_t *last_ptr = NULL;
+
+void set_first_token_w(smb_ucs2_t *ptr)
+{
+       last_ptr = ptr;
+}
+
+/****************************************************************************
+ Get the next token from a string, return False if none found
+ handles double-quotes. 
+ Based on a routine by GJC@VILLAGE.COM. 
+ Extensively modified by Andrew.Tridgell@anu.edu.au
+ bufsize is in bytes.
+****************************************************************************/
+
+static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t',  (smb_ucs2_t)'\n',  (smb_ucs2_t)'\r', 0};
+static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
+
+BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
+{
+       smb_ucs2_t *s;
+       BOOL quoted;
+       size_t len=1;
+
+       /*
+        * Convert bufsize to smb_ucs2_t units.
+        */
+
+       bufsize /= sizeof(smb_ucs2_t);
+
+       if (!ptr)
+               ptr = &last_ptr;
+       if (!ptr)
+               return(False);
+
+       s = *ptr;
+
+       /*
+        * Default to simple separators.
+        */
+
+       if (!sep)
+               sep = sep_list;
+
+       /*
+        * Find the first non sep char.
+        */
+
+       while(*s && strchr_w(sep,*s))
+               s++;
+
+       /*
+        * Nothing left ?
+        */
+
+       if (!*s)
+               return(False);
+
+       /*
+        * Copy over the token.
+        */
+
+       for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
+               if (*s == quotechar) {
+                       quoted = !quoted;
+               } else {
+                       len++;
+                       *buff++ = *s;
+               }
+       }
+
+       *ptr = (*s) ? s+1 : s;  
+       *buff = 0;
+       last_ptr = *ptr;
+
+       return(True);
+}
+
+/****************************************************************************
+ Convert list of tokens to array; dependent on above routine.
+ Uses last_ptr from above - bit of a hack.
+****************************************************************************/
+
+smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
+{
+       smb_ucs2_t *s=last_ptr;
+       int ictok=0;
+       smb_ucs2_t **ret, **iret;
+
+       if (!sep)
+               sep = sep_list;
+
+       while(*s && strchr_w(sep,*s))
+               s++;
+
+       /*
+        * Nothing left ?
+        */
+
+       if (!*s)
+               return(NULL);
+
+       do {
+               ictok++;
+               while(*s && (!strchr_w(sep,*s)))
+                       s++;
+               while(*s && strchr_w(sep,*s))
+                       *s++=0;
+       } while(*s);
+
+       *ctok = ictok;
+       s = last_ptr;
+
+       if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
+               return NULL;
+  
+       while(ictok--) {
+               *iret++=s;
+               while(*s++)
+                       ;
+               while(!*s)
+                       s++;
+       }
+
+       return ret;
+}
+
+/*******************************************************************
+ Case insensitive string compararison.
+********************************************************************/
+
+int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
+{
+       /* 
+        * Compare until we run out of string, either t or s, or find a difference.
+        */
+
+       while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
+               s++;
+               t++;
+       }
+
+       return(toupper_w(*s) - toupper_w(*t));
+}
+
+/*******************************************************************
+ Case insensitive string compararison, length limited.
+ n is in ucs2 units.
+********************************************************************/
+
+int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
+{
+       /*
+        * Compare until we run out of string, either t or s, or chars.
+        */
+
+       while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
+               s++;
+               t++;
+               n--;
+       }
+
+    /*
+        * Not run out of chars - strings are different lengths.
+        */
+
+    if (n) 
+      return(toupper_w(*s) - toupper_w(*t));
+
+    /*
+        * Identical up to where we run out of chars, 
+        * and strings are same length.
+        */
+
+       return(0);
+}
+
+/*******************************************************************
+ Compare 2 strings.
+********************************************************************/
+
+BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+{
+       if (s1 == s2)
+               return(True);
+       if (!s1 || !s2)
+               return(False);
+  
+       return(StrCaseCmp_w(s1,s2)==0);
+}
+
+/*******************************************************************
+ Compare 2 strings up to and including the nth char. n is in ucs2
+ units.
+******************************************************************/
+
+BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
+{
+       if (s1 == s2)
+               return(True);
+       if (!s1 || !s2 || !n)
+               return(False);
+  
+       return(StrnCaseCmp_w(s1,s2,n)==0);
+}
+
+/*******************************************************************
+ Compare 2 strings (case sensitive).
+********************************************************************/
+
+BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
+{
+       if (s1 == s2)
+               return(True);
+       if (!s1 || !s2)
+               return(False);
+  
+       return(strcmp_w(s1,s2)==0);
+}
+
+/*******************************************************************
+ Convert a string to lower case.
+********************************************************************/
+
+void strlower_w(smb_ucs2_t *s)
+{
+       while (*s) {
+               if (isupper_w(*s))
+                       *s = tolower_w(*s);
+               s++;
+       }
+}
+
+/*******************************************************************
+ Convert a string to upper case.
+********************************************************************/
+
+void strupper_w(smb_ucs2_t *s)
+{
+       while (*s) {
+               if (islower_w(*s))
+                       *s = toupper_w(*s);
+               s++;
+       }
+}
+
+/*******************************************************************
+ Convert a string to "normal" form.
+********************************************************************/
+
+void strnorm_w(smb_ucs2_t *s)
+{
+       extern int case_default;
+       if (case_default == CASE_UPPER)
+               strupper_w(s);
+       else
+               strlower_w(s);
+}
+
+/*******************************************************************
+ Check if a string is in "normal" case.
+********************************************************************/
+
+BOOL strisnormal_w(smb_ucs2_t *s)
+{
+       extern int case_default;
+       if (case_default == CASE_UPPER)
+               return(!strhaslower_w(s));
+
+       return(!strhasupper_w(s));
+}
+
+/****************************************************************************
+ String replace.
+****************************************************************************/
+
+void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
+{
+       while (*s) {
+               if (oldc == *s)
+                       *s = newc;
+               s++;
+       }
+}
+
+/*******************************************************************
+ Skip past some strings in a buffer. n is in bytes.
+********************************************************************/
+
+smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
+{
+       while (n--)
+               buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
+       return(buf);
+}
+
+/*******************************************************************
+ Count the number of characters in a string. Same as strlen_w in
+ smb_ucs2_t string units.
+********************************************************************/
+
+size_t str_charnum_w(const smb_ucs2_t *s)
+{
+       return strlen_w(s);
+}
+
+/*******************************************************************
+ Trim the specified elements off the front and back of a string.
+********************************************************************/
+
+BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
+{
+       BOOL ret = False;
+       size_t front_len = (front && *front) ? strlen_w(front) : 0;
+       size_t back_len = (back && *back) ? strlen_w(back) : 0;
+       size_t s_len;
+
+       while (front_len && strncmp_w(s, front, front_len) == 0) {
+               smb_ucs2_t *p = s;
+               ret = True;
+
+               while (1) {
+                       if (!(*p = p[front_len]))
+                               break;
+                       p++;
+               }
+       }
+
+       if(back_len) {
+               s_len = strlen_w(s);
+               while ((s_len >= back_len) && 
+                       (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
+                       ret = True;
+                       s[s_len - back_len] = 0;
+                       s_len = strlen_w(s);
+               }
+       }
+
+       return(ret);
+}
+
+/****************************************************************************
+ Does a string have any uppercase chars in it ?
+****************************************************************************/
+
+BOOL strhasupper_w(const smb_ucs2_t *s)
+{
+       while (*s) {
+               if (isupper_w(*s))
+                       return(True);
+               s++;
+       }
+       return(False);
+}
+
+/****************************************************************************
+ Does a string have any lowercase chars in it ?
+****************************************************************************/
+
+BOOL strhaslower_w(const smb_ucs2_t *s)
+{
+       while (*s) {
+               if (islower(*s))
+                       return(True);
+               s++;
+       }
+       return(False);
+}
+
+/****************************************************************************
+ Find the number of 'c' chars in a string.
+****************************************************************************/
+
+size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
+{
+       size_t count=0;
+
+       while (*s) {
+               if (*s == c)
+                       count++;
+               s++;
+       }
+       return(count);
+}
+
+/*******************************************************************
+ Return True if a string consists only of one particular character.
+********************************************************************/
+
+BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
+{
+       if(s == NULL)
+               return False;
+       if(!*s)
+               return False;
+
+       while (*s) {
+               if (*s != c)
+                       return False;
+               s++;
+       }
+       return True;
+}
+
+/*******************************************************************
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
+ does *NOT* check for multibyte characters. Don't change it !
+ maxlength is in ucs2 units.
+********************************************************************/
+
+smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
+{
+       size_t len, i;
+
+       if (!dest) {
+               DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
+               return NULL;
+       }
+
+       if (!src) {
+               *dest = 0;
+               return dest;
+       }  
+
+       len = strlen_w(src);
+       if (len >= maxlength)
+               len = maxlength - 1;
+
+       for(i = 0; i < len; i++) {
+               smb_ucs2_t val = src[i];
+               if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
+                       dest[i] = src[i];
+               else
+                       dest[i] = (smb_ucs2_t)'_';
+       }
+
+       dest[i] = 0;
+
+       return dest;
+}
+
+/****************************************************************************
+ Like strncpy but always null terminates. Make sure there is room !
+ The variable n should always be one less than the available size and is in
+ ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
+{
+       smb_ucs2_t *d = dest;
+       if (!dest)
+               return(NULL);
+       if (!src) {
+               *dest = 0;
+               return(dest);
+       }
+
+       while (n-- && (*d++ = *src++))
+               ;
+       *d = 0;
+       return(dest);
+}
+
+/****************************************************************************
+ Like strncpy but copies up to the character marker. Always null terminates.
+ returns a pointer to the character marker in the source string (src).
+ n is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
+{
+       smb_ucs2_t *p;
+       size_t str_len;
+
+       p = strchr_w(src, c);
+       if (p == NULL) {
+               fstring cval;
+               smb_ucs2_t mbcval[2];
+               mbcval[0] = c;
+               mbcval[1] = 0;
+               DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
+                       unicode_to_unix(cval,mbcval,sizeof(cval)) ));
+               return NULL;
+       }
+
+       str_len = PTR_DIFF(p, src) + 1;
+       safe_strcpy_w(dest, src, MIN(n, str_len));
+
+       return p;
+}
+
+/*************************************************************
+ Routine to get hex characters and turn them into a 16 byte array.
+ The array can be variable length, and any non-hex-numeric
+ characters are skipped.  "0xnn" or "0Xnn" is specially catered
+ for. len is in bytes.
+ Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
+**************************************************************/
+
+static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
+static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
+                                                               (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
+                                                               (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
+                                                               (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
+
+size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
+{
+       size_t i;
+       size_t num_chars = 0;
+       unsigned char   lonybble, hinybble;
+       smb_ucs2_t *p1 = NULL, *p2 = NULL;
+
+       /*
+        * Convert to smb_ucs2_t units.
+        */
+
+       len /= sizeof(smb_ucs2_t);
+
+       for (i = 0; i < len && strhex[i] != 0; i++) {
+               if (strnequal_w(hexchars, hexprefix, 2)) {
+                       i++; /* skip two chars */
+                       continue;
+               }
+
+               if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
+                       break;
+
+               i++; /* next hex digit */
+
+               if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
+                       break;
+
+               /* get the two nybbles */
+               hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
+               lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
+
+               p[num_chars] = (hinybble << 4) | lonybble;
+               num_chars++;
+
+               p1 = NULL;
+               p2 = NULL;
+       }
+       return num_chars;
+}
+
+/****************************************************************************
+ Check if a string is part of a list.
+****************************************************************************/
+
+BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
+{
+       wpstring tok;
+       smb_ucs2_t *p=list;
+
+       if (!list)
+               return(False);
+
+       while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
+               if (casesensitive) {
+                       if (strcmp_w(tok,s) == 0)
+                               return(True);
+               } else {
+                       if (StrCaseCmp_w(tok,s) == 0)
+                               return(True);
+               }
+       }
+       return(False);
+}
+
+/* This is used to prevent lots of mallocs of size 2 */
+static smb_ucs2_t *null_string = NULL;
+
+/****************************************************************************
+ Set a string value, allocing the space for the string.
+****************************************************************************/
+
+BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+       size_t l;
+
+       if (!null_string) {
+               if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
+                       DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
+               return False;
+               }
+               *null_string = 0;
+       }
+
+       if (!src)     
+               src = null_string;
+
+       l = strlen_w(src);
+
+       if (l == 0)
+               *dest = null_string;
+       else {
+               (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
+               if ((*dest) == NULL) {
+                       DEBUG(0,("Out of memory in string_init_w\n"));
+                       return False;
+               }
+
+               wpstrcpy(*dest,src);
+       }
+       return(True);
+}
+
+/****************************************************************************
+ Free a string value.
+****************************************************************************/
+
+void string_free_w(smb_ucs2_t **s)
+{
+       if (!s || !(*s))
+               return;
+       if (*s == null_string)
+               *s = NULL;
+       if (*s)
+               free((char *)*s);
+       *s = NULL;
+}
+
+/****************************************************************************
+ Set a string value, allocing the space for the string, and deallocating any 
+ existing space.
+****************************************************************************/
+
+BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+{
+       string_free_w(dest);
+
+       return(string_init_w(dest,src));
+}
+
+/****************************************************************************
+ Substitute a string for a pattern in another string. Make sure there is 
+ enough room !
+
+ This routine looks for pattern in s and replaces it with 
+ insert. It may do multiple replacements.
+
+ Any of " ; ' $ or ` in the insert string are replaced with _
+ if len==0 then no length check is performed
+ len is in ucs2 units.
+****************************************************************************/
+
+void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+       smb_ucs2_t *p;
+       ssize_t ls,lp,li, i;
+
+       if (!insert || !pattern || !s)
+               return;
+
+       ls = (ssize_t)strlen_w(s);
+       lp = (ssize_t)strlen_w(pattern);
+       li = (ssize_t)strlen_w(insert);
+
+       if (!*pattern)
+               return;
+       
+       while (lp <= ls && (p = strstr_w(s,pattern))) {
+               if (len && (ls + (li-lp) >= len)) {
+                       fstring out;
+                       DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n", 
+                                (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+                                unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+                       break;
+               }
+               if (li != lp)
+                       memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+               for (i=0;i<li;i++) {
+                       switch (insert[i]) {
+                       case (smb_ucs2_t)'`':
+                       case (smb_ucs2_t)'"':
+                       case (smb_ucs2_t)'\'':
+                       case (smb_ucs2_t)';':
+                       case (smb_ucs2_t)'$':
+                       case (smb_ucs2_t)'%':
+                       case (smb_ucs2_t)'\r':
+                       case (smb_ucs2_t)'\n':
+                               p[i] = (smb_ucs2_t)'_';
+                               break;
+                       default:
+                               p[i] = insert[i];
+                       }
+               }
+               s = p + li;
+               ls += (li-lp);
+       }
+}
+
+void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
+{
+       string_sub_w(s, pattern, insert, sizeof(wfstring));
+}
+
+void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
+{
+       string_sub_w(s, pattern, insert, sizeof(wpstring));
+}
+
+/****************************************************************************
+ Similar to string_sub() but allows for any character to be substituted. 
+ Use with caution !
+ if len==0 then no length check is performed.
+****************************************************************************/
+
+void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
+{
+       smb_ucs2_t *p;
+       ssize_t ls,lp,li;
+
+       if (!insert || !pattern || !s)
+               return;
+
+       ls = (ssize_t)strlen_w(s);
+       lp = (ssize_t)strlen_w(pattern);
+       li = (ssize_t)strlen_w(insert);
+
+       if (!*pattern)
+               return;
+       
+       while (lp <= ls && (p = strstr_w(s,pattern))) {
+               if (len && (ls + (li-lp) >= len)) {
+                       fstring out;
+                       DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n", 
+                                (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
+                                unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
+                       break;
+               }
+               if (li != lp)
+                       memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
+
+               memcpy(p, insert, li*sizeof(smb_ucs2_t));
+               s = p + li;
+               ls += (li-lp);
+       }
+}
+
+/****************************************************************************
+ Splits out the front and back at a separator.
+****************************************************************************/
+
+void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
+{
+    smb_ucs2_t *p = strrchr_w(path, sep);
+
+       if (p != NULL)
+               *p = 0;
+
+       if (front != NULL)
+               wpstrcpy(front, path);
+
+       if (p != NULL) {
+               if (back != NULL)
+                       wpstrcpy(back, p+1);
+               *p = (smb_ucs2_t)'\\';
+       } else {
+               if (back != NULL)
+                       back[0] = 0;
+       }
+}
+
+
+/****************************************************************************
+ Write an octal as a string.
+****************************************************************************/
+
+smb_ucs2_t *octal_string_w(int i)
+{
+       static smb_ucs2_t wret[64];
+       char ret[64];
+
+       if (i == -1)
+               slprintf(ret, sizeof(ret), "-1");
+       else 
+               slprintf(ret, sizeof(ret), "0%o", i);
+       return unix_to_unicode(wret, ret, sizeof(wret));
+}
+
+
+/****************************************************************************
+ Truncate a string at a specified length.
+ length is in ucs2 units.
+****************************************************************************/
+
+smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
+{
+       if (s && strlen_w(s) > length)
+               s[length] = 0;
+
+       return s;
+}
index 1ab6832045ee4fecf9360d1cefa82097687a373f..a8165824f832efe1bff6822e15559a726c37489c 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.[pl]o
 *.po32
 
index 358e2b45a8bca7a7758587dd77257af981b02c76..c311a125a0e40d236882aa001cc4a2623b2f7be7 100644 (file)
@@ -977,7 +977,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
        timeout.tv_sec = t/1000;
        timeout.tv_usec = 1000*(t%1000);
 
-       sys_select(fd+1,&fds,&fds,&timeout);
+       sys_select(fd+1,&fds,NULL,&timeout);
 
        if (FD_ISSET(fd,&fds)) 
                return(read_packet(fd,type));
index 4c75aaee1f6a6a86540964a90f2d2b89f72b1913..6c6fb567e997742a73e6afdf486492937b302b9a 100644 (file)
@@ -29,16 +29,16 @@ initialises a password structure
 ****************************************************************************/
 void pwd_init(struct pwd_info *pwd)
 {
-       ZERO_STRUCT(pwd->password  );
+       ZERO_STRUCT(pwd->password);
        ZERO_STRUCT(pwd->smb_lm_pwd);
        ZERO_STRUCT(pwd->smb_nt_pwd);
        ZERO_STRUCT(pwd->smb_lm_owf);
        ZERO_STRUCT(pwd->smb_nt_owf);
        pwd->nt_owf_len = 0;
 
-       pwd->null_pwd  = True; /* safest option... */
+       pwd->null_pwd = True;   /* safest option... */
        pwd->cleartext = False;
-       pwd->crypted   = False;
+       pwd->crypted = False;
 }
 
 /****************************************************************************
@@ -57,7 +57,7 @@ BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2)
 {
        if (pwd1->crypted || pwd2->crypted)
        {
-               DEBUG(0,("pwd_compare: cannot compare crypted passwords\n"));
+               DEBUG(0, ("pwd_compare: cannot compare crypted passwords\n"));
                return True;
        }
 
@@ -65,21 +65,15 @@ BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2)
        {
                if (strequal(pwd1->password, pwd2->password))
                {
-                       ZERO_STRUCT(pwd1);
-                       ZERO_STRUCT(pwd2);
-
                        return True;
                }
        }
        if (pwd1->null_pwd && pwd2->null_pwd)
        {
-               ZERO_STRUCT(pwd1);
-               ZERO_STRUCT(pwd2);
-
                return True;
        }
 
-       if (!pwd1->null_pwd  && !pwd2->null_pwd &&
+       if (!pwd1->null_pwd && !pwd2->null_pwd &&
            !pwd1->cleartext && !pwd2->cleartext)
        {
                dump_data_pw("pwd compare: nt#1\n", pwd1->smb_nt_pwd, 16);
@@ -91,16 +85,10 @@ BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2)
                if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0 &&
                    memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
                {
-                       ZERO_STRUCT(pwd1);
-                       ZERO_STRUCT(pwd2);
-
                        return True;
                }
        }
 
-       ZERO_STRUCT(pwd1);
-       ZERO_STRUCT(pwd2);
-
        return False;
 }
 
@@ -114,7 +102,7 @@ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
 
        pwd_init(pwd);
 
-       user_pass = (char*)getpass(passwd_report);
+       user_pass = (char *)getpass(passwd_report);
 
        if (user_pass == NULL || user_pass[0] == 0)
        {
@@ -138,8 +126,8 @@ void pwd_set_nullpwd(struct pwd_info *pwd)
        pwd_init(pwd);
 
        pwd->cleartext = False;
-       pwd->null_pwd  = True;
-       pwd->crypted   = False;
+       pwd->null_pwd = True;
+       pwd->crypted = False;
 }
 
 /****************************************************************************
@@ -150,8 +138,8 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
        pwd_init(pwd);
        fstrcpy(pwd->password, clr);
        pwd->cleartext = True;
-       pwd->null_pwd  = False;
-       pwd->crypted   = False;
+       pwd->null_pwd = False;
+       pwd->crypted = False;
 
 }
 
@@ -174,48 +162,27 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
  stores lm and nt hashed passwords
  ****************************************************************************/
 void pwd_set_lm_nt_16(struct pwd_info *pwd,
-                               const uchar lm_pwd[16],
-                               const uchar nt_pwd[16])
+                     const uchar lm_pwd[16], const uchar nt_pwd[16])
 {
        pwd_init(pwd);
 
-       if (lm_pwd)
-       {
-               memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
-       }
-       else
-       {
-               memset(pwd->smb_lm_pwd, 0, 16);
-       }
+       Memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
+       Memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
 
-       if (nt_pwd)
-       {
-               memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
-       }
-       else
-       {
-               memset(pwd->smb_nt_pwd, 0, 16);
-       }
-
-       pwd->null_pwd  = False;
+       pwd->null_pwd = False;
        pwd->cleartext = False;
-       pwd->crypted   = False;
+       pwd->crypted = False;
 
 }
 
 /****************************************************************************
  gets lm and nt hashed passwords
  ****************************************************************************/
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16],
+                     uchar nt_pwd[16])
 {
-       if (lm_pwd != NULL)
-       {
-               memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
-       }
-       if (nt_pwd != NULL)
-       {
-               memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
-       }
+       Memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
+       Memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
 }
 
 /****************************************************************************
@@ -226,7 +193,7 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
        pwd_init(pwd);
 
        nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
-       pwd->null_pwd  = False;
+       pwd->null_pwd = False;
        pwd->cleartext = False;
        pwd->crypted = False;
 
@@ -236,34 +203,31 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
  makes lm and nt OWF crypts
  ****************************************************************************/
 void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
-               const char *user, const char *server, const char *domain,
-                                       uchar sess_key[16])
+                        const char *user, const char *server,
+                        const char *domain, uchar sess_key[16])
 {
        uchar kr[16];
 
-       DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
-               user, server, domain));
+       DEBUG(10, ("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
+                  user, server, domain));
 
 
        SMBgenclientchals(pwd->lm_cli_chal,
                          pwd->nt_cli_chal,
-                         &pwd->nt_cli_chal_len,
-                         server, domain);
-       
+                         &pwd->nt_cli_chal_len, server, domain);
+
        ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
 
        /* lm # */
        SMBOWFencrypt_ntv2(kr,
-                          srv_key, 8,
-                          pwd->lm_cli_chal, 8,
-                          pwd->smb_lm_owf);
+                          srv_key, 8, pwd->lm_cli_chal, 8, pwd->smb_lm_owf);
        memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
 
        /* nt # */
        SMBOWFencrypt_ntv2(kr,
-                      srv_key, 8,
-                      pwd->nt_cli_chal, pwd->nt_cli_chal_len,
-                      pwd->smb_nt_owf);
+                          srv_key, 8,
+                          pwd->nt_cli_chal, pwd->nt_cli_chal_len,
+                          pwd->smb_nt_owf);
        memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
        pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
 
@@ -273,26 +237,26 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
 #endif
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("server cryptkey: "));
+       DEBUG(100, ("server cryptkey: "));
        dump_data(100, srv_key, 8);
 
-       DEBUG(100,("client lmv2 cryptkey: "));
+       DEBUG(100, ("client lmv2 cryptkey: "));
        dump_data(100, pwd->lm_cli_chal, 8);
 
-       DEBUG(100,("client ntv2 cryptkey: "));
+       DEBUG(100, ("client ntv2 cryptkey: "));
        dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
 
-       DEBUG(100,("ntv2_owf_passwd: "));
+       DEBUG(100, ("ntv2_owf_passwd: "));
        dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
-       DEBUG(100,("nt_sess_pwd: "));
+       DEBUG(100, ("nt_sess_pwd: "));
        dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
 
-       DEBUG(100,("lmv2_owf_passwd: "));
+       DEBUG(100, ("lmv2_owf_passwd: "));
        dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
-       DEBUG(100,("lm_sess_pwd: "));
+       DEBUG(100, ("lm_sess_pwd: "));
        dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
 
-       DEBUG(100,("session key:\n"));
+       DEBUG(100, ("session key:\n"));
        dump_data(100, sess_key, 16);
 #endif
        pwd->crypted = True;
@@ -303,12 +267,12 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
  makes lm and nt OWF crypts
  ****************************************************************************/
 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
-                               uchar sess_key[16])
+                       uchar sess_key[16])
 {
        if (pwd->null_pwd)
        {
 #ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
+               DEBUG(100, ("pwd_make_lm_nt_owf: NULL password\n"));
 #endif
                pwd->nt_owf_len = 0;
                return;
@@ -322,20 +286,20 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
        SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, sess_key);
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("client cryptkey: "));
+       DEBUG(100, ("client cryptkey: "));
        dump_data(100, cryptkey, 8);
 
-       DEBUG(100,("nt_owf_passwd: "));
+       DEBUG(100, ("nt_owf_passwd: "));
        dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
-       DEBUG(100,("nt_sess_pwd: "));
+       DEBUG(100, ("nt_sess_pwd: "));
        dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
 
-       DEBUG(100,("lm_owf_passwd: "));
+       DEBUG(100, ("lm_owf_passwd: "));
        dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
-       DEBUG(100,("lm_sess_pwd: "));
+       DEBUG(100, ("lm_sess_pwd: "));
        dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
 
-       DEBUG(100,("session key:\n"));
+       DEBUG(100, ("session key:\n"));
        dump_data(100, sess_key, 16);
 #endif
 
@@ -347,12 +311,12 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
  gets lm and nt crypts
  ****************************************************************************/
 void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len)
+                      uchar * nt_owf, size_t * nt_owf_len)
 {
        if (pwd->null_pwd)
        {
 #ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
+               DEBUG(100, ("pwd_get_lm_nt_owf: NULL password\n"));
 #endif
                if (nt_owf_len != NULL)
                {
@@ -360,18 +324,12 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
                }
                return;
        }
-               
-       if (lm_owf != NULL)
-       {
-               memcpy(lm_owf, pwd->smb_lm_owf, 24);
-       }
-       if (nt_owf != NULL)
-       {
-               memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
-       }
+
+       Memcpy(lm_owf, pwd->smb_lm_owf, 24);
+       Memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
+
        if (nt_owf_len != NULL)
        {
                *nt_owf_len = pwd->nt_owf_len;
        }
 }
-
index 1fd10d60e0e753647ba9e1dfc8975778bb6874b0..68314adb1c256e9fbd5920ec3a9fdae32d2d1f2b 100644 (file)
@@ -224,6 +224,51 @@ void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24)
 #endif
 }
 
+BOOL make_oem_passwd_hash(uchar data[516],
+                         const char *pwrd, int new_pw_len,
+                         const uchar old_pw_hash[16], BOOL unicode)
+{
+       if (new_pw_len == 0)
+       {
+               new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
+       }
+
+       if (new_pw_len > 512)
+       {
+               DEBUG(0,
+                     ("make_oem_passwd_hash: new password is too long.\n"));
+               return False;
+       }
+
+       /*
+        * Now setup the data area.
+        * We need to generate a random fill
+        * for this area to make it harder to
+        * decrypt. JRA.
+        */
+       generate_random_buffer(data, 516, False);
+       if (unicode)
+       {
+               ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
+       }
+       else
+       {
+               fstrcpy(&data[512 - new_pw_len], pwrd);
+       }
+       SIVAL(data, 512, new_pw_len);
+
+#ifdef DEBUG_PASSWORD
+       DEBUG(100, ("make_oem_passwd_hash\n"));
+       dump_data(100, data, 516);
+#endif
+       if (old_pw_hash != NULL)
+       {
+               SamOEMhash(data, old_pw_hash, True);
+       }
+
+       return True;
+}
+
 void SMBOWFencrypt_ntv2(const uchar kr[16],
                        const uchar * srv_chal, int srv_chal_len,
                        const uchar * cli_chal, int cli_chal_len,
@@ -416,51 +461,6 @@ void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16])
        lm_owf_genW(pwd, lm_p16);
 }
 
-BOOL make_oem_passwd_hash(uchar data[516],
-                         const char *pwrd, int new_pw_len,
-                         const uchar old_pw_hash[16], BOOL unicode)
-{
-       if (new_pw_len == 0)
-       {
-               new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
-       }
-
-       if (new_pw_len > 512)
-       {
-               DEBUG(0,
-                     ("make_oem_passwd_hash: new password is too long.\n"));
-               return False;
-       }
-
-       /*
-        * Now setup the data area.
-        * We need to generate a random fill
-        * for this area to make it harder to
-        * decrypt. JRA.
-        */
-       generate_random_buffer(data, 516, False);
-       if (unicode)
-       {
-               ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
-       }
-       else
-       {
-               fstrcpy(&data[512 - new_pw_len], pwrd);
-       }
-       SIVAL(data, 512, new_pw_len);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100, ("make_oem_passwd_hash\n"));
-       dump_data(100, data, 516);
-#endif
-       if (old_pw_hash != NULL)
-       {
-               SamOEMhash(data, old_pw_hash, True);
-       }
-
-       return True;
-}
-
 BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key)
 {
        const uchar *keyptr = key;
index f53fd7456399efd81f1ca5d5ee386b385fb53002..2f85e92932a382eb7414411a4b2edce523b57b0d 100644 (file)
@@ -38,41 +38,27 @@ extern int DEBUGLEVEL;
 /* the locking database handle */
 static TDB_CONTEXT *tdb;
 
+int global_smbpid;
+
+
 /****************************************************************************
- Utility function to map a lock type correctly depending on the real open
- mode of a file.
+remove any locks on this fd
 ****************************************************************************/
-static int map_lock_type(files_struct *fsp, int lock_type)
+void locking_close_file(files_struct *fsp)
 {
-       if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
-               /*
-                * Many UNIX's cannot get a write lock on a file opened read-only.
-                * Win32 locking semantics allow this.
-                * Do the best we can and attempt a read-only lock.
-                */
-               DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
-               return F_RDLCK;
-       } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
-               /*
-                * Ditto for read locks on write only files.
-                */
-               DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n"));
-               return F_WRLCK;
-       }
-       
-       /*
-        * This return should be the most normal, as we attempt
-        * to always open files read/write.
-        */
-       
-       return lock_type;
+       if (!lp_locking(SNUM(fsp->conn))) return;
+
+       brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode, 
+                 getpid(), fsp->conn->cnum, fsp->fnum);
 }
 
+
 /****************************************************************************
  Utility function called to see if a file region is locked.
 ****************************************************************************/
 BOOL is_locked(files_struct *fsp,connection_struct *conn,
-              SMB_OFF_T count,SMB_OFF_T offset, int lock_type)
+              SMB_OFF_T count,SMB_OFF_T offset, 
+              enum brl_type lock_type)
 {
        int snum = SNUM(conn);
        
@@ -82,13 +68,9 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
        if (!lp_locking(snum) || !lp_strict_locking(snum))
                return(False);
 
-       /*
-        * Note that most UNIX's can *test* for a write lock on
-        * a read-only fd, just not *set* a write lock on a read-only
-        * fd. So we don't need to use map_lock_type here.
-        */
-       
-       return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type));
+       return !brl_locktest(fsp->fd_ptr->dev, fsp->fd_ptr->inode, 
+                            global_smbpid, getpid(), conn->cnum, 
+                            offset, count, lock_type);
 }
 
 
@@ -96,7 +78,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
  Utility function called by locking requests.
 ****************************************************************************/
 BOOL do_lock(files_struct *fsp,connection_struct *conn,
-             SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
+             SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
              int *eclass,uint32 *ecode)
 {
        BOOL ok = False;
@@ -113,9 +95,12 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
        DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
                  lock_type, (double)offset, (double)count, fsp->fsp_name ));
 
-       if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
-               ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
-                               map_lock_type(fsp,lock_type));
+       if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
+               ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
+                             global_smbpid, getpid(), conn->cnum, 
+                             offset, count, 
+                             lock_type);
+       }
 
        if (!ok) {
                *eclass = ERRDOS;
@@ -130,7 +115,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
  Utility function called by unlocking requests.
 ****************************************************************************/
 BOOL do_unlock(files_struct *fsp,connection_struct *conn,
-               SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode)
+               SMB_OFF_T count,SMB_OFF_T offset, 
+              int *eclass,uint32 *ecode)
 {
        BOOL ok = False;
        
@@ -140,8 +126,11 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
        DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
                  (double)offset, (double)count, fsp->fsp_name ));
        
-       if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
-               ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
+       if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
+               ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
+                               global_smbpid, getpid(), conn->cnum, 
+                               offset, count);
+       }
    
        if (!ok) {
                *eclass = ERRDOS;
@@ -156,6 +145,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
 ****************************************************************************/
 BOOL locking_init(int read_only)
 {
+       brl_init(read_only);
+
        if (tdb) return True;
 
        tdb = tdb_open(lock_path("locking.tdb"), 
@@ -474,19 +465,21 @@ BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock)
        return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv);
 }
 
-static void (*traverse_callback)(share_mode_entry *, char *);
 
 /****************************************************************************
 traverse the whole database with this function, calling traverse_callback
 on each share mode
 ****************************************************************************/
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
+                       void* state)
 {
        struct locking_data *data;
        share_mode_entry *shares;
        char *name;
        int i;
 
+       SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
+
        data = (struct locking_data *)dbuf.dptr;
        shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
        name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares);
@@ -501,9 +494,8 @@ static int traverse_fn(TDB_CONTEXT *db, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
  Call the specified function on each entry under management by the
  share mode system.
 ********************************************************************/
-int share_mode_forall(void (*fn)(share_mode_entry *, char *))
+int share_mode_forall(SHAREMODE_FN(fn))
 {
        if (!tdb) return 0;
-       traverse_callback = fn;
-       return tdb_traverse(tdb, traverse_fn, NULL);
+       return tdb_traverse(tdb, traverse_fn, (void*)fn);
 }
index b13cb76b58aa346a131a5fba251b96e3f468abac..fc7bdb54f8f406004f5702fdeeee3a55186455d5 100644 (file)
@@ -298,8 +298,6 @@ void exit_server(char *reason)
 #endif
        }    
 
-       locking_end();
-
        DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
 #ifdef MEM_MAN
        {
@@ -539,9 +537,6 @@ static void usage(char *pname)
                exit_server("open socket failed");
        }
 
-       if (!locking_init(0))
-               exit(1);
-
        /* possibly reload the services file. */
        fn->reload_services(True);
        
index 54c080204353a1adf3053dc12484ae4b381d3dd5..492040e881a93e87e5487aaa0fbaf06752c02d39 100644 (file)
@@ -79,8 +79,7 @@ static BOOL receive_message_or_msrpc(int c, prs_struct * ps,
        to.tv_sec = timeout / 1000;
        to.tv_usec = (timeout % 1000) * 1000;
 
-       selrtn =
-               sys_select(MAX(maxfd, c) + 1, &fds, NULL,
+       selrtn = sys_select(MAX(maxfd, c) + 1, &fds, NULL,
                           timeout > 0 ? &to : NULL);
 
        /* Check if error */
@@ -163,7 +162,7 @@ static void process_msrpc(rpcsrv_struct * l, const char *name,
                        int selrtn;
                        struct timeval to;
                        int maxfd;
-                       int timeout = SMBD_SELECT_LOOP * 1000;
+                       int timeout = SMBD_SELECT_TIMEOUT * 1000;
 
                        smb_read_error = 0;
 
@@ -174,8 +173,7 @@ static void process_msrpc(rpcsrv_struct * l, const char *name,
                        to.tv_sec = timeout / 1000;
                        to.tv_usec = (timeout % 1000) * 1000;
 
-                       selrtn =
-                               sys_select(MAX(maxfd, l->c) + 1, NULL, &fds,
+                       selrtn = sys_select(MAX(maxfd, l->c) + 1, NULL, &fds,
                                           timeout > 0 ? &to : NULL);
 
                        /* Check if error */
@@ -406,6 +404,7 @@ BOOL msrpcd_init(int c, rpcsrv_struct ** l)
 void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
                    const char *name)
 {
+       int counter = 0;
        extern fstring remote_machine;
        extern fstring local_machine;
        extern pstring global_myname;
@@ -428,79 +427,58 @@ void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
 
        while (True)
        {
-               int counter;
-               int service_load_counter = 0;
                BOOL got_msrpc = False;
                prs_struct pdu;
 
                errno = 0;
 
-               for (counter = SMBD_SELECT_LOOP;
-                    !receive_message_or_msrpc(l->c, &pdu,
-                                              SMBD_SELECT_LOOP * 1000,
-                                              &got_msrpc);
-                    counter += SMBD_SELECT_LOOP)
+               counter = (counter + 1 ) % 200;
+               
+               if (!receive_message_or_msrpc(l->c, &pdu,
+                                              SMBD_SELECT_TIMEOUT * 1000,
+                                              &got_msrpc))
                {
-                       time_t t;
-
-                       if (counter > 365 * 3600)       /* big number of seconds. */
-                       {
-                               counter = 0;
-                               service_load_counter = 0;
-                       }
-
                        if (smb_read_error == READ_EOF)
                        {
                                DEBUG(3, ("end of file from client\n"));
-                               if (fn->idle != NULL)
-                               {
-                                       become_root(False);
-                                       fn->idle();
-                                       unbecome_root(False);
-                               }
-                               return;
                        }
 
                        if (smb_read_error == READ_ERROR)
                        {
                                DEBUG(3, ("receive error (%s) exiting\n",
                                          strerror(errno)));
-                               if (fn->idle != NULL)
-                               {
-                                       become_root(False);
-                                       fn->idle();
-                                       unbecome_root(False);
-                               }
-                               return;
                        }
 
-                       t = time(NULL);
-
-                       /* check for smb.conf reload */
-                       if (counter >=
-                           service_load_counter + SMBD_RELOAD_CHECK)
+                       if (fn->idle != NULL)
                        {
-                               service_load_counter = counter;
-
-                               /* reload services, if files have changed. */
-                               fn->reload_services(True);
+                               become_root(False);
+                               fn->idle();
+                               unbecome_root(False);
                        }
 
+                       return;
+               }
+
+               if (counter == 0)
+               {
+                       /* reload services, if files have changed. */
+                       fn->reload_services(True);
+               }
+
+               /*
+                * If reload_after_sighup == True then we got a SIGHUP
+                * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+                */
+
+               if (reload_after_sighup)
+               {
+                       DEBUG(0,
+                             ("Reloading services after SIGHUP\n"));
+                       fn->reload_services(False);
+                       reload_after_sighup = False;
                        /*
-                        * If reload_after_sighup == True then we got a SIGHUP
-                        * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+                        * Use this as an excuse to print some stats.
                         */
-
-                       if (reload_after_sighup)
-                       {
-                               DEBUG(0,
-                                     ("Reloading services after SIGHUP\n"));
-                               fn->reload_services(False);
-                               reload_after_sighup = False;
-                               /*
-                                * Use this as an excuse to print some stats.
-                                */
-                       }
                }
 
                if (got_msrpc)
@@ -510,3 +488,4 @@ void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
                prs_free_data(&pdu);
        }
 }
+
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 6d609cec52bfa8ec66916564302c3273f2d07a98..442e6d6a56f94304cea796d1d4d9b05ec02d63d6 100644 (file)
@@ -1 +1,2 @@
+.libs
 *.po
index decd78ee19286ad37d4de7b22b47a6fd13006041..fc4fbb2acad0354ae8f7f564babb08014e2daf5f 100644 (file)
@@ -151,10 +151,10 @@ void winbindd_getgrnam_from_group(DOM_SID *domain_sid, char *domain_name,
 
     if (!(winbindd_surs_sam_sid_to_unixid(&domain_group_sid, 
                                           request->data.groupname,
-                                          SID_NAME_ALIAS, &unix_gid) ||
+                                          RID_TYPE_ALIAS, &unix_gid) ||
           winbindd_surs_sam_sid_to_unixid(&domain_group_sid, 
                                           request->data.groupname,
-                                          SID_NAME_DOM_GRP, &unix_gid))) {
+                                          RID_TYPE_GROUP, &unix_gid))) {
         DEBUG(1, ("error sursing unix gid for sid\n"));
     } else {
         DOM_SID temp;
@@ -189,9 +189,9 @@ void winbindd_getgrnam_from_gid(DOM_SID *domain_sid, char *domain_name,
 
     /* Get sid from gid */
 
-    if (!(winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_ALIAS,
+    if (!(winbindd_surs_unixid_to_sam_sid(request->data.gid, RID_TYPE_ALIAS,
                                           &domain_group_sid, False) ||
-          winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_DOM_GRP,
+          winbindd_surs_unixid_to_sam_sid(request->data.gid, RID_TYPE_GROUP,
                                           &domain_group_sid, False))) {
         DEBUG(1, ("Could not convert gid %d to domain or local sid\n",
                   request->data.gid));
index 6cd9b92753f6633dad80d71214d3a983185bb3a3..f9e7070425ae2e1dd337b7d5e1c0370c5beee6f0 100644 (file)
@@ -88,6 +88,8 @@ static int create_new_id(fstring sid_str, int isgroup)
     uint32 hwm_id;
     fstring temp;
 
+    DEBUG(0,("TODO: create_new_id: lock tdb databases\n"));
+
     isgroup ? (id_by_sid = surs_tdb_gid_by_sid) : 
         (id_by_sid = surs_tdb_uid_by_sid);
 
index 3c21408d82f9f208767d9f10fab88ffafa2a48bb..d3405e36eb68b8e05c29af76d84aaffb9e55f5c7 100644 (file)
@@ -117,17 +117,17 @@ void winbindd_getpwnam_from_user(DOM_SID *domain_sid, char *domain_name,
     sid_append_rid(&group_sid, user_info.info.id21->group_rid);
 
     res = winbindd_surs_sam_sid_to_unixid(&user_sid, request->data.username,
-                                          SID_NAME_USER, &unix_uid);
+                                          RID_TYPE_USER, &unix_uid);
 
     if (!res) {
         DEBUG(1, ("error sursing unix uid for sid\n"));
     } else {
 
         res = res ? (winbindd_surs_sam_sid_to_unixid(&group_sid, NULL,
-                                                     SID_NAME_ALIAS, 
+                                                     RID_TYPE_ALIAS, 
                                                      &unix_gid) ||
                      winbindd_surs_sam_sid_to_unixid(&group_sid, NULL,
-                                                     SID_NAME_DOM_GRP, 
+                                                     RID_TYPE_GROUP, 
                                                      &unix_gid)) : False;
         if (!res) {
             DEBUG(1, ("error sursing unix gid for sid\n"));
@@ -164,7 +164,7 @@ void winbindd_getpwnam_from_uid(DOM_SID *domain_sid,
 
     /* Get sid from uid */
 
-    if (!winbindd_surs_unixid_to_sam_sid(request->data.uid, SID_NAME_USER,
+    if (!winbindd_surs_unixid_to_sam_sid(request->data.uid, RID_TYPE_USER,
                                          &domain_user_sid, False)) {
         DEBUG(1, ("Could not convert uid %d to domain sid\n",
                   request->data.uid));
@@ -205,7 +205,7 @@ void winbindd_getpwnam_from_uid(DOM_SID *domain_sid,
     }
 
     res = winbindd_surs_sam_sid_to_unixid(&domain_user_sid, username,
-                                          SID_NAME_USER, &unix_uid);
+                                          RID_TYPE_USER, &unix_uid);
 
     if (!res) {
         DEBUG(1, ("error sursing unix uid for sid\n"));
@@ -214,9 +214,9 @@ void winbindd_getpwnam_from_uid(DOM_SID *domain_sid,
     /* ??? Should be domain_group-sid??? */
 
     res = res ? (winbindd_surs_sam_sid_to_unixid(&domain_user_sid, NULL,
-                                                 SID_NAME_ALIAS, &unix_gid) ||
+                                                 RID_TYPE_ALIAS, &unix_gid) ||
                  winbindd_surs_sam_sid_to_unixid(&domain_user_sid, NULL,
-                                                 SID_NAME_DOM_GRP, &unix_gid))
+                                                 RID_TYPE_GROUP, &unix_gid))
         : False;
 
     /* Fill in password structure */
index 1ab6832045ee4fecf9360d1cefa82097687a373f..a8165824f832efe1bff6822e15559a726c37489c 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.[pl]o
 *.po32
 
index 4ded5f64cb317842f07319c15132a713cdd47fdf..6bdb631662cb3c357152b065155b55b0c282a9b3 100644 (file)
@@ -71,7 +71,7 @@ BOOL bLoaded = False;
 extern int DEBUGLEVEL;
 extern pstring user_socket_options;
 extern pstring global_myname;
-pstring global_scope;
+pstring global_scope = "";
 
 #ifndef GLOBAL_NAME
 #define GLOBAL_NAME "global"
@@ -118,9 +118,6 @@ typedef struct
   char *szConfigFile;
   char *szSMBPasswdFile;
   char *szSAMDirectory;
-  char *szSMBPassGroupFile;
-  char *szSMBGroupFile;
-  char *szSMBAliasFile;
   char *szPasswordServer;
   char *szSocketOptions;
   char *szValidChars;
@@ -140,7 +137,6 @@ typedef struct
   char *szLogonHome;
   char *szSmbrun;
   char *szWINSserver;
-  char *szWINSHook;
   char *szCodingSystem;
   char *szInterfaces;
   char *szRemoteAnnounce;
@@ -167,8 +163,15 @@ typedef struct
   char *szLdapBuiltinSubcontext;
 #endif /* WITH_NT5LDAP */
   char *szPanicAction;
+  char *szAddUserScript;
+  char *szDelUserScript;
+  char *szWINSHook;
   char *szNtForms;
   char *szNtDriverFile;  
+#ifdef WITH_UTMP
+  char *szUtmpDir;
+#endif /* WITH_UTMP */
+  char *szSourceEnv;
   int max_log_size;
   int mangled_stack;
   int max_xmit;
@@ -252,6 +255,7 @@ typedef struct
   BOOL bTimestampLogs;
   BOOL bNTSmbSupport;
   BOOL bNTPipeSupport;
+  BOOL bNTAclSupport;
   BOOL bStatCache;
   BOOL bKernelOplocks;
 #if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
@@ -264,6 +268,7 @@ typedef struct
   BOOL bDebugHiresTimestamp;
   BOOL bDebugPid;
   BOOL bDebugUid;
+  BOOL bHostMSDfs;
 } global;
 
 static global Globals;
@@ -315,17 +320,25 @@ typedef struct
   char *writelist;
   char *volume;
   char *fstype;
-  char *vfsObjectFile;
-  struct vfs_options *vfsOptions;
+  char *szVfsObjectFile;
+  char *szVfsOptions;
   int  iMinPrintSpace;
+  int  iWriteCacheSize;
   int  iCreate_mask;
   int  iCreate_force_mode;
+  int  iSecurity_mask;
+  int  iSecurity_force_mode;
   int  iDir_mask;
   int  iDir_force_mode;
+  int  iDir_Security_mask;
+  int  iDir_Security_force_mode;
   int  iMaxConnections;
   int  iDefaultCase;
   int  iPrinting;
+  int  iOplockContentionLimit;
   BOOL bAlternatePerm;
+  BOOL bPreexecClose;
+  BOOL bRootpreexecClose;
   BOOL bRevalidate;
   BOOL bCaseSensitive;
   BOOL bCasePreserve;
@@ -346,8 +359,12 @@ typedef struct
   BOOL bMap_archive;
   BOOL bLocking;
   BOOL bStrictLocking;
+#ifdef WITH_UTMP
+  BOOL bUtmp;
+#endif
   BOOL bShareModes;
   BOOL bOpLocks;
+  BOOL bLevel2OpLocks;
   BOOL bOnlyUser;
   BOOL bMangledNames;
   BOOL bWidelinks;
@@ -363,6 +380,11 @@ typedef struct
   BOOL bDosFiletimeResolution;
   BOOL bFakeDirCreateTimes;
   BOOL bBlockingLocks;
+  BOOL bInheritPerms; 
+#ifdef MS_DFS
+  char *szDfsMap;
+  BOOL bDfsMapLoaded;
+#endif
   char dummy[3]; /* for alignment */
 } service;
 
@@ -413,14 +435,22 @@ static service sDefault =
   NULL,    /* vfs object */
   NULL,    /* vfs options */
   0,       /* iMinPrintSpace */
+  0,       /* iWriteCacheSize */
   0744,    /* iCreate_mask */
   0000,    /* iCreate_force_mode */
+  -1,      /* iSecurity_mask */
+  -1,      /* iSecurity_force_mode */
   0755,    /* iDir_mask */
   0000,    /* iDir_force_mode */
+  -1,      /* iDir_Security_mask */
+  -1,      /* iDir_Security_force_mode */
   0,       /* iMaxConnections */
   CASE_LOWER, /* iDefaultCase */
   DEFAULT_PRINTING, /* iPrinting */
+  2,       /* iOplockContentionLimit */
   False,   /* bAlternatePerm */
+  False,   /* bPreexecClose */
+  False,   /* bRootpreexecClose */
   False,   /* revalidate */
   False,   /* case sensitive */
   True,   /* case preserve */
@@ -441,8 +471,12 @@ static service sDefault =
   True,  /* bMap_archive */
   True,  /* bLocking */
   False,  /* bStrictLocking */
+#ifdef WITH_UTMP
+  False,  /* bUtmp */
+#endif
   True,  /* bShareModes */
   True,  /* bOpLocks */
+  True, /* bLevel2OpLocks */
   False, /* bOnlyUser */
   True,  /* bMangledNames */
   True,  /* bWidelinks */
@@ -458,12 +492,17 @@ static service sDefault =
   False, /* bDosFiletimeResolution */
   False, /* bFakeDirCreateTimes */
   True,  /* bBlockingLocks */
+  False, /* bInheritPerms */
+#ifdef MS_DFS
+  NULL,    /* MS Dfs map path */
+  False, /* bDfsMapLoaded */
+#endif
   ""     /* dummy */
 };
 
 
 
-/* local variables */
+/* Local variables */
 static service **ServicePtrs = NULL;
 static int iNumServices = 0;
 static int iServiceIndex = 0;
@@ -480,8 +519,10 @@ static BOOL handle_include(char *pszParmValue, char **ptr);
 static BOOL handle_copy(char *pszParmValue, char **ptr);
 static BOOL handle_character_set(char *pszParmValue,char **ptr);
 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
+static BOOL handle_client_code_page(char *pszParmValue,char **ptr);
 static BOOL handle_vfs_object(char *pszParmValue, char **ptr);
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr);
+static BOOL handle_source_env(char *pszParmValue,char **ptr);
+static BOOL handle_netbios_name(char *pszParmValue,char **ptr);
 
 static void set_server_role(void);
 static void set_default_server_announce_type(void);
@@ -499,14 +540,26 @@ static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "ai
                                           {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
                                           {PRINT_QNX, "qnx"},   {PRINT_PLP, "plp"},
                                           {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
-                                          {-1, NULL}};
+                                          {PRINT_CUPS, "cups"}, {-1, NULL}};
+
+static struct enum_list enum_bool_auto[] = {{True, "True"},
+                                               {False, "False"}, 
+                                               {True, "Yes"}, 
+                                               {False, "No"}, 
+                                               {Auto, "Auto"}, 
+                                               {-1, NULL}};
 
-static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
-                                             {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
+/* Types of machine we can announce as. */
+#define ANNOUNCE_AS_NT_SERVER 1
+#define ANNOUNCE_AS_WIN95 2
+#define ANNOUNCE_AS_WFW 3
+#define ANNOUNCE_AS_NT_WORKSTATION 4
+
+static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
 
 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
 
-static struct enum_list enum_bool_auto[] = {{True, "True"}, {False, "False"}, {True, "Yes"}, {False, "No"}, {Auto, "Auto"}, {-1, NULL}};
+static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
 
 /* 
    Do you want session setups at user level security with a invalid
@@ -540,15 +593,16 @@ static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3,
 static struct parm_struct parm_table[] =
 {
   {"Base Options", P_SEP, P_SEPARATOR},
-
-  {"comment",          P_STRING,  P_LOCAL,  &sDefault.comment,          NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
-  {"path",             P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
-  {"directory",        P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  0},
-  {"workgroup",        P_USTRING, P_GLOBAL, &Globals.szWorkGroup,       NULL,   NULL,  FLAG_BASIC},
-  {"netbios name",     P_UGSTRING,P_GLOBAL, global_myname,                     NULL,   NULL,  FLAG_BASIC},
-  {"netbios aliases",  P_STRING,  P_GLOBAL, &Globals.szNetbiosAliases,  NULL,   NULL,  0},
-  {"netbios scope",    P_UGSTRING,  P_GLOBAL, global_scope,  NULL,   NULL,  0},
-  {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL,   NULL,  FLAG_BASIC},
+  {"coding system",    P_STRING,  P_GLOBAL, &Globals.szCodingSystem,    handle_coding_system, NULL,  0},
+  {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page,   NULL,  0},
+  {"comment",          P_STRING,  P_LOCAL,  &sDefault.comment,          NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
+  {"path",             P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
+  {"directory",        P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL,   NULL,  FLAG_DOS_STRING},
+  {"workgroup",        P_USTRING, P_GLOBAL, &Globals.szWorkGroup,       NULL,   NULL,  FLAG_BASIC|FLAG_DOS_STRING},
+  {"netbios name",     P_UGSTRING,P_GLOBAL, global_myname,              handle_netbios_name,   NULL,  FLAG_BASIC|FLAG_DOS_STRING},
+  {"netbios aliases",  P_STRING,  P_GLOBAL, &Globals.szNetbiosAliases,  NULL,   NULL,  FLAG_DOS_STRING},
+  {"netbios scope",    P_UGSTRING,P_GLOBAL, global_scope,               NULL,   NULL,  FLAG_DOS_STRING},
+  {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL,   NULL,  FLAG_BASIC|FLAG_DOS_STRING},
   {"interfaces",       P_STRING,  P_GLOBAL, &Globals.szInterfaces,      NULL,   NULL,  FLAG_BASIC},
   {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL,   NULL,  0},
 
@@ -588,38 +642,43 @@ static struct parm_struct parm_table[] =
   {"password level",   P_INTEGER, P_GLOBAL, &Globals.pwordlevel,        NULL,   NULL,  0},
   {"username level",   P_INTEGER, P_GLOBAL, &Globals.unamelevel,        NULL,   NULL,  0},
   {"unix password sync", P_BOOL,  P_GLOBAL, &Globals.bUnixPasswdSync,   NULL,   NULL,  0},
-  {"dfs map",          P_STRING,  P_GLOBAL, &Globals.szDfsMap,          NULL,   NULL,  0},
-  {"revalidate",       P_BOOL,    P_LOCAL,  &sDefault.bRevalidate,      NULL,   NULL,  FLAG_GLOBAL},
-  {"username",         P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  FLAG_GLOBAL},
+  {"revalidate",       P_BOOL,    P_LOCAL,  &sDefault.bRevalidate,      NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"use rhosts",       P_BOOL,    P_GLOBAL, &Globals.bUseRhosts,        NULL,   NULL,  0},
+  {"username",         P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
   {"user",             P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  0},
   {"users",            P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  0},
-  {"guest account",    P_STRING,  P_LOCAL,  &sDefault.szGuestaccount,   NULL,   NULL,  FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
-  {"invalid users",    P_STRING,  P_LOCAL,  &sDefault.szInvalidUsers,   NULL,   NULL,  FLAG_GLOBAL},
-  {"valid users",      P_STRING,  P_LOCAL,  &sDefault.szValidUsers,     NULL,   NULL,  FLAG_GLOBAL},
-  {"admin users",      P_STRING,  P_LOCAL,  &sDefault.szAdminUsers,     NULL,   NULL,  FLAG_GLOBAL},
-  {"read list",        P_STRING,  P_LOCAL,  &sDefault.readlist,         NULL,   NULL,  FLAG_GLOBAL},
-  {"write list",       P_STRING,  P_LOCAL,  &sDefault.writelist,        NULL,   NULL,  FLAG_GLOBAL},
-  {"force user",       P_STRING,  P_LOCAL,  &sDefault.force_user,       NULL,   NULL,  0},
-  {"force group",      P_STRING,  P_LOCAL,  &sDefault.force_group,      NULL,   NULL,  0},
+  {"guest account",    P_STRING,  P_LOCAL,  &sDefault.szGuestaccount,   NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_GLOBAL},
+  {"invalid users",    P_STRING,  P_LOCAL,  &sDefault.szInvalidUsers,   NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"valid users",      P_STRING,  P_LOCAL,  &sDefault.szValidUsers,     NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"admin users",      P_STRING,  P_LOCAL,  &sDefault.szAdminUsers,     NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"read list",        P_STRING,  P_LOCAL,  &sDefault.readlist,         NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"write list",       P_STRING,  P_LOCAL,  &sDefault.writelist,        NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"force user",       P_STRING,  P_LOCAL,  &sDefault.force_user,       NULL,   NULL,  FLAG_SHARE},
+  {"force group",      P_STRING,  P_LOCAL,  &sDefault.force_group,      NULL,   NULL,  FLAG_SHARE},
   {"group",            P_STRING,  P_LOCAL,  &sDefault.force_group,      NULL,   NULL,  0},
-  {"read only",        P_BOOL,    P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  FLAG_BASIC},
+  {"read only",        P_BOOL,    P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  FLAG_BASIC|FLAG_SHARE},
   {"write ok",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
   {"writeable",        P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
   {"writable",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL,   NULL,  0},
-  {"create mask",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,     NULL,   NULL,  FLAG_GLOBAL},
+  {"create mask",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,     NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
   {"create mode",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mask,     NULL,   NULL,  FLAG_GLOBAL},
-  {"force create mode",P_OCTAL,   P_LOCAL,  &sDefault.iCreate_force_mode,     NULL,   NULL,  FLAG_GLOBAL},
-  {"directory mask",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,        NULL,   NULL,  FLAG_GLOBAL},
+  {"force create mode",P_OCTAL,   P_LOCAL,  &sDefault.iCreate_force_mode,     NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"security mask",    P_OCTAL,   P_LOCAL,  &sDefault.iSecurity_mask,   NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"force security mode",P_OCTAL, P_LOCAL,  &sDefault.iSecurity_force_mode,NULL,NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"directory mask",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,        NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
   {"directory mode",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_mask,        NULL,   NULL,  FLAG_GLOBAL},
-  {"force directory mode",   P_OCTAL,   P_LOCAL,  &sDefault.iDir_force_mode,        NULL,   NULL,  FLAG_GLOBAL},
-  {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL,   NULL,  0},
+  {"force directory mode",   P_OCTAL,P_LOCAL,&sDefault.iDir_force_mode, NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"directory security mask",P_OCTAL,P_LOCAL,&sDefault.iDir_Security_mask,NULL, NULL,  FLAG_GLOBAL|FLAG_SHARE},
+  {"force directory security mode",P_OCTAL, P_LOCAL,  &sDefault.iDir_Security_force_mode,NULL,NULL,FLAG_GLOBAL|FLAG_SHARE},
+  {"inherit permissions",P_BOOL,  P_LOCAL,  &sDefault.bInheritPerms,    NULL,   NULL,  FLAG_SHARE},
+  {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL,   NULL,  FLAG_SHARE},
   {"only guest",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL,   NULL,  0},
-  {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL,   NULL,  FLAG_BASIC|FLAG_PRINT},
+  {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
   {"public",           P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL,   NULL,  0},
-  {"only user",        P_BOOL,    P_LOCAL,  &sDefault.bOnlyUser,        NULL,   NULL,  0},
-  {"hosts allow",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
+  {"only user",        P_BOOL,    P_LOCAL,  &sDefault.bOnlyUser,        NULL,   NULL,  FLAG_SHARE},
+  {"hosts allow",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
   {"allow hosts",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL,   NULL,  0},
-  {"hosts deny",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
+  {"hosts deny",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL,   NULL,  FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
   {"deny hosts",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL,   NULL,  0},
 
 #ifdef WITH_SSL
@@ -654,7 +713,7 @@ static struct parm_struct parm_table[] =
   {"debug hires timestamp",  P_BOOL,    P_GLOBAL, &Globals.bDebugHiresTimestamp,    NULL,   NULL,  0},
   {"debug pid",        P_BOOL,    P_GLOBAL, &Globals.bDebugPid,         NULL,   NULL,  0},
   {"debug uid",        P_BOOL,    P_GLOBAL, &Globals.bDebugUid,         NULL,   NULL,  0},
-  {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL,   NULL,  FLAG_GLOBAL},
+  {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL,   NULL,  FLAG_GLOBAL|FLAG_SHARE|FLAG_PRINT},
 
   {"Protocol Options", P_SEP, P_SEPARATOR},
 
@@ -664,6 +723,7 @@ static struct parm_struct parm_table[] =
   {"write raw",        P_BOOL,    P_GLOBAL, &Globals.bWriteRaw,         NULL,   NULL,  0},
   {"nt smb support",   P_BOOL,    P_GLOBAL, &Globals.bNTSmbSupport,    NULL,   NULL,  0},
   {"nt pipe support",   P_BOOL,    P_GLOBAL, &Globals.bNTPipeSupport,    NULL,   NULL,  0},
+  {"nt acl support",   P_BOOL,    P_GLOBAL, &Globals.bNTAclSupport,     NULL,   NULL,  0},
   {"announce version", P_STRING,  P_GLOBAL, &Globals.szAnnounceVersion, NULL,   NULL,  0},
   {"announce as",      P_ENUM,    P_GLOBAL, &Globals.announce_as,       NULL,   enum_announce_as, 0},
   {"max mux",          P_INTEGER, P_GLOBAL, &Globals.max_mux,           NULL,   NULL,  0},
@@ -683,40 +743,40 @@ static struct parm_struct parm_table[] =
   {"getwd cache",      P_BOOL,    P_GLOBAL, &use_getwd_cache,           NULL,   NULL,  0},
   {"keepalive",        P_INTEGER, P_GLOBAL, &keepalive,                 NULL,   NULL,  0},
   {"lpq cache time",   P_INTEGER, P_GLOBAL, &Globals.lpqcachetime,      NULL,   NULL,  0},
-  {"max connections",  P_INTEGER, P_LOCAL,  &sDefault.iMaxConnections,  NULL,   NULL,  0},
+  {"max connections",  P_INTEGER, P_LOCAL,  &sDefault.iMaxConnections,  NULL,   NULL,  FLAG_SHARE},
   {"max disk size",    P_INTEGER, P_GLOBAL, &Globals.maxdisksize,       NULL,   NULL,  0},
   {"max open files",   P_INTEGER, P_GLOBAL, &Globals.max_open_files,    NULL,   NULL,  0},
-  {"min print space",  P_INTEGER, P_LOCAL,  &sDefault.iMinPrintSpace,   NULL,   NULL,  0},
+  {"min print space",  P_INTEGER, P_LOCAL,  &sDefault.iMinPrintSpace,   NULL,   NULL,  FLAG_PRINT},
   {"read prediction",  P_BOOL,    P_GLOBAL, &Globals.bReadPrediction,   NULL,   NULL,  0},
   {"read size",        P_INTEGER, P_GLOBAL, &Globals.ReadSize,          NULL,   NULL,  0},
   {"shared mem size",  P_INTEGER, P_GLOBAL, &Globals.shmem_size,        NULL,   NULL,  0},
   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL,   NULL,  0},
   {"stat cache size",  P_INTEGER, P_GLOBAL, &Globals.stat_cache_size,   NULL,   NULL,  0},
-  {"strict sync",      P_BOOL,    P_LOCAL,  &sDefault.bStrictSync,      NULL,   NULL,  0},
-  {"sync always",      P_BOOL,    P_LOCAL,  &sDefault.bSyncAlways,      NULL,   NULL,  0},
+  {"strict sync",      P_BOOL,    P_LOCAL,  &sDefault.bStrictSync,      NULL,   NULL,  FLAG_SHARE},
+  {"sync always",      P_BOOL,    P_LOCAL,  &sDefault.bSyncAlways,      NULL,   NULL,  FLAG_SHARE},
+  {"write cache size", P_INTEGER, P_LOCAL,  &sDefault.iWriteCacheSize,  NULL,   NULL,  FLAG_SHARE},
 
   {"Printing Options", P_SEP, P_SEPARATOR},
-
-  {"load printers",    P_BOOL,    P_GLOBAL, &Globals.bLoadPrinters,     NULL,   NULL,  0},
-  {"printcap name",    P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL,   NULL,  0},
+  {"load printers",    P_BOOL,    P_GLOBAL, &Globals.bLoadPrinters,     NULL,   NULL,  FLAG_PRINT},
+  {"printcap name",    P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL,   NULL,  FLAG_PRINT},
   {"printcap",         P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL,   NULL,  0},
-  {"printer driver file", P_STRING,  P_GLOBAL, &Globals.szDriverFile,   NULL,   NULL,  0},
+  {"printer driver file", P_STRING,  P_GLOBAL, &Globals.szDriverFile,   NULL,   NULL,  FLAG_PRINT},
+  {"printable",        P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  FLAG_PRINT},
   {"print ok",         P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  0},
-  {"printable",        P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  0},
   {"postscript",       P_BOOL,    P_LOCAL,  &sDefault.bPostscript,      NULL,   NULL,  FLAG_PRINT},
   {"printing",         P_ENUM,    P_LOCAL,  &sDefault.iPrinting,        NULL,   enum_printing, FLAG_PRINT|FLAG_GLOBAL},
   {"print command",    P_STRING,  P_LOCAL,  &sDefault.szPrintcommand,   NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
   {"lpq command",      P_STRING,  P_LOCAL,  &sDefault.szLpqcommand,     NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
   {"lprm command",     P_STRING,  P_LOCAL,  &sDefault.szLprmcommand,    NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
-  {"lppause command",  P_STRING,  P_LOCAL,  &sDefault.szLppausecommand, NULL,   NULL,  FLAG_GLOBAL},
-  {"lpresume command", P_STRING,  P_LOCAL,  &sDefault.szLpresumecommand,NULL,   NULL,  FLAG_GLOBAL},
-  {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
-  {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
+  {"lppause command",  P_STRING,  P_LOCAL,  &sDefault.szLppausecommand, NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
+  {"lpresume command", P_STRING,  P_LOCAL,  &sDefault.szLpresumecommand,NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
+  {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+  {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
 
   {"printer name",     P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL,   NULL,  FLAG_PRINT},
   {"printer",          P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL,   NULL,  0},
-  {"printer driver",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriver,  NULL,   NULL,  0},
-  {"printer driver location",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriverLocation,  NULL,   NULL,  FLAG_GLOBAL},
+  {"printer driver",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriver,  NULL,   NULL,  FLAG_PRINT},
+  {"printer driver location",   P_STRING,  P_LOCAL,  &sDefault.szPrinterDriverLocation,  NULL,   NULL,  FLAG_PRINT|FLAG_GLOBAL},
   {"nt forms file",    P_STRING,  P_GLOBAL, &Globals.szNtForms,         NULL,   NULL,  FLAG_GLOBAL},
   {"nt printer driver",P_STRING,  P_GLOBAL, &Globals.szNtDriverFile,    NULL,   NULL,  FLAG_GLOBAL},
 
@@ -724,25 +784,23 @@ static struct parm_struct parm_table[] =
   {"strip dot",        P_BOOL,    P_GLOBAL, &Globals.bStripDot,         NULL,   NULL,  0},
   {"character set",    P_STRING,  P_GLOBAL, &Globals.szCharacterSet,    handle_character_set, NULL,  0},
   {"mangled stack",    P_INTEGER, P_GLOBAL, &Globals.mangled_stack,     NULL,   NULL,  0},
-  {"coding system",    P_STRING,  P_GLOBAL, &Globals.szCodingSystem,    handle_coding_system, NULL,  0},
-  {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL,   NULL,  0},
-  {"default case",     P_ENUM, P_LOCAL,  &sDefault.iDefaultCase,        NULL,   enum_case, 0},
-  {"case sensitive",   P_BOOL,    P_LOCAL,  &sDefault.bCaseSensitive,   NULL,   NULL,  FLAG_GLOBAL},
+  {"default case",     P_ENUM, P_LOCAL,  &sDefault.iDefaultCase,        NULL,   enum_case, FLAG_SHARE},
+  {"case sensitive",   P_BOOL,    P_LOCAL,  &sDefault.bCaseSensitive,   NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
   {"casesignames",     P_BOOL,    P_LOCAL,  &sDefault.bCaseSensitive,   NULL,   NULL,  0},
-  {"preserve case",    P_BOOL,    P_LOCAL,  &sDefault.bCasePreserve,    NULL,   NULL,  FLAG_GLOBAL},
-  {"short preserve case",P_BOOL,  P_LOCAL,  &sDefault.bShortCasePreserve,NULL,   NULL,  FLAG_GLOBAL},
-  {"mangle case",      P_BOOL,    P_LOCAL,  &sDefault.bCaseMangle,      NULL,   NULL,  FLAG_GLOBAL},
-  {"mangling char",    P_CHAR,    P_LOCAL,  &sDefault.magic_char,       NULL,   NULL,  FLAG_GLOBAL},
-  {"hide dot files",   P_BOOL,    P_LOCAL,  &sDefault.bHideDotFiles,    NULL,   NULL,  FLAG_GLOBAL},
-  {"delete veto files",P_BOOL,    P_LOCAL,  &sDefault.bDeleteVetoFiles, NULL,   NULL,  FLAG_GLOBAL},
-  {"veto files",       P_STRING,  P_LOCAL,  &sDefault.szVetoFiles,      NULL,   NULL,  FLAG_GLOBAL},
-  {"hide files",       P_STRING,  P_LOCAL,  &sDefault.szHideFiles,      NULL,   NULL,  FLAG_GLOBAL},
-  {"veto oplock files",P_STRING,  P_LOCAL,  &sDefault.szVetoOplockFiles,NULL,   NULL,  FLAG_GLOBAL},
-  {"map system",       P_BOOL,    P_LOCAL,  &sDefault.bMap_system,      NULL,   NULL,  FLAG_GLOBAL},
-  {"map hidden",       P_BOOL,    P_LOCAL,  &sDefault.bMap_hidden,      NULL,   NULL,  FLAG_GLOBAL},
-  {"map archive",      P_BOOL,    P_LOCAL,  &sDefault.bMap_archive,     NULL,   NULL,  FLAG_GLOBAL},
-  {"mangled names",    P_BOOL,    P_LOCAL,  &sDefault.bMangledNames,    NULL,   NULL,  FLAG_GLOBAL},
-  {"mangled map",      P_STRING,  P_LOCAL,  &sDefault.szMangledMap,     NULL,   NULL,  FLAG_GLOBAL},
+  {"preserve case",    P_BOOL,    P_LOCAL,  &sDefault.bCasePreserve,    NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"short preserve case",P_BOOL,  P_LOCAL,  &sDefault.bShortCasePreserve,NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"mangle case",      P_BOOL,    P_LOCAL,  &sDefault.bCaseMangle,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"mangling char",    P_CHAR,    P_LOCAL,  &sDefault.magic_char,       NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"hide dot files",   P_BOOL,    P_LOCAL,  &sDefault.bHideDotFiles,    NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"delete veto files",P_BOOL,    P_LOCAL,  &sDefault.bDeleteVetoFiles, NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"veto files",       P_STRING,  P_LOCAL,  &sDefault.szVetoFiles,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+  {"hide files",       P_STRING,  P_LOCAL,  &sDefault.szHideFiles,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+  {"veto oplock files",P_STRING,  P_LOCAL,  &sDefault.szVetoOplockFiles,NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
+  {"map system",       P_BOOL,    P_LOCAL,  &sDefault.bMap_system,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"map hidden",       P_BOOL,    P_LOCAL,  &sDefault.bMap_hidden,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"map archive",      P_BOOL,    P_LOCAL,  &sDefault.bMap_archive,     NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"mangled names",    P_BOOL,    P_LOCAL,  &sDefault.bMangledNames,    NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"mangled map",      P_STRING,  P_LOCAL,  &sDefault.szMangledMap,     NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
   {"stat cache",       P_BOOL,    P_GLOBAL, &Globals.bStatCache,        NULL,   NULL,  0},
 
   {"Domain Options", P_SEP, P_SEPARATOR},
@@ -759,24 +817,25 @@ static struct parm_struct parm_table[] =
   {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout,  NULL,   NULL,  0},
 
   {"Logon Options", P_SEP, P_SEPARATOR},
-
-  {"logon script",     P_STRING,  P_GLOBAL, &Globals.szLogonScript,     NULL,   NULL,  0},
-  {"logon path",       P_STRING,  P_GLOBAL, &Globals.szLogonPath,       NULL,   NULL,  0},
+  {"add user script",  P_STRING,  P_GLOBAL, &Globals.szAddUserScript,   NULL,   NULL,  0},
+  {"delete user script",P_STRING, P_GLOBAL, &Globals.szDelUserScript,   NULL,   NULL,  0},
+  {"logon script",     P_STRING,  P_GLOBAL, &Globals.szLogonScript,     NULL,   NULL,  FLAG_DOS_STRING},
+  {"logon path",       P_STRING,  P_GLOBAL, &Globals.szLogonPath,       NULL,   NULL,  FLAG_DOS_STRING},
   {"logon drive",      P_STRING,  P_GLOBAL, &Globals.szLogonDrive,      NULL,   NULL,  0},
-  {"logon home",       P_STRING,  P_GLOBAL, &Globals.szLogonHome,       NULL,   NULL,  0},
+  {"logon home",       P_STRING,  P_GLOBAL, &Globals.szLogonHome,       NULL,   NULL,  FLAG_DOS_STRING},
   {"domain logons",    P_BOOL,    P_GLOBAL, &Globals.bDomainLogons,     NULL,   NULL,  0},
 
   {"Browse Options", P_SEP, P_SEPARATOR},
 
   {"os level",         P_INTEGER, P_GLOBAL, &Globals.os_level,          NULL,   NULL,  FLAG_BASIC},
-  {"lm announce",      P_ENUM,    P_GLOBAL, &Globals.lm_announce,       NULL,   enum_bool_auto, 0},
+  {"lm announce",      P_ENUM,    P_GLOBAL, &Globals.lm_announce,       NULL,   enum_lm_announce, 0},
   {"lm interval",      P_INTEGER, P_GLOBAL, &Globals.lm_interval,       NULL,   NULL,  0},
   {"preferred master", P_ENUM,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   enum_bool_auto,  FLAG_BASIC},
   {"prefered master",  P_ENUM,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   enum_bool_auto,  FLAG_HIDE},
   {"local master",     P_BOOL,    P_GLOBAL, &Globals.bLocalMaster,      NULL,   NULL,  FLAG_BASIC},
   {"domain master",    P_ENUM,    P_GLOBAL, &Globals.bDomainMaster,     NULL,   enum_bool_auto,  FLAG_BASIC},
   {"browse list",      P_BOOL,    P_GLOBAL, &Globals.bBrowseList,       NULL,   NULL,  0},
-  {"browseable",       P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL,   NULL,  0},
+  {"browseable",       P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
   {"browsable",        P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL,   NULL,  0},
 
   {"WINS Options", P_SEP, P_SEPARATOR},
@@ -788,15 +847,20 @@ static struct parm_struct parm_table[] =
   {"wins hook",        P_STRING,  P_GLOBAL, &Globals.szWINSHook, NULL,   NULL,  0},
 
   {"Locking Options", P_SEP, P_SEPARATOR},
-
-  {"blocking locks",   P_BOOL,    P_LOCAL,  &sDefault.bBlockingLocks,    NULL,   NULL,  0},
-  {"fake oplocks",     P_BOOL,    P_LOCAL,  &sDefault.bFakeOplocks,     NULL,   NULL,  0},
+  {"blocking locks",   P_BOOL,    P_LOCAL,  &sDefault.bBlockingLocks,    NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"fake oplocks",     P_BOOL,    P_LOCAL,  &sDefault.bFakeOplocks,     NULL,   NULL,  FLAG_SHARE},
   {"kernel oplocks",   P_BOOL,    P_GLOBAL, &Globals.bKernelOplocks,    NULL,   NULL,  FLAG_GLOBAL},
-  {"locking",          P_BOOL,    P_LOCAL,  &sDefault.bLocking,         NULL,   NULL,  FLAG_GLOBAL},
+  {"locking",          P_BOOL,    P_LOCAL,  &sDefault.bLocking,         NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+#ifdef WITH_UTMP
+  {"utmp",             P_BOOL,    P_LOCAL,  &sDefault.bUtmp,            NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+#endif
   {"ole locking compatibility",   P_BOOL,    P_GLOBAL,  &Globals.bOleLockingCompat,   NULL,   NULL,  FLAG_GLOBAL},
-  {"oplocks",          P_BOOL,    P_LOCAL,  &sDefault.bOpLocks,         NULL,   NULL,  FLAG_GLOBAL},
-  {"strict locking",   P_BOOL,    P_LOCAL,  &sDefault.bStrictLocking,   NULL,   NULL,  FLAG_GLOBAL},
-  {"share modes",      P_BOOL,    P_LOCAL,  &sDefault.bShareModes,      NULL,   NULL,  FLAG_GLOBAL},
+  {"oplocks",          P_BOOL,    P_LOCAL,  &sDefault.bOpLocks,         NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"level2 oplocks",   P_BOOL,    P_LOCAL,  &sDefault.bLevel2OpLocks,   NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL},
+  {"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL},
+  {"strict locking",   P_BOOL,    P_LOCAL,  &sDefault.bStrictLocking,   NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"share modes",      P_BOOL,    P_LOCAL,  &sDefault.bShareModes,      NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
 
 #if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
   {"Ldap Options", P_SEP, P_SEPARATOR},
@@ -834,6 +898,10 @@ static struct parm_struct parm_table[] =
   {"auto services",    P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL,   NULL,  0},
   {"lock dir",         P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL,   NULL,  0},
   {"lock directory",   P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL,   NULL,  0},
+#ifdef WITH_UTMP
+  {"utmp dir",         P_STRING,  P_GLOBAL, &Globals.szUtmpDir,         NULL,   NULL,  0},
+  {"utmp directory",   P_STRING,  P_GLOBAL, &Globals.szUtmpDir,         NULL,   NULL,  0},
+#endif /* WITH_UTMP */
   {"default service",  P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL,   NULL,  0},
   {"default",          P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL,   NULL,  0},
   {"message command",  P_STRING,  P_GLOBAL, &Globals.szMsgCommand,      NULL,   NULL,  0},
@@ -849,31 +917,40 @@ static struct parm_struct parm_table[] =
   {"-valid",           P_BOOL,    P_LOCAL,  &sDefault.valid,            NULL,   NULL,  FLAG_HIDE},
   {"copy",             P_STRING,  P_LOCAL,  &sDefault.szCopy,           handle_copy, NULL,  FLAG_HIDE},
   {"include",          P_STRING,  P_LOCAL,  &sDefault.szInclude,        handle_include, NULL,  FLAG_HIDE},
-  {"exec",             P_STRING,  P_LOCAL,  &sDefault.szPreExec,        NULL,   NULL,  0},
+  {"exec",             P_STRING,  P_LOCAL,  &sDefault.szPreExec,        NULL,   NULL,  FLAG_SHARE|FLAG_PRINT},
   {"preexec",          P_STRING,  P_LOCAL,  &sDefault.szPreExec,        NULL,   NULL,  0},
-  {"postexec",         P_STRING,  P_LOCAL,  &sDefault.szPostExec,       NULL,   NULL,  0},
-  {"root preexec",     P_STRING,  P_LOCAL,  &sDefault.szRootPreExec,    NULL,   NULL,  0},
-  {"root postexec",    P_STRING,  P_LOCAL,  &sDefault.szRootPostExec,   NULL,   NULL,  0},
-  {"available",        P_BOOL,    P_LOCAL,  &sDefault.bAvailable,       NULL,   NULL,  0},
-  {"volume",           P_STRING,  P_LOCAL,  &sDefault.volume,           NULL,   NULL,  0},
-  {"fstype",           P_STRING,  P_LOCAL,  &sDefault.fstype,           NULL,   NULL,  0},
-  {"set directory",    P_BOOLREV, P_LOCAL,  &sDefault.bNo_set_dir,      NULL,   NULL,  0},
-  {"wide links",       P_BOOL,    P_LOCAL,  &sDefault.bWidelinks,       NULL,   NULL,  FLAG_GLOBAL},
-  {"follow symlinks",  P_BOOL,    P_LOCAL,  &sDefault.bSymlinks,        NULL,   NULL,  FLAG_GLOBAL},
-  {"dont descend",     P_STRING,  P_LOCAL,  &sDefault.szDontdescend,    NULL,   NULL,  0},
-  {"magic script",     P_STRING,  P_LOCAL,  &sDefault.szMagicScript,    NULL,   NULL,  0},
-  {"magic output",     P_STRING,  P_LOCAL,  &sDefault.szMagicOutput,    NULL,   NULL,  0},
-  {"delete readonly",  P_BOOL,    P_LOCAL,  &sDefault.bDeleteReadonly,  NULL,   NULL,  FLAG_GLOBAL},
-  {"dos filetimes",    P_BOOL,    P_LOCAL,  &sDefault.bDosFiletimes,    NULL,   NULL,  FLAG_GLOBAL},
-  {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution,   NULL,  NULL,  FLAG_GLOBAL},
+  {"preexec close",    P_BOOL,    P_LOCAL,  &sDefault.bPreexecClose,    NULL,   NULL,  FLAG_SHARE},
+  {"postexec",         P_STRING,  P_LOCAL,  &sDefault.szPostExec,       NULL,   NULL,  FLAG_SHARE|FLAG_PRINT},
+  {"root preexec",     P_STRING,  P_LOCAL,  &sDefault.szRootPreExec,    NULL,   NULL,  FLAG_SHARE|FLAG_PRINT},
+  {"root preexec close", P_BOOL,  P_LOCAL,  &sDefault.bRootpreexecClose,NULL,   NULL,  FLAG_SHARE},
+  {"root postexec",    P_STRING,  P_LOCAL,  &sDefault.szRootPostExec,   NULL,   NULL,  FLAG_SHARE|FLAG_PRINT},
+  {"available",        P_BOOL,    P_LOCAL,  &sDefault.bAvailable,       NULL,   NULL,  FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+  {"volume",           P_STRING,  P_LOCAL,  &sDefault.volume,           NULL,   NULL,  FLAG_SHARE},
+  {"fstype",           P_STRING,  P_LOCAL,  &sDefault.fstype,           NULL,   NULL,  FLAG_SHARE},
+  {"set directory",    P_BOOLREV, P_LOCAL,  &sDefault.bNo_set_dir,      NULL,   NULL,  FLAG_SHARE},
+  {"source environment",P_STRING, P_GLOBAL, &Globals.szSourceEnv,       handle_source_env,NULL,0},
+  {"wide links",       P_BOOL,    P_LOCAL,  &sDefault.bWidelinks,       NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"follow symlinks",  P_BOOL,    P_LOCAL,  &sDefault.bSymlinks,        NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"dont descend",     P_STRING,  P_LOCAL,  &sDefault.szDontdescend,    NULL,   NULL,  FLAG_SHARE},
+  {"magic script",     P_STRING,  P_LOCAL,  &sDefault.szMagicScript,    NULL,   NULL,  FLAG_SHARE},
+  {"magic output",     P_STRING,  P_LOCAL,  &sDefault.szMagicOutput,    NULL,   NULL,  FLAG_SHARE},
+  {"delete readonly",  P_BOOL,    P_LOCAL,  &sDefault.bDeleteReadonly,  NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"dos filetimes",    P_BOOL,    P_LOCAL,  &sDefault.bDosFiletimes,    NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
+  {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution,   NULL,  NULL,  FLAG_SHARE|FLAG_GLOBAL},
   
-  {"fake directory create times", P_BOOL,P_LOCAL,  &sDefault.bFakeDirCreateTimes, NULL,   NULL, FLAG_GLOBAL},
+  {"fake directory create times", P_BOOL,P_LOCAL,  &sDefault.bFakeDirCreateTimes, NULL,   NULL, FLAG_SHARE|FLAG_GLOBAL},
   {"panic action",     P_STRING,  P_GLOBAL, &Globals.szPanicAction,     NULL,   NULL,  0},
 
   {"VFS options", P_SEP, P_SEPARATOR},
 
-  {"vfs object",       P_STRING,  P_LOCAL,  &sDefault.vfsObjectFile,    handle_vfs_object,   NULL,  0},
-  {"vfs option",       P_PTR,  P_LOCAL,  &sDefault.vfsOptions,       handle_vfs_option,   NULL,  0}, 
+  {"vfs object",       P_STRING,  P_LOCAL,  &sDefault.szVfsObjectFile,  handle_vfs_object,   NULL,  0},
+  {"vfs options",      P_STRING,  P_LOCAL,  &sDefault.szVfsOptions,     NULL,   NULL,  0}, 
+
+#ifdef MS_DFS
+  {"dfs map",         P_STRING,  P_LOCAL,  &sDefault.szDfsMap,        NULL,   NULL,  FLAG_SHARE},
+  {"host msdfs",      P_BOOL,    P_GLOBAL, &Globals.bHostMSDfs,        NULL,   NULL, FLAG_GLOBAL},
+#endif
+
   {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL,   NULL, 0}
 };
 
@@ -896,7 +973,7 @@ static void init_globals(void)
        if ((parm_table[i].type == P_STRING ||
             parm_table[i].type == P_USTRING) && 
            parm_table[i].ptr)
-         string_init(parm_table[i].ptr,"");
+         string_set(parm_table[i].ptr,"");
 
       string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
       string_set(&sDefault.szPrinterDriver, "NULL");
@@ -917,7 +994,7 @@ static void init_globals(void)
   string_set(&Globals.szSMBGroupFile, SMB_GROUP_FILE);
   string_set(&Globals.szSMBAliasFile, SMB_ALIAS_FILE);
 #endif
-  string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
+  string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
   string_set(&Globals.szWorkGroup, WORKGROUP);
   string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
   string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
@@ -926,6 +1003,9 @@ static void init_globals(void)
   string_set(&Globals.szNtDriverFile, NTDRIVERSDIR);
   string_set(&Globals.szLockDir, LOCKDIR);
   string_set(&Globals.szRootdir, "/");
+#ifdef WITH_UTMP
+  string_set(&Globals.szUtmpDir, "");
+#endif /* WITH_UTMP */
   string_set(&Globals.szSmbrun, SMBRUN);
   string_set(&Globals.szSocketAddress, "0.0.0.0");
   pstrcpy(s, "Samba ");
@@ -962,7 +1042,7 @@ static void init_globals(void)
   Globals.bReadRaw = True;
   Globals.bWriteRaw = True;
   Globals.bReadPrediction = False;
-  Globals.bReadbmpx = True;
+  Globals.bReadbmpx = False;
   Globals.bNullPasswords = False;
   Globals.bStripDot = False;
   Globals.syslog = 1;
@@ -981,7 +1061,7 @@ static void init_globals(void)
   Globals.lm_interval = 60;
   Globals.shmem_size = SHMEM_SIZE;
   Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
-  Globals.announce_as = ANNOUNCE_AS_NT;
+  Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
   Globals.bUnixRealname = False;
 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
   Globals.bNISHomeMap = False;
@@ -999,9 +1079,10 @@ static void init_globals(void)
   Globals.bOleLockingCompat = True;
   Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
   Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
+  Globals.bNTAclSupport = True; /* Use NT ACLs by default. */
   Globals.bStatCache = True; /* use stat cache by default */
   Globals.map_to_guest = 0; /* By Default, "Never" */
-  Globals.min_passwd_length = 5; /* By Default, 5. */
+  Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
   Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */
 
 #if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
@@ -1021,20 +1102,15 @@ static void init_globals(void)
 
 #ifdef WITH_SSL
   Globals.sslVersion = SMB_SSL_V23;
-
-  /*
-   * Most of the next variables should be string_set!
-   */
-
-  string_set(&Globals.sslHostsRequire, NULL);
-  string_set(&Globals.sslHostsResign, NULL);
-  string_set(&Globals.sslCaCertDir, NULL);
-  string_set(&Globals.sslCaCertFile, NULL);
-  string_set(&Globals.sslCert, NULL);
-  string_set(&Globals.sslPrivKey, NULL);
-  string_set(&Globals.sslClientCert, NULL);
-  string_set(&Globals.sslClientPrivKey, NULL);
-  string_set(&Globals.sslCiphers, NULL);
+  string_set(&Globals.sslHostsRequire, "");
+  string_set(&Globals.sslHostsResign, "");
+  string_set(&Globals.sslCaCertDir, "");
+  string_set(&Globals.sslCaCertFile, "");
+  string_set(&Globals.sslCert, "");
+  string_set(&Globals.sslPrivKey, "");
+  string_set(&Globals.sslClientCert, "");
+  string_set(&Globals.sslClientPrivKey, "");
+  string_set(&Globals.sslCiphers, "");
   Globals.sslEnabled = False;
   Globals.sslReqClientCert = False;
   Globals.sslReqServerCert = False;
@@ -1096,16 +1172,6 @@ static void init_globals(void)
   interpret_coding_system(KANJI);
 }
 
-/***************************************************************************
-check if a string is initialised and if not then initialise it
-***************************************************************************/
-static void string_initial(char **s,char *v)
-{
-  if (!*s || !**s)
-    string_init(s,v);
-}
-
-
 /***************************************************************************
 Initialise the sDefault parameter structure.
 ***************************************************************************/
@@ -1116,100 +1182,83 @@ static void init_locals(void)
     {
     case PRINT_BSD:
     case PRINT_AIX:
+    case PRINT_LPRNG:
     case PRINT_PLP:
-      string_initial(&sDefault.szLpqcommand,"lpq -P%p");
-      string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
-      string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
+      string_set(&sDefault.szLpqcommand,"lpq -P%p");
+      string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
+      string_set(&sDefault.szPrintcommand,"lpr -r -P%p %s");
       break;
 
-    case PRINT_LPRNG:
-      string_initial(&sDefault.szLpqcommand,"lpq -P%p");
-      string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
-      string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
-      string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
-      string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
-      string_initial(&sDefault.szLppausecommand,"lpc hold %p %j");
-      string_initial(&sDefault.szLpresumecommand,"lpc release %p %j");
+    case PRINT_CUPS:
+      string_set(&sDefault.szLpqcommand,"/usr/bin/lpstat -o%p");
+      string_set(&sDefault.szLprmcommand,"/usr/bin/cancel %p-%j");
+      string_set(&sDefault.szPrintcommand,"/usr/bin/lp -d%p -oraw %s; rm %s");
+      string_set(&sDefault.szQueuepausecommand, "/usr/bin/disable %p");
+      string_set(&sDefault.szQueueresumecommand, "/usr/bin/enable %p");
       break;
 
     case PRINT_SYSV:
     case PRINT_HPUX:
-      string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
-      string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
-      string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
-#ifdef SYSV
-      string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
-      string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
-      string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
-      string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
-#else /* SYSV */
-      string_initial(&sDefault.szQueuepausecommand, "disable %p");
-      string_initial(&sDefault.szQueueresumecommand, "enable %p");
+      string_set(&sDefault.szLpqcommand,"lpstat -o%p");
+      string_set(&sDefault.szLprmcommand,"cancel %p-%j");
+      string_set(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
+      string_set(&sDefault.szQueuepausecommand, "disable %p");
+      string_set(&sDefault.szQueueresumecommand, "enable %p");
+#ifndef HPUX
+      string_set(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
+      string_set(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
 #endif /* SYSV */
       break;
 
     case PRINT_QNX:
-      string_initial(&sDefault.szLpqcommand,"lpq -P%p");
-      string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
-      string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
+      string_set(&sDefault.szLpqcommand,"lpq -P%p");
+      string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
+      string_set(&sDefault.szPrintcommand,"lp -r -P%p %s");
       break;
 
     case PRINT_SOFTQ:
-      string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
-      string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
-      string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
-      string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
-      string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
+      string_set(&sDefault.szLpqcommand,"qstat -l -d%p");
+      string_set(&sDefault.szLprmcommand,"qstat -s -j%j -c");
+      string_set(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
+      string_set(&sDefault.szLppausecommand,"qstat -s -j%j -h");
+      string_set(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
       break;
       
     }
 }
 
+static TALLOC_CTX *lp_talloc;
 
 /******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
+free up temporary memory - called from the main loop
+********************************************************************/
+void lp_talloc_free(void)
+{
+       if (!lp_talloc) return;
+       talloc_destroy(lp_talloc);
+       lp_talloc = NULL;
+}
+
+/*******************************************************************
+convenience routine to grab string parameters into temporary memory
 and run standard_sub_basic on them. The buffers can be written to by
 callers without affecting the source string.
 ********************************************************************/
-static char *lp_user_string(const user_struct *vuser, char *s)
+static char *lp_user_string(const user_struct *vuser, const char *s)
 {
-  static char *bufs[10];
-  static int buflen[10];
-  static int next = -1;  
+       size_t len = s?strlen(s):0;
   char *ret;
-  int i;
-  int len = s?strlen(s):0;
 
-  if (next == -1) {
-    /* initialisation */
-    for (i=0;i<10;i++) {
-      bufs[i] = NULL;
-      buflen[i] = 0;
-    }
-    next = 0;
-  }
+       if (!lp_talloc) lp_talloc = talloc_init();
 
-  len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
-                                        substitution room */
-
-  if (buflen[next] != len) {
-    buflen[next] = len;
-    if (bufs[next])
-      free(bufs[next]);
-    bufs[next] = (char *)malloc(len);
-    if (!bufs[next]) {
-      DEBUG(0,("out of memory in lp_string()"));
-      exit(1);
-    }
-  } 
+       ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
 
-  ret = &bufs[next][0];
-  next = (next+1)%10;
+       if (!ret) return NULL;
 
   if (!s) 
     *ret = 0;
   else
-    StrCpy(ret,s);
+               StrnCpy(ret,s,len);
 
   trim_string(ret, "\"", "\"");
 
@@ -1217,61 +1266,26 @@ static char *lp_user_string(const user_struct *vuser, char *s)
   return(ret);
 }
 
-static TALLOC_CTX *lp_talloc;
-
-/******************************************************************* a
-free up temporary memory - called from the main loop
-********************************************************************/
-void lp_talloc_free(void)
-{
-       if (!lp_talloc) return;
-       talloc_destroy(lp_talloc);
-       lp_talloc = NULL;
-}
-
-/******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
+/*******************************************************************
+convenience routine to grab string parameters into temporary memory
 and run standard_sub_basic on them. The buffers can be written to by
 callers without affecting the source string.
 ********************************************************************/
-static char *lp_string(char *s)
+static char *lp_string(const char *s)
 {
-  static char *bufs[10];
-  static int buflen[10];
-  static int next = -1;  
+       size_t len = s?strlen(s):0;
   char *ret;
-  int i;
-  int len = s?strlen(s):0;
-
-  if (next == -1) {
-    /* initialisation */
-    for (i=0;i<10;i++) {
-      bufs[i] = NULL;
-      buflen[i] = 0;
-    }
-    next = 0;
-  }
 
-  len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
-                                        substitution room */
+       if (!lp_talloc) lp_talloc = talloc_init();
 
-  if (buflen[next] != len) {
-    buflen[next] = len;
-    if (bufs[next]) free(bufs[next]);
-    bufs[next] = (char *)malloc(len);
-    if (!bufs[next]) {
-      DEBUG(0,("out of memory in lp_string()"));
-      exit(1);
-    }
-  } 
+       ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
 
-  ret = &bufs[next][0];
-  next = (next+1)%10;
+       if (!ret) return NULL;
 
   if (!s) 
     *ret = 0;
   else
-    StrCpy(ret,s);
+               StrnCpy(ret,s,len);
 
   trim_string(ret, "\"", "\"");
 
@@ -1306,9 +1320,6 @@ static char *lp_string(char *s)
 #define FN_VUSER_STRING(fn_name,ptr) \
  char *fn_name(const user_struct *usr) {return(lp_user_string(usr, *(char **)(ptr) ? *(char **)(ptr) : ""));}
 
-struct vfs_options *lp_vfsoptions(int i) 
-{ return(LP_SNUM_OK(i) ? pSERVICE(i)->vfsOptions : sDefault.vfsOptions); }
-
 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
@@ -1324,9 +1335,14 @@ FN_GLOBAL_STRING(lp_smb_alias_file,&Globals.szSMBAliasFile)
 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
+#ifdef WITH_UTMP
+FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir)
+#endif /* WITH_UTMP */
 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
+FN_GLOBAL_STRING(lp_source_environment,&Globals.szSourceEnv)
 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
+FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
@@ -1345,7 +1361,6 @@ FN_GLOBAL_STRING(lp_ntusrname_map,&Globals.szNTusernameMap)
 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) 
 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync) 
 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
-FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook)
 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
@@ -1353,9 +1368,12 @@ static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
 FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
+FN_GLOBAL_STRING(lp_adduser_script,&Globals.szAddUserScript)
+FN_GLOBAL_STRING(lp_deluser_script,&Globals.szDelUserScript)
+FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook)
+
 FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms)
 FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile)
-FN_GLOBAL_STRING(lp_dfs_map,&Globals.szDfsMap)
 
 #if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
@@ -1424,8 +1442,9 @@ FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
 FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
 FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
+FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport)
 FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
-
+FN_GLOBAL_BOOL(lp_host_msdfs,&Globals.bHostMSDfs)
 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
@@ -1500,7 +1519,7 @@ FN_LOCAL_STRING(lp_force_group,force_group)
 FN_LOCAL_STRING(lp_readlist,readlist)
 FN_LOCAL_STRING(lp_writelist,writelist)
 FN_LOCAL_STRING(lp_fstype,fstype)
-FN_LOCAL_STRING(lp_vfsobj,vfsObjectFile)
+FN_LOCAL_STRING(lp_vfsobj,szVfsObjectFile)
 static FN_LOCAL_STRING(lp_volume,volume)
 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
@@ -1508,6 +1527,13 @@ FN_LOCAL_STRING(lp_hide_files,szHideFiles)
 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
 
+#ifdef MS_DFS
+FN_LOCAL_STRING(lp_dfsmap,szDfsMap)
+FN_LOCAL_BOOL(lp_dfsmap_loaded,bDfsMapLoaded)
+#endif
+
+FN_LOCAL_BOOL(lp_preexec_close,bPreexecClose)
+FN_LOCAL_BOOL(lp_rootpreexec_close,bRootpreexecClose)
 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
@@ -1526,8 +1552,12 @@ FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
 FN_LOCAL_BOOL(lp_locking,bLocking)
 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
+#ifdef WITH_UTMP
+FN_LOCAL_BOOL(lp_utmp,bUtmp)
+#endif
 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
+FN_LOCAL_BOOL(lp_level2_oplocks,bLevel2OpLocks)
 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
@@ -1542,15 +1572,22 @@ FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
 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_INTEGER(lp_create_mode,iCreate_mask)
+FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
-FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
+FN_LOCAL_INTEGER(_lp_security_mask,iSecurity_mask)
+FN_LOCAL_INTEGER(_lp_force_security_mode,iSecurity_force_mode)
+FN_LOCAL_INTEGER(lp_dir_mask,iDir_mask)
 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
+FN_LOCAL_INTEGER(_lp_dir_security_mask,iDir_Security_mask)
+FN_LOCAL_INTEGER(_lp_force_dir_security_mode,iDir_Security_force_mode)
 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
 FN_LOCAL_INTEGER(lp_printing,iPrinting)
+FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit)
+FN_LOCAL_INTEGER(lp_write_cache_size,iWriteCacheSize)
 
 FN_LOCAL_CHAR(lp_magicchar,magic_char)
 
@@ -1657,9 +1694,10 @@ static int add_a_service(service *pservice, char *name)
 
   init_service(pSERVICE(i));
   copy_service(pSERVICE(i),&tservice,NULL);
-  if (name)
+  if (name) {
     string_set(&iSERVICE(i).szService,name);  
-
+    unix_to_dos(iSERVICE(i).szService, True);
+  }
   return(i);
 }
 
@@ -2042,75 +2080,174 @@ BOOL lp_file_list_changed(void)
 }
 
 /***************************************************************************
-  handle the interpretation of the vfs object parameter
-  *************************************************************************/
-static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
+ Run standard_sub_basic on netbios name... needed because global_myname
+ is not accessed through any lp_ macro.
+ Note: We must *NOT* use string_set() here as ptr points to global_myname.
+***************************************************************************/
+
+static BOOL handle_netbios_name(char *pszParmValue,char **ptr)
 {
-    /* Set string value */
+       pstring netbios_name;
 
-    string_set(ptr,pszParmValue);
+       pstrcpy(netbios_name,pszParmValue);
 
-    /* Do any other initialisation required for vfs.  Note that
-       anything done here may have linking repercussions in nmbd. */
+       standard_sub_basic(netbios_name);
+       strupper(netbios_name);
 
-    return True;
+       /*
+        * Convert from UNIX to DOS string - the UNIX to DOS converter
+        * isn't called on the special handlers.
+        */
+       unix_to_dos(netbios_name, True);
+       pstrcpy(global_myname,netbios_name);
+
+       DEBUG(4,("handle_netbios_name: set global_myname to: %s\n", global_myname));
+
+       return(True);
 }
 
 /***************************************************************************
-  handle the interpretation of the vfs option parameter
- *************************************************************************/
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
+ Do the work of sourcing in environment variable/value pairs.
+***************************************************************************/
+
+static BOOL source_env(FILE *fenv)
 {
-    struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
-    int i;
+       pstring line;
+       char *varval;
+       size_t len;
+       char *p;
     
-    /* Create new vfs option */
+       while (!feof(fenv)) {
+               if (fgets(line, sizeof(line), fenv) == NULL)
+                       break;
 
-    new_option = (struct vfs_options *)malloc(sizeof(*new_option));
-    if (new_option == NULL) {
-       return False;
+               if(feof(fenv))
+                       break;
+
+               if((len = strlen(line)) == 0)
+                       continue;
+
+               if (line[len - 1] == '\n')
+                       line[--len] = '\0';
+
+               if ((varval=malloc(len+1)) == NULL) {
+                       DEBUG(0,("source_env: Not enough memory!\n"));
+                       return(False);
     }
 
-    ZERO_STRUCTP(new_option);
+               DEBUG(4,("source_env: Adding to environment: %s\n", line));
+               strncpy(varval, line, len);
+               varval[len] = '\0';
 
-    /* Get name and value */
+               p=strchr(line, (int) '=');
+               if (p == NULL) {
+                       DEBUG(4,("source_env: missing '=': %s\n", line));
+                       continue;
+               }
     
-    new_option->name = strtok(pszParmValue, "=");
+               if (putenv(varval)) {
+                       DEBUG(0,("source_env: Failed to put environment variable %s\n", varval ));
+                       continue;
+               }
 
-    if (new_option->name == NULL) {
-       return False;
+               *p='\0';
+               p++;
+               DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line)));
     }
 
-    while(isspace(*new_option->name)) {
-       new_option->name++;
+       DEBUG(4,("source_env: returning successfully\n"));
+       return(True);
     }
 
-    for (i = strlen(new_option->name); i > 0; i--) {
-       if (!isspace(new_option->name[i - 1])) break;
+/***************************************************************************
+ Handle the source environment operation
+***************************************************************************/
+
+static BOOL handle_source_env(char *pszParmValue,char **ptr)
+{
+       pstring fname;
+       char *p = fname;
+       FILE *env;
+       BOOL result;
+
+       pstrcpy(fname,pszParmValue);
+
+       standard_sub_basic(fname);
+
+       string_set(ptr,pszParmValue);
+
+       DEBUG(4, ("handle_source_env: checking env type\n"));
+
+       /*
+        * Filename starting with '|' means popen and read from stdin.
+        */
+
+       if (*p == '|') {
+
+               DEBUG(4, ("handle_source_env: source env from pipe\n"));
+               p++;
+
+               if ((env = sys_popen(p, "r", True)) == NULL) {
+                       DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) ));
+                       return(False);
     }
 
-    new_option->name[i] = '\0';
-    new_option->name = strdup(new_option->name);
+               DEBUG(4, ("handle_source_env: calling source_env()\n"));
+               result = source_env(env);
+               sys_pclose(env);
 
-    new_option->value = strtok(NULL, "=");
+       } else {
 
-    if (new_option->value != NULL) {
+               SMB_STRUCT_STAT st;
 
-       while(isspace(*new_option->value)) {
-           new_option->value++;
+               DEBUG(4, ("handle_source_env: source env from file %s\n", fname));
+               if ((env = sys_fopen(fname, "r")) == NULL) {
+                       DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) ));
+                       return(False);
        }
        
-       for (i = strlen(new_option->value); i > 0; i--) {
-           if (!isspace(new_option->value[i - 1])) break;
+               /*
+                * Ensure this file is owned by root and not writable by world.
+                */
+               if(fstat(fileno(env), &st) != 0) {
+                       DEBUG(0,("handle_source_env: Failed to stat file %s, Error was %s\n", fname, strerror(errno) ));
+                       fclose(env);
+                       return False;
        }
        
-       new_option->value[i] = '\0';
-       new_option->value = strdup(new_option->value);
+               if((st.st_uid != (uid_t)0) || (st.st_mode & S_IWOTH)) {
+                       DEBUG(0,("handle_source_env: unsafe to source env file %s. Not owned by root or world writable\n", fname ));
+                       fclose(env);
+                       return False;
     }
 
-    /* Add to list */
+               result=source_env(env);
+               fclose(env);
+       }
+       return(result);
+}
+
+
+
+#ifdef MS_DFS
+void set_dfsmap_loaded(int i,BOOL b)
+{
+  pSERVICE(i)->bDfsMapLoaded = b;
+}
+
+#endif
 
-    DLIST_ADD(*options, new_option);
+/***************************************************************************
+  handle the interpretation of the vfs object parameter
+  *************************************************************************/
+static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
+{
+    /* Set string value */
+
+    string_set(ptr,pszParmValue);
+
+    /* Do any other initialisation required for vfs.  Note that
+       anything done here may have linking repercussions in nmbd. */
 
     return True;
 }
@@ -2126,15 +2263,36 @@ static BOOL handle_coding_system(char *pszParmValue,char **ptr)
 }
 
 /***************************************************************************
- Handle the interpretation of the character set system parameter
+ Handle the interpretation of the character set system parameter.
 ***************************************************************************/
+
+static char *saved_character_set = NULL;
+
 static BOOL handle_character_set(char *pszParmValue,char **ptr)
 {
+    /* A dependency here is that the parameter client code page should be
+      set before this is called.
+    */
        string_set(ptr,pszParmValue);
-       interpret_character_set(pszParmValue);
+       strupper(*ptr);
+       saved_character_set = strdup(*ptr);
+       interpret_character_set(*ptr,lp_client_code_page());
        return(True);
 }
 
+/***************************************************************************
+ Handle the interpretation of the client code page parameter.
+ We handle this separately so that we can reset the character set
+ parameter in case this came before 'client code page' in the smb.conf.
+***************************************************************************/
+
+static BOOL handle_client_code_page(char *pszParmValue,char **ptr)
+{
+       Globals.client_code_page = atoi(pszParmValue);
+       if (saved_character_set != NULL)
+               interpret_character_set(saved_character_set,lp_client_code_page());     
+       return(True);
+}
 
 /***************************************************************************
 handle the valid chars lines
@@ -2232,7 +2390,7 @@ static void init_copymap(service *pservice)
   pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
   if (!pservice->copymap)
     DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS));
-
+  else
   for (i=0;i<NUMPARAMETERS;i++)
     pservice->copymap[i] = True;
 }
@@ -2326,19 +2484,27 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
 
      case P_STRING:
        string_set(parm_ptr,pszParmValue);
+       if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+           unix_to_dos(*(char **)parm_ptr, True);
        break;
 
      case P_USTRING:
        string_set(parm_ptr,pszParmValue);
+       if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+           unix_to_dos(*(char **)parm_ptr, True);
        strupper(*(char **)parm_ptr);
        break;
 
      case P_GSTRING:
        pstrcpy((char *)parm_ptr,pszParmValue);
+       if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+           unix_to_dos((char *)parm_ptr, True);
        break;
 
      case P_UGSTRING:
        pstrcpy((char *)parm_ptr,pszParmValue);
+       if (parm_table[parmnum].flags & FLAG_DOS_STRING)
+           unix_to_dos((char *)parm_ptr, True);
        strupper((char *)parm_ptr);
        break;
 
@@ -2350,8 +2516,7 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
                     }
             }
             break;
-
-     default:
+     case P_SEP:
             break;
      }
 
@@ -2407,7 +2572,7 @@ static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
                break;
       
        case P_OCTAL:
-               fprintf(f,"0%o",*(int *)ptr);
+               fprintf(f,"%s",octal_string(*(int *)ptr));
                break;
       
        case P_GSTRING:
@@ -2421,8 +2586,7 @@ static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
                if (*(char **)ptr)
                        fprintf(f,"%s",*(char **)ptr);
                break;
-
-       default:
+       case P_SEP:
                break;
        }
 }
@@ -2463,8 +2627,7 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
        if (p2 && !*p2) p2 = NULL;
        return(p1==p2 || strequal(p1,p2));
       }
-
-     default:
+     case P_SEP:
             break;
     }
   return(False);
@@ -2544,7 +2707,7 @@ static BOOL is_default(int i)
        case P_OCTAL:
        case P_ENUM:
                return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
-       default:
+       case P_SEP:
                break;
        }
        return False;
@@ -2792,13 +2955,57 @@ static void lp_save_defaults(void)
                case P_ENUM:
                        parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
                        break;
-               default:
+               case P_SEP:
                        break;
                }
        }
        defaults_saved = True;
 }
 
+/*******************************************************************
+ Set the server type we will announce as via nmbd.
+********************************************************************/
+static void set_server_role(void)
+{
+       server_role = ROLE_DOMAIN_NONE;
+
+       switch (lp_security())
+       {
+               case SEC_SHARE:
+               {
+                       if (lp_domain_logons())
+                       {
+                               DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
+                       }
+                       break;
+               }
+               case SEC_SERVER:
+               case SEC_DOMAIN:
+               {
+                       if (lp_domain_logons())
+                       {
+                               server_role = ROLE_DOMAIN_BDC;
+                               break;
+                       }
+                       server_role = ROLE_DOMAIN_MEMBER;
+                       break;
+               }
+               case SEC_USER:
+               {
+                       if (lp_domain_logons())
+                       {
+                               server_role = ROLE_DOMAIN_PDC;
+                               break;
+                       }
+                       break;
+               }
+               default:
+               {
+                       DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
+               }
+       }
+}
+
 
 /***************************************************************************
 Load the services array from the services file. Return True on success, 
@@ -2859,6 +3066,14 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
 }
 
 
+/***************************************************************************
+reset the max number of services
+***************************************************************************/
+void lp_resetnumservices(void)
+{
+  iNumServices = 0;
+}
+
 /***************************************************************************
 return the max number of services
 ***************************************************************************/
@@ -2870,7 +3085,7 @@ int lp_numservices(void)
 /***************************************************************************
 Display the contents of the services array in human-readable form.
 ***************************************************************************/
-void lp_dump(FILE *f, BOOL show_defaults)
+void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
 {
    int iService;
 
@@ -2882,15 +3097,8 @@ void lp_dump(FILE *f, BOOL show_defaults)
    
    dump_a_service(&sDefault, f);
 
-   for (iService = 0; iService < iNumServices; iService++)
-   {
-     if (VALID(iService))
-       {
-        if (iSERVICE(iService).szService[0] == '\0')
-          break;
-        dump_a_service(pSERVICE(iService), f);
-       }
-   }
+   for (iService = 0; iService < maxtoprint; iService++)
+     lp_dump_one(f, show_defaults, iService);
 }
 
 /***************************************************************************
@@ -2939,50 +3147,6 @@ char *volume_label(int snum)
 }
 
 
-/*******************************************************************
- Set the server type we will announce as via nmbd.
-********************************************************************/
-static void set_server_role(void)
-{
-       server_role = ROLE_DOMAIN_NONE;
-
-       switch (lp_security())
-       {
-               case SEC_SHARE:
-               {
-                       if (lp_domain_logons())
-                       {
-                               DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
-                       }
-                       break;
-               }
-               case SEC_SERVER:
-               case SEC_DOMAIN:
-               {
-                       if (lp_domain_logons())
-                       {
-                               server_role = ROLE_DOMAIN_BDC;
-                               break;
-                       }
-                       server_role = ROLE_DOMAIN_MEMBER;
-                       break;
-               }
-               case SEC_USER:
-               {
-                       if (lp_domain_logons())
-                       {
-                               server_role = ROLE_DOMAIN_PDC;
-                               break;
-                       }
-                       break;
-               }
-               default:
-               {
-                       DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
-               }
-       }
-}
-
 /*******************************************************************
  Set the server type we will announce as via nmbd.
 ********************************************************************/
@@ -3048,6 +3212,44 @@ static void set_default_server_announce_type(void)
        }
 }
 
+/***********************************************************
+ returns role of Samba server
+************************************************************/
+
+int lp_server_role(void)
+{
+  return server_role;
+}
+
+/***********************************************************
+ If we are PDC then prefer us as DMB
+************************************************************/
+
+BOOL lp_domain_master(void)
+{
+       if (Globals.bDomainMaster == Auto)
+       {
+               return (lp_server_role() == ROLE_DOMAIN_PDC);
+       }
+
+       return Globals.bDomainMaster;
+}
+
+/***********************************************************
+ If we are DMB then prefer us as LMB
+************************************************************/
+
+BOOL lp_preferred_master(void)
+{
+       if (Globals.bPreferredMaster == Auto)
+       {
+               return (lp_local_master() && lp_domain_master());
+       }
+
+       return Globals.bPreferredMaster;
+}
+
+
 
 /*******************************************************************
 remove a service
@@ -3168,40 +3370,40 @@ BOOL lp_kernel_oplocks(void)
 }
 
 /***********************************************************
- returns role of Samba server
+ Functions to return the current security masks/modes. If
+ set to -1 then return the create mask/mode instead.
 ************************************************************/
 
-int lp_server_role(void)
+int lp_security_mask(int snum)
 {
-  return server_role;
+  int val = _lp_security_mask(snum);
+  if(val == -1)
+    return lp_create_mask(snum);
+  return val;
 }
 
-/***********************************************************
- If we are PDC then prefer us as DMB
-************************************************************/
-
-BOOL lp_domain_master(void)
+int lp_force_security_mode(int snum)
 {
-       if (Globals.bDomainMaster == Auto)
-       {
-               return (lp_server_role() == ROLE_DOMAIN_PDC);
-       }
-
-       return Globals.bDomainMaster;
+  int val = _lp_force_security_mode(snum);
+  if(val == -1)
+    return lp_force_create_mode(snum);
+  return val;
 }
 
-/***********************************************************
- If we are DMB then prefer us as LMB
-************************************************************/
-
-BOOL lp_preferred_master(void)
+int lp_dir_security_mask(int snum)
 {
-       if (Globals.bPreferredMaster == Auto)
-       {
-               return (lp_local_master() && lp_domain_master());
-       }
+  int val = _lp_dir_security_mask(snum);
+  if(val == -1)
+    return lp_dir_mask(snum);
+  return val;
+}
 
-       return Globals.bPreferredMaster;
+int lp_force_dir_security_mode(int snum)
+{
+  int val = _lp_force_dir_security_mode(snum);
+  if(val == -1)
+    return lp_force_dir_mode(snum);
+  return val;
 }
 
 
index 74dd3d7a254830afb58035cac9d8972be48052c4..3ecdcdc92b3457d2dd6476d495f43a620006baf1 100644 (file)
@@ -157,28 +157,42 @@ static int EatComment( FILE *InFile )
   return( c );
   } /* EatComment */
 
+/*****************************************************************************
+ * Scan backards within a string to discover if the last non-whitespace
+ * character is a line-continuation character ('\\').
+ *
+ *  Input:  line  - A pointer to a buffer containing the string to be
+ *                  scanned.
+ *          pos   - This is taken to be the offset of the end of the
+ *                  string.  This position is *not* scanned.
+ *
+ *  Output: The offset of the '\\' character if it was found, or -1 to
+ *          indicate that it was not.
+ *
+ *****************************************************************************/
+
 static int Continuation( char *line, int pos )
-  /* ------------------------------------------------------------------------ **
-   * Scan backards within a string to discover if the last non-whitespace
-   * character is a line-continuation character ('\\').
-   *
-   *  Input:  line  - A pointer to a buffer containing the string to be
-   *                  scanned.
-   *          pos   - This is taken to be the offset of the end of the
-   *                  string.  This position is *not* scanned.
-   *
-   *  Output: The offset of the '\\' character if it was found, or -1 to
-   *          indicate that it was not.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
+{
+  int pos2 = 0;
+
   pos--;
   while( (pos >= 0) && isspace(line[pos]) )
      pos--;
 
-  return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
-  } /* Continuation */
+  /* we should recognize if `\` is part of a multibyte character or not. */
+  while(pos2 <= pos) {
+    size_t skip = 0;
+    skip = get_character_len(line[pos2]);
+    if (skip) {
+        pos2 += skip;
+    } else if (pos == pos2) {
+        return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
+    } else  {
+        pos2++;
+    }
+  }
+  return (-1);
+}
 
 
 static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
index af9d6be961b213ad27e2ea901773923583dde142..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
-*.lo
\ No newline at end of file
+.libs
+*.lo
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 3368206e2b021b818e6ff87782e792756f2fd1e8..88efba6563dfe163c3c8b834c8e5cc329b91648f 100644 (file)
@@ -230,7 +230,7 @@ int get_ntdrivers(fstring **list, char *architecture)
                {
                        DEBUGADD(7,("Found: [%s]\n", dpname));
                        
-                       StrCpy(driver_name, dpname+match_len);
+                       fstrcpy(driver_name, dpname+match_len);
                        all_string_sub(driver_name, "#", "/", 0);
                        *list = Realloc(*list, sizeof(fstring)*(total+1));
                        StrnCpy((*list)[total], driver_name, strlen(driver_name));
@@ -1331,7 +1331,7 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode)
  * should I init this ones ???
        nt_devmode->devicename
 */
-       StrCpy(nt_devmode->formname, "A4");
+       safe_strcpy(nt_devmode->formname, "A4", sizeof(nt_devmode->formname)-1);
 
        nt_devmode->specversion      = 0x0401;
        nt_devmode->driverversion    = 0x0400;
index 2b5231814d09acf188d25b630937589b9520030f..c33b7b3010b1a43c8bf33eac8c33866f76ddda45 100644 (file)
@@ -54,10 +54,9 @@ print file name. Return NULL on error, else the passed buffer pointer.
 static char *build_print_command(connection_struct *conn, const vuser_key *key,
                                int snum,
                                 char *command, 
-                                char *syscmd, char *filename1)
+                                char *syscmd, char *filename)
 {
        char *tstr;
-       pstring filename;
   
        /* get the print command for the service. */
        tstr = command;
@@ -75,13 +74,8 @@ static char *build_print_command(connection_struct *conn, const vuser_key *key,
                DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
        }
   
-       if (strstr(syscmd,"%s")) {
-               pstrcpy(filename,filename1);
-    
-               string_sub(syscmd, "%s", filename);
-       }
-  
-       string_sub(syscmd, "%f", filename1);
+               pstring_sub(syscmd, "%s", filename);
+       pstring_sub(syscmd, "%f", filename);
   
        /* Does the service have a printername? If not, make a fake
            and empty */
@@ -93,7 +87,7 @@ static char *build_print_command(connection_struct *conn, const vuser_key *key,
                tstr = SERVICE(snum);
        }
   
-       string_sub(syscmd, "%p", tstr);
+       pstring_sub(syscmd, "%p", tstr);
   
        {
                user_struct *vuser = get_valid_user_struct(key);
@@ -253,7 +247,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
     return(False);
 
   /* the Job and Total columns must be integer */
-  if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
+  if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False);
 
   buf->job = atoi(tok[JOBTOK]);
   buf->size = atoi(tok[TOTALTOK]);
@@ -276,6 +270,8 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
         break;
       }
     }
+    /* Ensure null termination. */
+    buf->file[sizeof(buf->file)-1] = '\0';
   }
 
 #ifdef PRIOTOK
@@ -346,7 +342,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
     return(False);
   }
 
-  if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) {
+  if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
     return(False);
   }
 
@@ -355,7 +351,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
 
   if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
     buf->status = LPQ_PRINTING;
-  } else if (isdigit(*tokarr[LPRNG_RANKTOK])) {
+  } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
     buf->status = LPQ_QUEUED;
   } else {
     buf->status = LPQ_PAUSED;
@@ -391,6 +387,8 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
         break;
       }
     }
+    /* Ensure null termination. */
+    buf->file[sizeof(buf->file)-1] = '\0';
   }
 
   return(True);
@@ -416,9 +414,9 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
   int count=0;
 
   /* handle the case of "(standard input)" as a filename */
-  string_sub(line,"standard input","STDIN");
-  all_string_sub(line,"(","\"", 0);
-  all_string_sub(line,")","\"", 0);
+  pstring_sub(line,"standard input","STDIN");
+  all_string_sub(line,"(","\"",0);
+  all_string_sub(line,")","\"",0);
 
   for (count=0; 
        count<10 && 
@@ -533,9 +531,9 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     }
     if (!header_line_ok) return (False); /* incorrect header line */
     /* handle the case of "(standard input)" as a filename */
-    string_sub(line,"standard input","STDIN");
-    all_string_sub(line,"(","\"", 0);
-    all_string_sub(line,")","\"", 0);
+    pstring_sub(line,"standard input","STDIN");
+    all_string_sub(line,"(","\"",0);
+    all_string_sub(line,")","\"",0);
     
     for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
     /* we must get 2 tokens */
@@ -571,7 +569,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
     else if (base_prio) base_prio_reset=False;
     
     /* handle the dash in the job id */
-    string_sub(line,"-"," ");
+    pstring_sub(line,"-"," ");
     
     for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
       
@@ -606,7 +604,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
 
 
 /****************************************************************************
-parse a lpq line
+parse a lpstat line
 
 here is an example of "lpstat -o dcslw" output under sysv
 
@@ -620,22 +618,43 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
   int count=0;
   char *p;
 
-  /* handle the dash in the job id */
-  string_sub(line,"-"," ");
+  /* 
+   * Handle the dash in the job id, but make sure that we skip over
+   * the printer name in case we have a dash in that.
+   * Patch from Dom.Mitchell@palmerharvey.co.uk.
+   */
   
-  for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+  /*
+   * Move to the first space.
+   */
+  for (p = line ; !isspace(*p) && *p; p++)
+    ;
+
+  /*
+   * Back up until the last '-' character or
+   * start of line.
+   */
+  for (; (p >= line) && (*p != '-'); p--)
+    ;
+
+  if((p >= line) && (*p == '-'))
+    *p = ' ';
+
+  for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++)
+    ;
 
   /* we must get 7 tokens */
   if (count < 7)
     return(False);
 
   /* the 2nd and 4th, 6th columns must be integer */
-  if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False);
-  if (!isdigit((int)*tok[5])) return(False);
+  if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3]))
+    return(False);
+  if (!isdigit((int)*tok[5]))
+    return(False);
 
   /* if the user contains a ! then trim the first part of it */  
-  if ((p=strchr(tok[2],'!')))
-    {
+  if ((p=strchr(tok[2],'!'))) {
       fstring tmp;
       fstrcpy(tmp,p+1);
       fstrcpy(tok[2],tmp);
@@ -675,14 +694,14 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
   DEBUG(4,("antes [%s]\n", line));
 
   /* handle the case of "-- standard input --" as a filename */
-  string_sub(line,"standard input","STDIN");
+  pstring_sub(line,"standard input","STDIN");
   DEBUG(4,("despues [%s]\n", line));
-  all_string_sub(line,"-- ","\"", 0);
-  all_string_sub(line," --","\"", 0);
+  all_string_sub(line,"-- ","\"",0);
+  all_string_sub(line," --","\"",0);
   DEBUG(4,("despues 1 [%s]\n", line));
 
-  string_sub(line,"[job #","");
-  string_sub(line,"]","");
+  pstring_sub(line,"[job #","");
+  pstring_sub(line,"]","");
   DEBUG(4,("despues 2 [%s]\n", line));
 
   
@@ -738,9 +757,9 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
   int count=0;
 
   /* handle the case of "(standard input)" as a filename */
-  string_sub(line,"stdin","STDIN");
-  all_string_sub(line,"(","\"", 0);
-  all_string_sub(line,")","\"", 0);
+  pstring_sub(line,"stdin","STDIN");
+  all_string_sub(line,"(","\"",0);
+  all_string_sub(line,")","\"",0);
   
   for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
 
@@ -808,7 +827,7 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
   int count=0;
 
   /* mung all the ":"s to spaces*/
-  string_sub(line,":"," ");
+  pstring_sub(line,":"," ");
   
   for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
 
@@ -852,8 +871,8 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
     t->tm_mon  = atoi(tok[count+2]+3);
     switch (*tok[count+2])
     {
-    case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break;
-    default:                t->tm_year = atoi(tok[count+2]) + 2000; break;
+    case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
+    default:                t->tm_year = atoi(tok[count+2]); break;
     }
 
     t->tm_hour = atoi(tok[count+3]);
@@ -925,6 +944,14 @@ static BOOL parse_lpq_entry(int snum,char *line,
     if (p) *p = 0;
   }
 
+  /* in the LPRNG case, we skip lines starting by a space.*/
+  if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) )
+  {
+       if (line[0]==' ')
+               return ret;
+  }
+
+
   if (status && !ret)
     {
       /* a few simple checks to see if the line might be a
@@ -995,7 +1022,7 @@ int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
        }
     
        pstrcpy(syscmd,lpq_command);
-       string_sub(syscmd,"%p",printername);
+       pstring_sub(syscmd,"%p",printername);
 
        {
                user_struct *vuser = get_valid_user_struct(key);
@@ -1038,7 +1065,7 @@ int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
                        break;
                }
 
-               memset((char *)&(*queue)[count], 0, sizeof(**queue));
+               memset((char *)&(*queue)[count],'\0',sizeof(**queue));
          
                /* parse it */
                if (!parse_lpq_entry(snum,line,
@@ -1089,8 +1116,8 @@ void del_printqueue(connection_struct *conn,const vuser_key *key,
   slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
 
   pstrcpy(syscmd,lprm_command);
-  string_sub(syscmd,"%p",printername);
-  string_sub(syscmd,"%j",jobstr);
+  pstring_sub(syscmd,"%p",printername);
+  pstring_sub(syscmd,"%j",jobstr);
        {
                user_struct *vuser = get_valid_user_struct(key);
                standard_sub(conn, vuser, syscmd);
@@ -1132,8 +1159,8 @@ void status_printjob(connection_struct *conn,const vuser_key *key,
   slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
 
   pstrcpy(syscmd,lpstatus_command);
-  string_sub(syscmd,"%p",printername);
-  string_sub(syscmd,"%j",jobstr);
+  pstring_sub(syscmd,"%p",printername);
+  pstring_sub(syscmd,"%j",jobstr);
        {
                user_struct *vuser = get_valid_user_struct(key);
                standard_sub(conn, vuser, syscmd);
@@ -1192,20 +1219,20 @@ uint32 status_printqueue(connection_struct *conn,const vuser_key *key,
   }
 
   pstrcpy(syscmd,queuestatus_command);
-  string_sub(syscmd,"%p",printername);
+  pstring_sub(syscmd,"%p",printername);
        {
                user_struct *vuser = get_valid_user_struct(key);
                standard_sub(conn, vuser, syscmd);
                vuid_free_user_struct(vuser);
        }
 
+       return ret == 0 ? 0x0 : NT_STATUS_INVALID_PARAMETER;
+
 
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
   lpq_reset(snum); /* queue has changed */
-
-       return ret == 0 ? 0x0 : NT_STATUS_INVALID_PARAMETER;
 }
 
 
index af9d6be961b213ad27e2ea901773923583dde142..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
-*.lo
\ No newline at end of file
+.libs
+*.lo
index af9d6be961b213ad27e2ea901773923583dde142..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
-*.lo
\ No newline at end of file
+.libs
+*.lo
index 46daaedfe5b9155dc2e79e1e087766689ae343ce..eb223c9c7bc6754cc20cc61f70585bb05b88d58d 100644 (file)
@@ -32,18 +32,19 @@ extern int DEBUGLEVEL;
 /*******************************************************************
 makes a DOM_CLNT_SRV structure.
 ********************************************************************/
-static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
-                               const char *logon_srv, 
-                               const char *comp_name)
+static BOOL make_clnt_srv(DOM_CLNT_SRV * log,
+                         const char *logon_srv, const char *comp_name)
 {
-       if (log == NULL) return False;
+       if (log == NULL)
+               return False;
 
-       DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
+       DEBUG(5, ("make_clnt_srv: %d\n", __LINE__));
 
        if (logon_srv != NULL)
        {
                log->undoc_buffer = 1;
-               make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
+               make_unistr2(&(log->uni_logon_srv), logon_srv,
+                            strlen(logon_srv) + 1);
        }
        else
        {
@@ -53,7 +54,8 @@ static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
        if (comp_name != NULL)
        {
                log->undoc_buffer2 = 1;
-               make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+               make_unistr2(&(log->uni_comp_name), comp_name,
+                            strlen(comp_name) + 1);
        }
        else
        {
@@ -66,19 +68,22 @@ static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
 /*******************************************************************
 reads or writes a DOM_CLNT_SRV structure.
 ********************************************************************/
-static BOOL smb_io_clnt_srv(char *desc,  DOM_CLNT_SRV *log, prs_struct *ps, int depth)
+static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV * log, prs_struct *ps,
+                           int depth)
 {
-       if (log == NULL) return False;
+       if (log == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_clnt_srv");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer ));
+
+       prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer));
        if (log->undoc_buffer != 0)
        {
-               smb_io_unistr2("unistr2", &(log->uni_logon_srv), log->undoc_buffer, ps, depth);
+               smb_io_unistr2("unistr2", &(log->uni_logon_srv),
+                              log->undoc_buffer, ps, depth);
        }
 
        prs_align(ps);
@@ -86,7 +91,8 @@ static BOOL smb_io_clnt_srv(char *desc,  DOM_CLNT_SRV *log, prs_struct *ps, int
        prs_uint32("undoc_buffer2", ps, depth, &(log->undoc_buffer2));
        if (log->undoc_buffer2 != 0)
        {
-               smb_io_unistr2("unistr2", &(log->uni_comp_name), log->undoc_buffer2, ps, depth);
+               smb_io_unistr2("unistr2", &(log->uni_comp_name),
+                              log->undoc_buffer2, ps, depth);
        }
 
        return True;
@@ -95,22 +101,23 @@ static BOOL smb_io_clnt_srv(char *desc,  DOM_CLNT_SRV *log, prs_struct *ps, int
 /*******************************************************************
 makes a DOM_LOG_INFO structure.
 ********************************************************************/
-BOOL make_log_info(DOM_LOG_INFO *log,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name)
+BOOL make_log_info(DOM_LOG_INFO * log,
+                  const char *logon_srv, const char *acct_name,
+                  uint16 sec_chan, const char *comp_name)
 {
-       if (log == NULL) return False;
+       if (log == NULL)
+               return False;
 
-       DEBUG(5,("make_log_info %d\n", __LINE__));
+       DEBUG(5, ("make_log_info %d\n", __LINE__));
 
        log->undoc_buffer = 1;
 
-       make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
-       make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name)+1);
+       make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv) + 1);
+       make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name) + 1);
 
        log->sec_chan = sec_chan;
 
-       make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+       make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name) + 1);
 
        return True;
 }
@@ -118,15 +125,17 @@ BOOL make_log_info(DOM_LOG_INFO *log,
 /*******************************************************************
 reads or writes a DOM_LOG_INFO structure.
 ********************************************************************/
-BOOL smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps, int depth)
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO * log, prs_struct *ps,
+                    int depth)
 {
-       if (log == NULL) return False;
+       if (log == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_log_info");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
 
        smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
@@ -142,25 +151,18 @@ BOOL smb_io_log_info(char *desc,  DOM_LOG_INFO *log, prs_struct *ps, int depth)
 /*******************************************************************
 makes a DOM_CLNT_INFO2 structure.
 ********************************************************************/
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
-                               const char *logon_srv, const char *comp_name,
-                               DOM_CRED *clnt_cred)
+BOOL make_clnt_info2(DOM_CLNT_INFO2 * clnt,
+                    const char *logon_srv, const char *comp_name,
+                    DOM_CRED * clnt_cred)
 {
-       if (clnt == NULL) return False;
+       if (clnt == NULL)
+               return False;
 
-       DEBUG(5,("make_clnt_info: %d\n", __LINE__));
+       DEBUG(5, ("make_clnt_info: %d\n", __LINE__));
 
        make_clnt_srv(&(clnt->login), logon_srv, comp_name);
 
-       if (clnt_cred != NULL)
-       {
-               clnt->ptr_cred = 1;
-               memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
-       }
-       else
-       {
-               clnt->ptr_cred = 0;
-       }
+       clnt->ptr_cred = Memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
 
        return True;
 }
@@ -168,21 +170,23 @@ BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
 /*******************************************************************
 reads or writes a DOM_CLNT_INFO2 structure.
 ********************************************************************/
-BOOL smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 * clnt, prs_struct *ps,
+                      int depth)
 {
-       if (clnt == NULL) return False;
+       if (clnt == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_clnt_info2");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_clnt_srv("", &(clnt->login), ps, depth);
 
        prs_align(ps);
-       
+
        prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
-       smb_io_cred    ("", &(clnt->cred ), ps, depth);
+       smb_io_cred("", &(clnt->cred), ps, depth);
 
        return True;
 }
@@ -190,17 +194,18 @@ BOOL smb_io_clnt_info2(char *desc,  DOM_CLNT_INFO2 *clnt, prs_struct *ps, int de
 /*******************************************************************
 makes a DOM_CLNT_INFO structure.
 ********************************************************************/
-BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
-               const char *logon_srv, const char *acct_name,
-               uint16 sec_chan, const char *comp_name,
-                               DOM_CRED *cred)
+BOOL make_clnt_info(DOM_CLNT_INFO * clnt,
+                   const char *logon_srv, const char *acct_name,
+                   uint16 sec_chan, const char *comp_name, DOM_CRED * cred)
 {
-       if (clnt == NULL || cred == NULL) return False;
+       if (clnt == NULL || cred == NULL)
+               return False;
 
-       DEBUG(5,("make_clnt_info\n"));
+       DEBUG(5, ("make_clnt_info\n"));
 
-       make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan, comp_name);
-       memcpy(&(clnt->cred), cred, sizeof(clnt->cred));
+       make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan,
+                     comp_name);
+       Memcpy(&clnt->cred, cred, sizeof(clnt->cred));
 
        return True;
 }
@@ -208,17 +213,19 @@ BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
 /*******************************************************************
 reads or writes a DOM_CLNT_INFO structure.
 ********************************************************************/
-BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO * clnt, prs_struct *ps,
+                     int depth)
 {
-       if (clnt == NULL) return False;
+       if (clnt == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_clnt_info");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_log_info("", &(clnt->login), ps, depth);
-       smb_io_cred    ("", &(clnt->cred ), ps, depth);
+       smb_io_cred("", &(clnt->cred), ps, depth);
 
        return True;
 }
@@ -226,20 +233,14 @@ BOOL smb_io_clnt_info(char *desc,  DOM_CLNT_INFO *clnt, prs_struct *ps, int dept
 /*******************************************************************
 makes an OWF_INFO structure.
 ********************************************************************/
-BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16])
+BOOL make_owf_info(OWF_INFO * hash, const uint8 data[16])
 {
-       if (hash == NULL) return False;
+       if (hash == NULL)
+               return False;
 
-       DEBUG(5,("make_owf_info: %d\n", __LINE__));
-       
-       if (data != NULL)
-       {
-               memcpy(hash->data, data, sizeof(hash->data));
-       }
-       else
-       {
-               ZERO_STRUCT(hash->data);
-       }
+       DEBUG(5, ("make_owf_info: %d\n", __LINE__));
+
+       Memcpy(hash->data, data, sizeof(hash->data));
 
        return True;
 }
@@ -247,16 +248,17 @@ BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16])
 /*******************************************************************
 reads or writes an OWF_INFO structure.
 ********************************************************************/
-BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
+BOOL smb_io_owf_info(char *desc, OWF_INFO * hash, prs_struct *ps, int depth)
 {
-       if (hash == NULL) return False;
+       if (hash == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_owf_info");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint8s (False, "data", ps, depth, hash->data, 16);
+
+       prs_uint8s(False, "data", ps, depth, hash->data, 16);
 
        return True;
 }
@@ -264,7 +266,7 @@ BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-static BOOL net_io_neg_flags(char *desc, NEG_FLAGS * neg, prs_struct * ps,
+static BOOL net_io_neg_flags(char *desc, NEG_FLAGS * neg, prs_struct *ps,
                             int depth)
 {
        if (neg == NULL)
@@ -284,7 +286,7 @@ static BOOL net_io_neg_flags(char *desc, NEG_FLAGS * neg, prs_struct * ps,
 reads or writes a NETLOGON_INFO_3 structure.
 ********************************************************************/
 static BOOL net_io_netinfo_3(char *desc, NETLOGON_INFO_3 * info,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -310,7 +312,7 @@ static BOOL net_io_netinfo_3(char *desc, NETLOGON_INFO_3 * info,
 reads or writes a NETLOGON_INFO_1 structure.
 ********************************************************************/
 static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 * info,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -330,7 +332,7 @@ static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 * info,
 reads or writes a NETLOGON_INFO_2 structure.
 ********************************************************************/
 static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 * info,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -385,7 +387,7 @@ BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 * q_l,
 reads or writes an NET_Q_LOGON_CTRL2 structure.
 ********************************************************************/
 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 * q_l,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (q_l == NULL)
                return False;
@@ -420,7 +422,7 @@ BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
 
        r_l->switch_value = switch_value;       /* should only be 0x1 */
        r_l->status = status;
-       memcpy(&(r_l->logon), logon_info, sizeof(NETLOGON_INFO));
+       Memcpy(&r_l->logon, logon_info, sizeof(NETLOGON_INFO));
 
        if (status == NT_STATUS_NOPROBLEMO)
        {
@@ -438,7 +440,7 @@ BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 * r_l,
 reads or writes an NET_R_LOGON_CTRL2 structure.
 ********************************************************************/
 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (r_l == NULL)
                return False;
@@ -490,7 +492,7 @@ BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 * r_l,
 reads or writes an NET_R_TRUST_DOM_LIST structure.
 ********************************************************************/
 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (r_t == NULL)
                return False;
@@ -511,7 +513,7 @@ BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST * r_t,
 reads or writes an NET_Q_TRUST_DOM_LIST structure.
 ********************************************************************/
 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST * q_l,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (q_l == NULL)
                return False;
@@ -557,7 +559,7 @@ BOOL make_q_req_chal(NET_Q_REQ_CHAL * q_c,
 /*******************************************************************
 reads or writes an NET_Q_REQ_CHAL structure.
 ********************************************************************/
-BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct *ps,
                       int depth)
 {
        int old_align;
@@ -579,7 +581,7 @@ BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
        ps->align = 0;
 
        smb_io_unistr2("logon_clnt", &(q_c->uni_logon_clnt), True, ps, depth);
-       smb_io_chal("clnt_chal", &(q_c->clnt_chal), ps, depth); 
+       smb_io_chal("clnt_chal", &(q_c->clnt_chal), ps, depth);
 
        ps->align = old_align;
 
@@ -589,7 +591,7 @@ BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL * q_c, prs_struct * ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct * ps,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL * r_c, prs_struct *ps,
                       int depth)
 {
        if (r_c == NULL)
@@ -631,7 +633,7 @@ BOOL make_q_auth(NET_Q_AUTH * q_a,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth)
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct *ps, int depth)
 {
        int old_align;
        if (q_a == NULL)
@@ -655,7 +657,7 @@ BOOL net_io_q_auth(char *desc, NET_Q_AUTH * q_a, prs_struct * ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct * ps, int depth)
+BOOL net_io_r_auth(char *desc, NET_R_AUTH * r_a, prs_struct *ps, int depth)
 {
        if (r_a == NULL)
                return False;
@@ -697,7 +699,7 @@ BOOL make_q_auth_2(NET_Q_AUTH_2 * q_a,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct *ps,
                     int depth)
 {
        int old_align;
@@ -723,7 +725,7 @@ BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 * q_a, prs_struct * ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct * ps,
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 * r_a, prs_struct *ps,
                     int depth)
 {
        if (r_a == NULL)
@@ -767,7 +769,7 @@ BOOL make_q_srv_pwset(NET_Q_SRV_PWSET * q_s,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct *ps,
                        int depth)
 {
        if (q_s == NULL)
@@ -787,7 +789,7 @@ BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET * q_s, prs_struct * ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct * ps,
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET * r_s, prs_struct *ps,
                        int depth)
 {
        if (r_s == NULL)
@@ -922,7 +924,7 @@ BOOL make_id_info1(NET_ID_INFO_1 * id, const char *domain_name,
 /*******************************************************************
 reads or writes an NET_ID_INFO_1 structure.
 ********************************************************************/
-static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 * id, prs_struct * ps,
+static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 * id, prs_struct *ps,
                            int depth)
 {
        if (id == NULL)
@@ -1013,7 +1015,7 @@ BOOL make_id_info4(NET_ID_INFO_4 * id, const char *domain_name,
 /*******************************************************************
 reads or writes an NET_ID_INFO_4 structure.
 ********************************************************************/
-static BOOL net_io_id_info4(char *desc, NET_ID_INFO_4 * id, prs_struct * ps,
+static BOOL net_io_id_info4(char *desc, NET_ID_INFO_4 * id, prs_struct *ps,
                            int depth)
 {
        if (id == NULL)
@@ -1131,7 +1133,7 @@ BOOL make_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
 /*******************************************************************
 reads or writes an NET_ID_INFO_2 structure.
 ********************************************************************/
-static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 * id, prs_struct * ps,
+static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 * id, prs_struct *ps,
                            int depth)
 {
        if (id == NULL)
@@ -1193,16 +1195,8 @@ BOOL make_sam_info(DOM_SAM_INFO * sam,
 
        make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
 
-       if (rtn_cred != NULL)
-       {
-               sam->ptr_rtn_cred = 1;
-               memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
-       }
-       else
-       {
-               sam->ptr_rtn_cred = 0;
-       }
-
+       sam->ptr_rtn_cred =
+               Memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
        sam->logon_level = logon_level;
        sam->ctr = ctr;
 
@@ -1213,7 +1207,7 @@ BOOL make_sam_info(DOM_SAM_INFO * sam,
 reads or writes a DOM_SAM_INFO structure.
 ********************************************************************/
 static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR * ctr,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (ctr == NULL)
                return False;
@@ -1257,7 +1251,7 @@ static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR * ctr,
 /*******************************************************************
 reads or writes a DOM_SAM_INFO structure.
 ********************************************************************/
-static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO * sam, prs_struct * ps,
+static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO * sam, prs_struct *ps,
                            int depth)
 {
        if (sam == NULL)
@@ -1293,12 +1287,12 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -1307,9 +1301,9 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
-                         const char *padding, const DOM_SID * dom_sid)
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
+                         const char *padding, const DOM_SID *dom_sid)
 {
        /* only cope with one "other" sid, right now. */
        /* need to count the number of space-delimited sids */
@@ -1350,26 +1344,14 @@ BOOL make_net_user_info2W(NET_USER_INFO_2 * usr,
        usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
        usr->user_flgs = user_flgs;
 
-       if (sess_key != NULL)
-       {
-               memcpy(usr->user_sess_key, sess_key,
-                      sizeof(usr->user_sess_key));
-       }
-       else
-       {
-               ZERO_STRUCT(usr->user_sess_key);
-       }
+       Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
 
        make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
        make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
 
        usr->buffer_dom_id = dom_sid ? 1 : 0;   /* yes, put a domain SID in */
 
-       ZERO_STRUCT(usr->padding);
-       if (padding != NULL)
-       {
-               memcpy(usr->padding, padding, 8);
-       }
+       Memcpy(usr->padding, padding, sizeof(usr->padding));
 
        copy_unistr2(&(usr->uni_user_name), user_name);
        copy_unistr2(&(usr->uni_full_name), full_name);
@@ -1421,7 +1403,7 @@ BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
                         uint32 user_flgs,
                         char sess_key[16],
                         char *logon_srv,
-                        char *logon_dom, char *padding, DOM_SID * dom_sid)
+                        char *logon_dom, char *padding, DOM_SID *dom_sid)
 {
        /* only cope with one "other" sid, right now. */
        /* need to count the number of space-delimited sids */
@@ -1460,26 +1442,14 @@ BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
        usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
        usr->user_flgs = user_flgs;
 
-       if (sess_key != NULL)
-       {
-               memcpy(usr->user_sess_key, sess_key,
-                      sizeof(usr->user_sess_key));
-       }
-       else
-       {
-               ZERO_STRUCT(usr->user_sess_key);
-       }
+       Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
 
        make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
        make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
 
        usr->buffer_dom_id = dom_sid ? 1 : 0;   /* yes, we're bothering to put a domain SID in */
 
-       ZERO_STRUCT(usr->padding);
-       if (padding != NULL)
-       {
-               memcpy(usr->padding, padding, 8);
-       }
+       Memcpy(usr->padding, padding, sizeof(usr->padding));
 
        make_unistr2(&(usr->uni_user_name), user_name, len_user_name);
        make_unistr2(&(usr->uni_full_name), full_name, len_full_name);
@@ -1512,7 +1482,7 @@ BOOL make_net_user_info2(NET_USER_INFO_2 * usr,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
+BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct *ps,
                       int depth)
 {
        uint32 i;
@@ -1600,7 +1570,7 @@ BOOL net_io_user_info2(char *desc, NET_USER_INFO_2 * usr, prs_struct * ps,
  net_user_info_3_copy_from_ctr
  *************************************************************************/
 BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
-               const NET_USER_INFO_CTR *ctr)
+                                  const NET_USER_INFO_CTR * ctr)
 {
        ZERO_STRUCTP(usr);
        if (ctr->ptr_user_info == 0)
@@ -1613,30 +1583,30 @@ BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
                {
                        const NET_USER_INFO_2 *usr2 = ctr->usr.id2;
                        if (!make_net_user_info3W(usr,
-                                         &usr2->logon_time,
-                                         &usr2->logoff_time,
-                                         &usr2->kickoff_time,
-                                         &usr2->pass_last_set_time,
-                                         &usr2->pass_can_change_time,
-                                         &usr2->pass_must_change_time,
-                                         &usr2->uni_user_name,
-                                         &usr2->uni_full_name,
-                                         &usr2->uni_logon_script,
-                                         &usr2->uni_profile_path,
-                                         &usr2->uni_home_dir,
-                                         &usr2->uni_dir_drive,
-                                         usr2->logon_count,
-                                         usr2->bad_pw_count,
-                                         usr2->user_id,
-                                         usr2->group_id,
-                                         usr2->num_groups,
-                                         usr2->gids,
-                                         usr2->user_flgs,
-                                         usr2->user_sess_key,
-                                         &usr2->uni_logon_srv,
-                                         &usr2->uni_logon_dom,
-                                         usr2->padding,
-                                         &usr2->dom_sid.sid, NULL))
+                                                 &usr2->logon_time,
+                                                 &usr2->logoff_time,
+                                                 &usr2->kickoff_time,
+                                                 &usr2->pass_last_set_time,
+                                                 &usr2->pass_can_change_time,
+                                                 &usr2->
+                                                 pass_must_change_time,
+                                                 &usr2->uni_user_name,
+                                                 &usr2->uni_full_name,
+                                                 &usr2->uni_logon_script,
+                                                 &usr2->uni_profile_path,
+                                                 &usr2->uni_home_dir,
+                                                 &usr2->uni_dir_drive,
+                                                 usr2->logon_count,
+                                                 usr2->bad_pw_count,
+                                                 usr2->user_id,
+                                                 usr2->group_id,
+                                                 usr2->num_groups,
+                                                 usr2->gids, usr2->user_flgs,
+                                                 usr2->user_sess_key,
+                                                 &usr2->uni_logon_srv,
+                                                 &usr2->uni_logon_dom,
+                                                 usr2->padding,
+                                                 &usr2->dom_sid.sid, NULL))
                        {
                                return False;
                        }
@@ -1649,7 +1619,7 @@ BOOL net_user_info_3_copy_from_ctr(NET_USER_INFO_3 * usr,
                }
                default:
                {
-                       DEBUG(0,("invalid NET_USER_INFO_X info class\n"));
+                       DEBUG(0, ("invalid NET_USER_INFO_X info class\n"));
                        return False;
                }
        }
@@ -1666,12 +1636,12 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const NTTIME * pass_last_set_time,
                          const NTTIME * pass_can_change_time,
                          const NTTIME * pass_must_change_time,
-                         const UNISTR2 * user_name,
-                         const UNISTR2 * full_name,
-                         const UNISTR2 * log_scr,
-                         const UNISTR2 * prof_path,
-                         const UNISTR2 * home_dir,
-                         const UNISTR2 * dir_drive,
+                         const UNISTR2 *user_name,
+                         const UNISTR2 *full_name,
+                         const UNISTR2 *log_scr,
+                         const UNISTR2 *prof_path,
+                         const UNISTR2 *home_dir,
+                         const UNISTR2 *dir_drive,
                          uint16 logon_count,
                          uint16 bad_pw_count,
                          uint32 user_id,
@@ -1680,10 +1650,10 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
                          const DOM_GID * gids,
                          uint32 user_flgs,
                          const char sess_key[16],
-                         const UNISTR2 * logon_srv,
-                         const UNISTR2 * logon_dom,
+                         const UNISTR2 *logon_srv,
+                         const UNISTR2 *logon_dom,
                          const char *padding,
-                         const DOM_SID * dom_sid, const char *other_sids)
+                         const DOM_SID *dom_sid, const char *other_sids)
 {
        /* only cope with one "other" sid, right now. */
        /* need to count the number of space-delimited sids */
@@ -1725,26 +1695,14 @@ BOOL make_net_user_info3W(NET_USER_INFO_3 * usr,
        usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
        usr->user_flgs = user_flgs;
 
-       if (sess_key != NULL)
-       {
-               memcpy(usr->user_sess_key, sess_key,
-                      sizeof(usr->user_sess_key));
-       }
-       else
-       {
-               ZERO_STRUCT(usr->user_sess_key);
-       }
+       Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
 
        make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
        make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
 
        usr->buffer_dom_id = dom_sid ? 1 : 0;   /* yes, put a domain SID in */
 
-       ZERO_STRUCT(usr->padding);
-       if (padding != NULL)
-       {
-               memcpy(usr->padding, padding, 8);
-       }
+       Memcpy(usr->padding, padding, sizeof(usr->padding));
 
        num_other_sids =
                make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
@@ -1803,7 +1761,7 @@ BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
                         char sess_key[16],
                         char *logon_srv,
                         char *logon_dom,
-                        char *padding, DOM_SID * dom_sid, char *other_sids)
+                        char *padding, DOM_SID *dom_sid, char *other_sids)
 {
        /* only cope with one "other" sid, right now. */
        /* need to count the number of space-delimited sids */
@@ -1843,26 +1801,14 @@ BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
        usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
        usr->user_flgs = user_flgs;
 
-       if (sess_key != NULL)
-       {
-               memcpy(usr->user_sess_key, sess_key,
-                      sizeof(usr->user_sess_key));
-       }
-       else
-       {
-               ZERO_STRUCT(usr->user_sess_key);
-       }
+       Memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
 
        make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
        make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
 
        usr->buffer_dom_id = dom_sid ? 1 : 0;   /* yes, we're bothering to put a domain SID in */
 
-       ZERO_STRUCT(usr->padding);
-       if (padding != NULL)
-       {
-               memcpy(usr->padding, padding, 8);
-       }
+       Memcpy(usr->padding, padding, sizeof(usr->padding));
 
        num_other_sids =
                make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
@@ -1901,7 +1847,7 @@ BOOL make_net_user_info3(NET_USER_INFO_3 * usr,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct *ps,
                       int depth)
 {
        uint32 i;
@@ -1919,7 +1865,8 @@ BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
        smb_io_time("kickoff_time", &(usr->kickoff_time), ps, depth);   /* kickoff time */
        smb_io_time("pass_last_set_time", &(usr->pass_last_set_time), ps, depth);       /* password last set time */
        smb_io_time("pass_can_change_time", &(usr->pass_can_change_time), ps, depth);   /* password can change time */
-       smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
+       smb_io_time("pass_must_change_time", &(usr->pass_must_change_time),
+                   ps, depth); /* password must change time */
 
        smb_io_unihdr("hdr_user_name", &(usr->hdr_user_name), ps, depth);       /* username unicode string header */
        smb_io_unihdr("hdr_full_name", &(usr->hdr_full_name), ps, depth);       /* user's full name unicode string header */
@@ -1998,7 +1945,7 @@ BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 * usr, prs_struct * ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON * q_l, prs_struct *ps,
                        int depth)
 {
        if (q_l == NULL)
@@ -2020,8 +1967,7 @@ makes a NET_R_SAM_LOGON structure.
 ********************************************************************/
 BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
                      const DOM_CRED * srv_creds,
-                     uint16 switch_value,
-                     void *id, uint32 status)
+                     uint16 switch_value, void *id, uint32 status)
 {
        if (r_s == NULL)
                return False;
@@ -2041,7 +1987,7 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
                if (id != NULL)
                {
                        r_s->ctr.ptr_user_info = 1;
-                       r_s->ctr.switch_value = switch_value;   
+                       r_s->ctr.switch_value = switch_value;
                }
                else
                {
@@ -2070,7 +2016,7 @@ BOOL make_r_sam_logon(NET_R_SAM_LOGON * r_s,
 reads or writes a structure.
 ********************************************************************/
 BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (ctr == NULL)
                return False;
@@ -2090,7 +2036,8 @@ BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
                        {
                                if (UNMARSHALLING(ps))
                                {
-                                       ctr->usr.id2 = g_new(NET_USER_INFO_2, 1);
+                                       ctr->usr.id2 =
+                                               g_new(NET_USER_INFO_2, 1);
                                }
                                if (ctr->usr.id == NULL)
                                {
@@ -2104,7 +2051,8 @@ BOOL net_io_user_info_ctr(char *desc, NET_USER_INFO_CTR * ctr,
                        {
                                if (UNMARSHALLING(ps))
                                {
-                                       ctr->usr.id3 = g_new(NET_USER_INFO_3, 1);
+                                       ctr->usr.id3 =
+                                               g_new(NET_USER_INFO_3, 1);
                                }
                                if (ctr->usr.id == NULL)
                                {
@@ -2143,7 +2091,7 @@ void free_net_user_info_ctr(NET_USER_INFO_CTR * ctr)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct *ps,
                        int depth)
 {
        if (r_l == NULL)
@@ -2153,11 +2101,11 @@ BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
        depth++;
 
        prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds);
-       smb_io_cred("", &(r_l->srv_creds), ps, depth);  
+       smb_io_cred("", &(r_l->srv_creds), ps, depth);
 
        net_io_user_info_ctr("", &r_l->ctr, ps, depth);
 
-       prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp); 
+       prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp);
        prs_uint32("status      ", ps, depth, &r_l->status);
 
        prs_align(ps);
@@ -2168,7 +2116,7 @@ BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON * r_l, prs_struct * ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct * ps,
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF * q_l, prs_struct *ps,
                         int depth)
 {
        if (q_l == NULL)
@@ -2217,7 +2165,7 @@ BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF * r_s,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct * ps,
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF * r_l, prs_struct *ps,
                         int depth)
 {
        if (r_l == NULL)
@@ -2266,7 +2214,7 @@ BOOL make_q_sam_sync(NET_Q_SAM_SYNC * q_s,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct * ps,
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
                       int depth)
 {
        if (q_s == NULL)
@@ -2313,7 +2261,7 @@ BOOL make_sam_delta_hdr(SAM_DELTA_HDR * delta, uint16 type, uint32 rid)
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        if (delta == NULL)
                return False;
@@ -2335,7 +2283,7 @@ static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
-                                  prs_struct * ps, int depth)
+                                  prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -2375,7 +2323,7 @@ static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -2403,17 +2351,17 @@ static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
 makes a SAM_ACCOUNT_INFO structure.
 ********************************************************************/
 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name,
                           uint32 user_rid, uint32 group_rid,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * desc,
+                          const UNISTR2 *home_dir,
+                          const UNISTR2 *dir_drive,
+                          const UNISTR2 *log_scr,
+                          const UNISTR2 *desc,
                           uint32 acb_info,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str, const UNISTR2 * mung_dial)
+                          const UNISTR2 *prof_path,
+                          const UNISTR2 *wkstas,
+                          const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
 {
        int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
        int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
@@ -2483,7 +2431,7 @@ BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
-                                  prs_struct * ps, int depth)
+                                  prs_struct *ps, int depth)
 {
        if (pwd == NULL)
                return False;
@@ -2509,7 +2457,7 @@ static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
-                                   SAM_ACCOUNT_INFO * info, prs_struct * ps,
+                                   SAM_ACCOUNT_INFO * info, prs_struct *ps,
                                    int depth)
 {
        BUFHDR2 hdr_priv_data;
@@ -2645,7 +2593,7 @@ static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
-                                     prs_struct * ps, int depth)
+                                     prs_struct *ps, int depth)
 {
        uint32 i;
        fstring tmp;
@@ -2705,7 +2653,7 @@ static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        if (info == NULL)
                return False;
@@ -2733,7 +2681,7 @@ static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
 reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
-                                     prs_struct * ps, int depth)
+                                     prs_struct *ps, int depth)
 {
        uint32 i;
        fstring tmp;
@@ -2788,7 +2736,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
                                 SAM_DELTA_CTR * delta, uint16 type,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        if (delta == NULL)
                return False;
@@ -2876,7 +2824,7 @@ BOOL make_r_sam_sync(NET_R_SAM_SYNC * r_s,
 reads or writes a structure.
 ********************************************************************/
 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
-                      NET_R_SAM_SYNC * r_s, prs_struct * ps, int depth)
+                      NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
 {
        uint32 i;
 
index 43ad697afa53aa9ef0ba43b9a6c80449efba1b6b..6b716aa98ff7d2ab620654b634f4470a3ec8a78e 100644 (file)
@@ -31,7 +31,7 @@ extern int DEBUGLEVEL;
 /*******************************************************************
 checks an RPC_HDR_AUTH structure.
 ********************************************************************/
-BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai)
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH * rai)
 {
        return (rai->auth_type == 0x44 && rai->auth_level == 0x06);
 }
@@ -39,11 +39,11 @@ BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai)
 /*******************************************************************
 creates an RPC_AUTH_NETSEC_NEG structure.
 ********************************************************************/
-BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
-                               fstring domain,
-                               fstring myname)
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG * neg,
+                             fstring domain, fstring myname)
 {
-       if (neg == NULL) return False;
+       if (neg == NULL)
+               return False;
 
        fstrcpy(neg->domain, domain);
        fstrcpy(neg->myname, myname);
@@ -57,15 +57,17 @@ reads or writes an RPC_AUTH_NETSEC_NEG structure.
 *** lkclXXXX HACK ALERT! ***
 
 ********************************************************************/
-BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG * neg,
+                               prs_struct *ps, int depth)
 {
-       if (neg == NULL) return False;
+       if (neg == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_neg");
        depth++;
 
-       prs_string("domain", ps, depth, neg->domain, 0, sizeof(neg->domain)); 
-       prs_string("myname", ps, depth, neg->myname, 0, sizeof(neg->myname)); 
+       prs_string("domain", ps, depth, neg->domain, 0, sizeof(neg->domain));
+       prs_string("myname", ps, depth, neg->myname, 0, sizeof(neg->myname));
 
        return True;
 }
@@ -77,11 +79,12 @@ creates an RPC_AUTH_NETSEC_RESP structure.
 *** lkclXXXX the actual offset is at the start of the auth verifier    ***
 
 ********************************************************************/
-BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags)
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP * rsp, uint32 flags)
 {
-       DEBUG(5,("make_rpc_auth_netsec_resp\n"));
+       DEBUG(5, ("make_rpc_auth_netsec_resp\n"));
 
-       if (rsp == NULL) return False;
+       if (rsp == NULL)
+               return False;
 
        rsp->flags = flags;
 
@@ -95,14 +98,16 @@ reads or writes an RPC_AUTH_NETSEC_RESP structure.
 *** lkclXXXX the actual offset is at the start of the auth verifier    ***
 
 ********************************************************************/
-BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP * rsp,
+                                prs_struct *ps, int depth)
 {
-       if (rsp == NULL) return False;
+       if (rsp == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_resp");
        depth++;
 
-       prs_uint32("flags", ps, depth, &rsp->flags); 
+       prs_uint32("flags", ps, depth, &rsp->flags);
 
        return True;
 }
@@ -110,7 +115,7 @@ BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_stru
 /*******************************************************************
 checks an RPC_AUTH_NETSEC_CHK structure.
 ********************************************************************/
-BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk)
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk)
 {
        static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
 
@@ -129,30 +134,18 @@ BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk)
 /*******************************************************************
 creates an RPC_AUTH_NETSEC_CHK structure.
 ********************************************************************/
-BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
-                               const uchar sig[8],
-                               const uchar data1[8],
-                               const uchar data3[8],
-                               const uchar data8[8])
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+                             const uchar sig[8],
+                             const uchar data1[8],
+                             const uchar data3[8], const uchar data8[8])
 {
-       if (chk == NULL) return False;
+       if (chk == NULL)
+               return False;
 
-       if (sig != NULL)
-       {
-               memcpy(chk->sig  , sig  , sizeof(chk->sig  ));
-       }
-       if (data1 != NULL)
-       {
-               memcpy(chk->data1, data1, sizeof(chk->data1));
-       }
-       if (data3 != NULL)
-       {
-               memcpy(chk->data3, data3, sizeof(chk->data3));
-       }
-       if (data8 != NULL)
-       {
-               memcpy(chk->data8, data8, sizeof(chk->data8));
-       }
+       Memcpy(chk->sig, sig, sizeof(chk->sig));
+       Memcpy(chk->data1, data1, sizeof(chk->data1));
+       Memcpy(chk->data3, data3, sizeof(chk->data3));
+       Memcpy(chk->data8, data8, sizeof(chk->data8));
 
        return True;
 }
@@ -160,14 +153,16 @@ BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
 /*******************************************************************
 reads or writes an RPC_AUTH_NETSEC_CHK structure.
 ********************************************************************/
-BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth)
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK * chk,
+                               prs_struct *ps, int depth)
 {
-       if (chk == NULL) return False;
+       if (chk == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk");
        depth++;
 
-       prs_uint8s(False, "sig  ", ps, depth, chk->sig  , sizeof(chk->sig  ));
+       prs_uint8s(False, "sig  ", ps, depth, chk->sig, sizeof(chk->sig));
        prs_uint8s(False, "data3", ps, depth, chk->data3, sizeof(chk->data3));
        prs_uint8s(False, "data1", ps, depth, chk->data1, sizeof(chk->data1));
        prs_uint8s(False, "data8", ps, depth, chk->data8, sizeof(chk->data8));
@@ -175,55 +170,54 @@ BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct
        return True;
 }
 
-static void netsechash(uchar *key, uchar *data, int data_len)
+static void netsechash(uchar * key, uchar * data, int data_len)
 {
-  uchar hash[256];
-  uchar index_i = 0;
-  uchar index_j = 0;
-  uchar j = 0;
-  int ind;
-
-  for (ind = 0; ind < 256; ind++)
-  {
-    hash[ind] = (uchar)ind;
-  }
-
-  for( ind = 0; ind < 256; ind++)
-  {
-     uchar tc;
-
-     j += (hash[ind] + key[ind%16]);
-
-     tc = hash[ind];
-     hash[ind] = hash[j];
-     hash[j] = tc;
-  }
-
-  for( ind = 0; ind < data_len; ind++)
-  {
-    uchar tc;
-    uchar t;
-
-    index_i++;
-    index_j += hash[index_i];
-
-    tc = hash[index_i];
-    hash[index_i] = hash[index_j];
-    hash[index_j] = tc;
-
-    t = hash[index_i] + hash[index_j];
-    data[ind] ^= hash[t];
-  }
+       uchar hash[256];
+       uchar index_i = 0;
+       uchar index_j = 0;
+       uchar j = 0;
+       int ind;
+
+       for (ind = 0; ind < 256; ind++)
+       {
+               hash[ind] = (uchar) ind;
+       }
+
+       for (ind = 0; ind < 256; ind++)
+       {
+               uchar tc;
+
+               j += (hash[ind] + key[ind % 16]);
+
+               tc = hash[ind];
+               hash[ind] = hash[j];
+               hash[j] = tc;
+       }
+
+       for (ind = 0; ind < data_len; ind++)
+       {
+               uchar tc;
+               uchar t;
+
+               index_i++;
+               index_j += hash[index_i];
+
+               tc = hash[index_i];
+               hash[index_i] = hash[index_j];
+               hash[index_j] = tc;
+
+               t = hash[index_i] + hash[index_j];
+               data[ind] ^= hash[t];
+       }
 }
 
 
 BOOL netsec_encode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len)
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
 {
        char dataN[4];
-       char digest1[16]; 
-       struct MD5Context ctx3; 
+       char digest1[16];
+       struct MD5Context ctx3;
        uchar sess_kf0[16];
        int i;
 
@@ -242,12 +236,12 @@ BOOL netsec_encode(struct netsec_auth_struct *a,
        MD5Update(&ctx3, dataN, 0x4);
        MD5Update(&ctx3, verf->sig, 8);
 
-       MD5Update(&ctx3, verf->data8, 8); 
+       MD5Update(&ctx3, verf->data8, 8);
 
        dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
        dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
 
-       hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+       hmac_md5(sess_kf0, dataN, 0x4, digest1);
        dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
        hmac_md5(digest1, verf->data3, 8, digest1);
        dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
@@ -256,7 +250,7 @@ BOOL netsec_encode(struct netsec_auth_struct *a,
        dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
 
        dump_data_pw("data   :\n", data, data_len);
-       MD5Update(&ctx3, data, data_len); 
+       MD5Update(&ctx3, data, data_len);
 
        {
                char digest_tmp[16];
@@ -268,10 +262,10 @@ BOOL netsec_encode(struct netsec_auth_struct *a,
                memcpy(verf->data1, digest2, sizeof(verf->data1));
        }
 
-       netsechash(digest1, data , data_len);
+       netsechash(digest1, data, data_len);
        dump_data_pw("data:\n", data, data_len);
 
-       hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+       hmac_md5(a->sess_key, dataN, 0x4, digest1);
        dump_data_pw("ctx:\n", digest1, sizeof(digest1));
 
        hmac_md5(digest1, verf->data1, 8, digest1);
@@ -282,17 +276,15 @@ BOOL netsec_encode(struct netsec_auth_struct *a,
        netsechash(digest1, verf->data3, 8);
        dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
 
-
        return True;
 }
 
 BOOL netsec_decode(struct netsec_auth_struct *a,
-                               RPC_AUTH_NETSEC_CHK *verf,
-                               char *data, size_t data_len)
+                  RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
 {
        char dataN[4];
-       char digest1[16]; 
-       struct MD5Context ctx3; 
+       char digest1[16];
+       struct MD5Context ctx3;
        uchar sess_kf0[16];
        int i;
 
@@ -306,7 +298,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a,
 
        dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
        dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
-       hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+       hmac_md5(a->sess_key, dataN, 0x4, digest1);
        dump_data_pw("ctx:\n", digest1, sizeof(digest1));
 
        hmac_md5(digest1, verf->data1, 8, digest1);
@@ -322,7 +314,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a,
 
        dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
 
-       hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+       hmac_md5(sess_kf0, dataN, 0x4, digest1);
        dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
        hmac_md5(digest1, verf->data3, 8, digest1);
        dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
@@ -330,13 +322,13 @@ BOOL netsec_decode(struct netsec_auth_struct *a,
        dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
        netsechash(digest1, verf->data8, 8);
        dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8));
-       MD5Update(&ctx3, verf->data8, 8); 
+       MD5Update(&ctx3, verf->data8, 8);
 
        dump_data_pw("data   :\n", data, data_len);
-       netsechash(digest1, data , data_len);
+       netsechash(digest1, data, data_len);
        dump_data_pw("datadec:\n", data, data_len);
 
-       MD5Update(&ctx3, data, data_len); 
+       MD5Update(&ctx3, data, data_len);
        {
                char digest_tmp[16];
                MD5Final(digest_tmp, &ctx3);
index 08f2e9e62f10236940a2657642f1f0f5dbaff286..214fc2d73c613ef7bb90453c9b33ac041c8bdf79 100644 (file)
@@ -606,8 +606,7 @@ BOOL prs_set_offset(prs_struct *ps, uint32 offset)
 
 void prs_mem_free(prs_struct *ps)
 {
-       if (ps->data)
-               free(ps->data);
+       safe_free(ps->data);
        ps->data = NULL;
        ps->offset = 0;
 }
@@ -780,8 +779,8 @@ BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct * ps, int depth,
                return False;
        }
 
-       DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s,
-                    len) ps->offset = end_offset;
+       DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len);
+       ps->offset = end_offset;
 
        return True;
 }
@@ -890,7 +889,8 @@ BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct * ps, int depth,
        }
 
        DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
-                    str->buffer, str->buf_len) ps->offset = end_offset;
+                    str->buffer, str->buf_len);
+       ps->offset = end_offset;
 
        return True;
 }
@@ -927,7 +927,8 @@ BOOL _prs_string2(BOOL charmode, char *name, prs_struct * ps, int depth,
        }
 
        DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q,
-                    str->buffer, str->str_str_len) ps->offset = end_offset;
+                    str->buffer, str->str_str_len);
+       ps->offset = end_offset;
 
        return True;
 }
index db0294dc621c8a71ee5810f1515db442789f80fa..74aec8b24dc731f423f9222a5078e83099b81625 100644 (file)
@@ -31,12 +31,12 @@ extern int DEBUGLEVEL;
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
-                               uint16 unknown_0, uint32 level)
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR * q_o,
+                         uint16 unknown_0, uint32 level)
 {
        q_o->ptr = 1;
        q_o->unknown_0 = unknown_0;
-       q_o->unknown_1 = 0x0; /* random - changes */
+       q_o->unknown_1 = 0x0;   /* random - changes */
        q_o->level = level;
 
        return True;
@@ -45,21 +45,23 @@ BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_open_hkcr(char *desc,  REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR * r_q, prs_struct *ps,
+                       int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint32("ptr      ", ps, depth, &(r_q->ptr      ));
+
+       prs_uint32("ptr      ", ps, depth, &(r_q->ptr));
        if (r_q->ptr != 0)
        {
                prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
                prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
-               prs_uint32("level    ", ps, depth, &(r_q->level    ));
+               prs_uint32("level    ", ps, depth, &(r_q->level));
        }
 
        return True;
@@ -69,15 +71,17 @@ BOOL reg_io_q_open_hkcr(char *desc,  REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int d
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_open_hkcr(char *desc,  REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR * r_r, prs_struct *ps,
+                       int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_r->pol), ps, depth);
 
        prs_uint32("status", ps, depth, &(r_r->status));
@@ -89,12 +93,12 @@ BOOL reg_io_r_open_hkcr(char *desc,  REG_R_OPEN_HKCR *r_r, prs_struct *ps, int d
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
-                               uint16 unknown_0, uint32 access_mask)
+BOOL make_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->unknown_1 = 0x0;   /* random - changes */
        q_o->access_mask = access_mask;
 
        return True;
@@ -103,16 +107,18 @@ BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_open_hklm(char *desc,  REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+                       int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint32("ptr      ", ps, depth, &(r_q->ptr      ));
+
+       prs_uint32("ptr      ", ps, depth, &(r_q->ptr));
        if (r_q->ptr != 0)
        {
                prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
@@ -127,15 +133,17 @@ BOOL reg_io_q_open_hklm(char *desc,  REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int d
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_open_hklm(char *desc,  REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+                       int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_r->pol), ps, depth);
 
        prs_uint32("status", ps, depth, &(r_r->status));
@@ -147,9 +155,9 @@ BOOL reg_io_r_open_hklm(char *desc,  REG_R_OPEN_HKLM *r_r, prs_struct *ps, int d
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY * q_u, POLICY_HND *pol)
 {
-       memcpy(&(q_u->pol), pol, sizeof(q_u->pol));
+       q_u->pol = *pol;
 
        return True;
 }
@@ -157,15 +165,17 @@ BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_flush_key(char *desc,  REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY * r_q, prs_struct *ps,
+                       int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_flush_key");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pol), ps, depth);
 
        return True;
@@ -175,15 +185,17 @@ BOOL reg_io_q_flush_key(char *desc,  REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int d
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_flush_key(char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY * r_r, prs_struct *ps,
+                       int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_flush_key");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_r->status));
 
        return True;
@@ -192,8 +204,8 @@ BOOL reg_io_r_flush_key(char *desc,  REG_R_FLUSH_KEY *r_r, prs_struct *ps, int d
 /*******************************************************************
 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)
        {
@@ -207,11 +219,13 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
                }
                if (ptr3 == NULL || *ptr3 != 0)
                {
-                       sec_io_desc_buf("data   ", data   , ps, depth);
+                       sec_io_desc_buf("data   ", data, ps, depth);
                }
                smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
-                                  data->max_len, data->len);
-               ps->offset = old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
+                                  data->max_len, data->len);
+               ps->offset =
+                       old_offset + data->len +
+                       sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
                prs_align(ps);
        }
 
@@ -222,18 +236,18 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
-                               char *key_name, char *key_class,
-                               SEC_ACCESS *sam_access,
-                               SEC_DESC_BUF *sec_buf,
-                               int sec_len, SEC_DESC *sec)
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY * q_c, POLICY_HND *hnd,
+                          char *key_name, char *key_class,
+                          SEC_ACCESS * sam_access,
+                          SEC_DESC_BUF * sec_buf,
+                          int sec_len, SEC_DESC * sec)
 {
-       int len_name  = key_name  != NULL ? strlen(key_name ) + 1: 0;
-       int len_class = key_class != NULL ? strlen(key_class) + 1: 0;
+       int len_name = key_name != NULL ? strlen(key_name) + 1 : 0;
+       int len_class = key_class != NULL ? strlen(key_class) + 1 : 0;
 
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+       q_c->pnt_pol = *hnd;
 
        make_uni_hdr(&(q_c->hdr_name), len_name);
        make_unistr2(&(q_c->uni_name), key_name, len_name);
@@ -242,7 +256,7 @@ BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
        make_unistr2(&(q_c->uni_class), key_class, len_class);
 
        q_c->reserved = 0x00000000;
-       memcpy(&(q_c->sam_access), sam_access, sizeof(q_c->sam_access));
+       q_c->sam_access = *sam_access;
 
        q_c->ptr1 = 1;
        q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
@@ -261,23 +275,26 @@ BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_create_key(char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY * r_q, prs_struct *ps,
+                        int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_create_key");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
 
-       smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
        smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
        prs_align(ps);
 
-       smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
-       smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_class), ps, depth);
+       smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("reserved", ps, depth, &(r_q->reserved));
@@ -290,7 +307,8 @@ BOOL reg_io_q_create_key(char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *ps, int
        }
 
        prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
-       reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth);
+       reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps,
+                         depth);
 
        prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
 
@@ -301,15 +319,17 @@ BOOL reg_io_q_create_key(char *desc,  REG_Q_CREATE_KEY *r_q, prs_struct *ps, int
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_create_key(char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY * r_r, prs_struct *ps,
+                        int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_create_key");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_r->key_pol), ps, depth);
        prs_uint32("unknown", ps, depth, &(r_r->unknown));
 
@@ -322,13 +342,13 @@ BOOL reg_io_r_create_key(char *desc,  REG_R_CREATE_KEY *r_r, prs_struct *ps, int
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
-                               char *name)
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE * q_c, POLICY_HND *hnd,
+                          char *name)
 {
-       int len_name  = name  != NULL ? strlen(name ) + 1: 0;
+       int len_name = name != NULL ? strlen(name) + 1 : 0;
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+       q_c->pnt_pol = *hnd;
 
        make_uni_hdr(&(q_c->hdr_name), len_name);
        make_unistr2(&(q_c->uni_name), name, len_name);
@@ -339,18 +359,20 @@ BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_delete_val(char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE * r_q, prs_struct *ps,
+                        int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_delete_val");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
 
-       smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
        smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
        prs_align(ps);
 
@@ -361,15 +383,17 @@ BOOL reg_io_q_delete_val(char *desc,  REG_Q_DELETE_VALUE *r_q, prs_struct *ps, i
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_delete_val(char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE * r_r, prs_struct *ps,
+                        int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_delete_val");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_r->status));
 
        return True;
@@ -379,13 +403,13 @@ BOOL reg_io_r_delete_val(char *desc,  REG_R_DELETE_VALUE *r_r, prs_struct *ps, i
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
-                               char *name)
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY * q_c, POLICY_HND *hnd,
+                          char *name)
 {
-       int len_name  = name  != NULL ? strlen(name ) + 1: 0;
+       int len_name = name != NULL ? strlen(name) + 1 : 0;
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+       q_c->pnt_pol = *hnd;
 
        make_uni_hdr(&(q_c->hdr_name), len_name);
        make_unistr2(&(q_c->uni_name), name, len_name);
@@ -396,18 +420,20 @@ BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_delete_key(char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY * r_q, prs_struct *ps,
+                        int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_delete_key");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
 
-       smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
        smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
        prs_align(ps);
 
@@ -418,15 +444,17 @@ BOOL reg_io_q_delete_key(char *desc,  REG_Q_DELETE_KEY *r_q, prs_struct *ps, int
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_delete_key(char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY * r_r, prs_struct *ps,
+                        int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_delete_key");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_r->status));
 
        return True;
@@ -436,12 +464,12 @@ BOOL reg_io_r_delete_key(char *desc,  REG_R_DELETE_KEY *r_r, prs_struct *ps, int
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
-                               uint32 max_class_len)
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY * q_o, POLICY_HND *hnd,
+                         uint32 max_class_len)
 {
        ZERO_STRUCTP(q_o);
 
-       memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+       q_o->pol = *hnd;
        q_o->hdr_class.uni_str_len = 0;
        q_o->hdr_class.uni_max_len = max_class_len * 2;
        q_o->hdr_class.buffer = max_class_len > 0 ? 1 : 0;
@@ -453,18 +481,21 @@ BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_query_key(char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY * r_q, prs_struct *ps,
+                       int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_query_key");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pol), ps, depth);
-       smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
-       smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_class), ps, depth);
+       smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps,
+                      depth);
 
        prs_align(ps);
 
@@ -475,29 +506,32 @@ BOOL reg_io_q_query_key(char *desc,  REG_Q_QUERY_KEY *r_q, prs_struct *ps, int d
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_query_key(char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY * r_r, prs_struct *ps,
+                       int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_query_key");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_unihdr ("", &(r_r->hdr_class), ps, depth);
-       smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps, depth);
+
+       smb_io_unihdr("", &(r_r->hdr_class), ps, depth);
+       smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps,
+                      depth);
 
        prs_align(ps);
 
-       prs_uint32("num_subkeys   ", ps, depth, &(r_r->num_subkeys   ));
-       prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen ));
+       prs_uint32("num_subkeys   ", ps, depth, &(r_r->num_subkeys));
+       prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen));
        prs_uint32("mak_subkeysize", ps, depth, &(r_r->max_subkeysize));
-       prs_uint32("num_values    ", ps, depth, &(r_r->num_values    ));
+       prs_uint32("num_values    ", ps, depth, &(r_r->num_values));
        prs_uint32("max_valnamelen", ps, depth, &(r_r->max_valnamelen));
        prs_uint32("max_valbufsize", ps, depth, &(r_r->max_valbufsize));
-       prs_uint32("sec_desc      ", ps, depth, &(r_r->sec_desc      ));
+       prs_uint32("sec_desc      ", ps, depth, &(r_r->sec_desc));
        smb_io_time("mod_time     ", &(r_r->mod_time), ps, depth);
-       
+
        prs_uint32("status", ps, depth, &(r_r->status));
 
        return True;
@@ -507,9 +541,9 @@ BOOL reg_io_r_query_key(char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps, int d
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A * q_o, POLICY_HND *hnd)
 {
-       memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+       q_o->pol = *hnd;
 
        return True;
 }
@@ -517,15 +551,17 @@ BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_unk_1a(char *desc,  REG_Q_UNK_1A *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A * r_q, prs_struct *ps,
+                    int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_unk_1a");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pol), ps, depth);
 
        return True;
@@ -535,17 +571,19 @@ BOOL reg_io_q_unk_1a(char *desc,  REG_Q_UNK_1A *r_q, prs_struct *ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_unk_1a(char *desc,  REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A * r_r, prs_struct *ps,
+                    int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_unk_1a");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("unknown", ps, depth, &(r_r->unknown));
-       prs_uint32("status" , ps, depth, &(r_r->status ));
+       prs_uint32("status", ps, depth, &(r_r->status));
 
        return True;
 }
@@ -554,12 +592,11 @@ BOOL reg_io_r_unk_1a(char *desc,  REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
-                               uint16 unknown_0, uint32 level)
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU * q_o, uint16 unknown_0, uint32 level)
 {
        q_o->ptr = 1;
        q_o->unknown_0 = unknown_0;
-       q_o->unknown_1 = 0x0; /* random - changes */
+       q_o->unknown_1 = 0x0;   /* random - changes */
        q_o->level = level;
 
        return True;
@@ -568,21 +605,23 @@ BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_open_hku(char *desc,  REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU * r_q, prs_struct *ps,
+                      int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_open_hku");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint32("ptr      ", ps, depth, &(r_q->ptr      ));
+
+       prs_uint32("ptr      ", ps, depth, &(r_q->ptr));
        if (r_q->ptr != 0)
        {
                prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
                prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
-               prs_uint32("level    ", ps, depth, &(r_q->level    ));
+               prs_uint32("level    ", ps, depth, &(r_q->level));
        }
 
        return True;
@@ -592,15 +631,17 @@ BOOL reg_io_q_open_hku(char *desc,  REG_Q_OPEN_HKU *r_q, prs_struct *ps, int dep
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_open_hku(char *desc,  REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU * r_r, prs_struct *ps,
+                      int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_open_hku");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_r->pol), ps, depth);
 
        prs_uint32("status", ps, depth, &(r_r->status));
@@ -612,13 +653,14 @@ BOOL reg_io_r_open_hku(char *desc,  REG_R_OPEN_HKU *r_r, prs_struct *ps, int dep
 /*******************************************************************
 makes an REG_Q_CLOSE structure.
 ********************************************************************/
-BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_reg_q_close(REG_Q_CLOSE * q_c, POLICY_HND *hnd)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_reg_q_close\n"));
+       DEBUG(5, ("make_reg_q_close\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
 
        return True;
 }
@@ -626,16 +668,17 @@ BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_close(char *desc,  REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
+BOOL reg_io_q_close(char *desc, REG_Q_CLOSE * q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_close");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->pol), ps, depth);
        prs_align(ps);
 
        return True;
@@ -644,16 +687,17 @@ BOOL reg_io_q_close(char *desc,  REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_close(char *desc,  REG_R_CLOSE *r_u, prs_struct *ps, int depth)
+BOOL reg_io_r_close(char *desc, REG_R_CLOSE * r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_close");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(r_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(r_u->pol), ps, depth);
        prs_align(ps);
 
        prs_uint32("status", ps, depth, &(r_u->status));
@@ -664,13 +708,14 @@ BOOL reg_io_r_close(char *desc,  REG_R_CLOSE *r_u, prs_struct *ps, int depth)
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
-                               uint32 sec_info,
-                               uint32 buf_len, SEC_DESC *sec_desc)
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC * q_i, POLICY_HND *pol,
+                           uint32 sec_info,
+                           uint32 buf_len, SEC_DESC * sec_desc)
 {
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        q_i->sec_info = sec_info;
 
@@ -684,21 +729,24 @@ BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_set_key_sec(char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth); 
+
+       smb_io_pol_hnd("", &(r_q->pol), ps, depth);
 
        prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
-       prs_uint32("ptr    ", ps, depth, &(r_q->ptr    ));
+       prs_uint32("ptr    ", ps, depth, &(r_q->ptr));
 
-       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps,
+                         depth);
 
        return True;
 }
@@ -706,15 +754,17 @@ BOOL reg_io_q_set_key_sec(char *desc,  REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, i
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_q->status));
 
        return True;
@@ -724,13 +774,14 @@ BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, in
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, 
-                               uint32 sec_info,
-                               uint32 buf_len, SEC_DESC_BUF *sec_buf)
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC * q_i, POLICY_HND *pol,
+                           uint32 sec_info,
+                           uint32 buf_len, SEC_DESC_BUF * sec_buf)
 {
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        q_i->sec_info = sec_info;
 
@@ -749,21 +800,24 @@ BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_get_key_sec(char *desc,  REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_get_key_sec");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth); 
+
+       smb_io_pol_hnd("", &(r_q->pol), ps, depth);
 
        prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
-       prs_uint32("ptr     ", ps, depth, &(r_q->ptr     ));
+       prs_uint32("ptr     ", ps, depth, &(r_q->ptr));
 
-       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps,
+                         depth);
 
        return True;
 }
@@ -772,35 +826,37 @@ BOOL reg_io_q_get_key_sec(char *desc,  REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, i
 /*******************************************************************
 makes a structure.
 ********************************************************************/
- void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol, 
-                               uint32 buf_len, uint8 *buf,
-                               uint32 status)
+void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC * r_i, POLICY_HND *pol,
+                           uint32 buf_len, uint8 *buf, uint32 status)
 {
-       if (r_i == NULL) return False;
+       if (r_i == NULL)
+               return False;
 
        r_i->ptr = 1;
        make_buf_hdr(&(r_i->hdr_sec), buf_len, buf_len);
        make_sec_desc_buf(r_i->data, buf_len, 1);
 
-       r_i->status = status; /* 0x0000 0000 or 0x0000 007a */
+       r_i->status = status;   /* 0x0000 0000 or 0x0000 007a */
 
        return True;
 }
-#endif 
+#endif
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_get_key_sec(char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC * r_q, prs_struct *ps,
+                         int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_get_key_sec");
        depth++;
 
        prs_align(ps);
-       
-       prs_uint32("ptr      ", ps, depth, &(r_q->ptr      ));
+
+       prs_uint32("ptr      ", ps, depth, &(r_q->ptr));
 
        if (r_q->ptr != 0)
        {
@@ -819,14 +875,15 @@ BOOL reg_io_r_get_key_sec(char *desc,  REG_R_GET_KEY_SEC *r_q, prs_struct *ps, i
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
-                               uint8 major, uint8 minor)
+BOOL make_reg_q_info(REG_Q_INFO * q_i, POLICY_HND *pol, const char *val_name,
+                    uint8 major, uint8 minor)
 {
        int len_type = val_name != NULL ? strlen(val_name) + 1 : 0;
 
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        make_uni_hdr(&(q_i->hdr_val), len_type);
        make_unistr2(&(q_i->uni_val), val_name, len_type);
@@ -836,8 +893,8 @@ BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
 
        q_i->ptr_uni_type = 0x1;
        q_i->uni_type.buf_max_len = 0x104;
-       q_i->uni_type.buf_len     = 0x0;
-       q_i->uni_type.undoc       = 0;
+       q_i->uni_type.buf_len = 0x0;
+       q_i->uni_type.undoc = 0;
 
        q_i->ptr_max_len = 1;
        q_i->buf_max_len = 0x104;
@@ -851,21 +908,22 @@ BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_info(char *desc, REG_Q_INFO * r_q, prs_struct *ps, int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_info");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth); 
-       smb_io_unihdr ("", &(r_q->hdr_val), ps, depth);
+
+       smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_val), ps, depth);
        smb_io_unistr2("", &(r_q->uni_val), r_q->hdr_val.buffer, ps, depth);
 
        prs_align(ps);
-       
+
        prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
        if (r_q->ptr_type != 0)
        {
@@ -874,7 +932,8 @@ BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
 
        prs_uint32("ptr_uni_type", ps, depth, &(r_q->ptr_uni_type));
 
-       smb_io_buffer2("uni_type", &(r_q->uni_type), r_q->ptr_uni_type, ps, depth);
+       smb_io_buffer2("uni_type", &(r_q->uni_type), r_q->ptr_uni_type, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr_max_len", ps, depth, &(r_q->ptr_max_len));
@@ -896,11 +955,11 @@ BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_r_info(REG_R_INFO *r_r,
-                               uint32 *type, BUFFER2 *buf,
-                               uint32 status)
+BOOL make_reg_r_info(REG_R_INFO * r_r,
+                    uint32 *type, BUFFER2 * buf, uint32 status)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        r_r->ptr_type = type != NULL ? 1 : 0;
        r_r->type = type;
@@ -921,7 +980,7 @@ BOOL make_reg_r_info(REG_R_INFO *r_r,
                r_r->ptr_max_len = 0;
                r_r->ptr_len = 0;
        }
-               
+
        r_r->status = status;
 
        return True;
@@ -930,15 +989,16 @@ BOOL make_reg_r_info(REG_R_INFO *r_r,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_info(char *desc, REG_R_INFO * r_r, prs_struct *ps, int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_info");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type));
        if (r_r->ptr_type != 0)
        {
@@ -946,7 +1006,8 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
        }
 
        prs_uint32("ptr_uni_type", ps, depth, &(r_r->ptr_uni_type));
-       smb_io_buffer2("uni_type", r_r->uni_type, r_r->ptr_uni_type, ps, depth);
+       smb_io_buffer2("uni_type", r_r->uni_type, r_r->ptr_uni_type, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len));
@@ -969,22 +1030,23 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
-                               uint32 val_idx, uint32 max_val_len,
-                               uint32 max_buf_len)
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE * q_i, POLICY_HND *pol,
+                        uint32 val_idx, uint32 max_val_len,
+                        uint32 max_buf_len)
 {
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
        ZERO_STRUCTP(q_i);
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        q_i->val_index = val_idx;
        q_i->hdr_name.uni_str_len = 0;
        q_i->hdr_name.uni_max_len = max_val_len * 2;
        q_i->hdr_name.buffer = max_val_len > 0 ? 1 : 0;
        q_i->uni_name.uni_max_len = max_val_len;
-       
+
        q_i->ptr_type = 1;
        q_i->type = 0x0;
 
@@ -1003,20 +1065,23 @@ BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_enum_val(char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE * q_q, prs_struct *ps,
+                      int depth)
 {
-       if (q_q == NULL) return False;
+       if (q_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_enum_val");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
-       
+
+       smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
        prs_uint32("val_index", ps, depth, &(q_q->val_index));
-       smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
-       smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+       smb_io_unihdr("hdr_name", &(q_q->hdr_name), ps, depth);
+       smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr_type", ps, depth, &(q_q->ptr_type));
@@ -1027,7 +1092,8 @@ BOOL reg_io_q_enum_val(char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
        }
 
        prs_uint32("ptr_value", ps, depth, &(q_q->ptr_value));
-       smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps, depth);
+       smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
@@ -1047,17 +1113,20 @@ BOOL reg_io_q_enum_val(char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_enum_val(char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE * r_q, prs_struct *ps,
+                      int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_enum_val");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_unihdr ("hdr_name", &(r_q->hdr_name), ps, depth);
-       smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+
+       smb_io_unihdr("hdr_name", &(r_q->hdr_name), ps, depth);
+       smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
@@ -1068,7 +1137,8 @@ BOOL reg_io_r_enum_val(char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
        }
 
        prs_uint32("ptr_value", ps, depth, &(r_q->ptr_value));
-       smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth);
+       smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
@@ -1091,22 +1161,22 @@ BOOL reg_io_r_enum_val(char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
-                               char *val_name, uint32 type,
-                               BUFFER3 *val)
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE * q_i, POLICY_HND *pol,
+                          char *val_name, uint32 type, BUFFER3 * val)
 {
        int val_len = strlen(val_name) + 1;
 
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
        ZERO_STRUCTP(q_i);
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        make_uni_hdr(&q_i->hdr_name, val_len);
        make_unistr2(&(q_i->uni_name), val_name, val_len);
-       
-       q_i->type      = type;
+
+       q_i->type = type;
        q_i->buf_value = val;
 
        return True;
@@ -1115,19 +1185,22 @@ BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_create_val(char *desc,  REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE * q_q, prs_struct *ps,
+                        int depth)
 {
-       if (q_q == NULL) return False;
+       if (q_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_create_val");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
-       
-       smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
-       smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+
+       smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+       smb_io_unihdr("hdr_name", &(q_q->hdr_name), ps, depth);
+       smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("type", ps, depth, &(q_q->type));
@@ -1140,15 +1213,17 @@ BOOL reg_io_q_create_val(char *desc,  REG_Q_CREATE_VALUE *q_q, prs_struct *ps, i
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_create_val(char *desc,  REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE * r_q, prs_struct *ps,
+                        int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_create_val");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_q->status));
 
        return True;
@@ -1157,11 +1232,13 @@ BOOL reg_io_r_create_val(char *desc,  REG_R_CREATE_VALUE *r_q, prs_struct *ps, i
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY * q_i, POLICY_HND *pol,
+                        uint32 key_idx)
 {
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       q_i->pol = *pol;
 
        q_i->key_index = key_idx;
        q_i->key_name_len = 0;
@@ -1175,7 +1252,7 @@ BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
        memset(q_i->pad2, 0, sizeof(q_i->pad2));
 
        q_i->ptr3 = 1;
-       init_nt_time(&(q_i->time));   /* ignored ? */
+       init_nt_time(&(q_i->time));     /* ignored ? */
 
        return True;
 }
@@ -1183,17 +1260,19 @@ BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_enum_key(char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY * q_q, prs_struct *ps,
+                      int depth)
 {
-       if (q_q == NULL) return False;
+       if (q_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_enum_key");
        depth++;
 
        prs_align(ps);
-       
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
-       
+
+       smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
        prs_uint32("key_index", ps, depth, &(q_q->key_index));
        prs_uint16("key_name_len", ps, depth, &(q_q->key_name_len));
        prs_uint16("unknown_1", ps, depth, &(q_q->unknown_1));
@@ -1203,14 +1282,16 @@ BOOL reg_io_q_enum_key(char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, int dep
        if (q_q->ptr1 != 0)
        {
                prs_uint32("unknown_2", ps, depth, &(q_q->unknown_2));
-               prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1));
+               prs_uint8s(False, "pad1", ps, depth, q_q->pad1,
+                          sizeof(q_q->pad1));
        }
 
        prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
 
        if (q_q->ptr2 != 0)
        {
-               prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2));
+               prs_uint8s(False, "pad2", ps, depth, q_q->pad2,
+                          sizeof(q_q->pad2));
        }
 
        prs_uint32("ptr3", ps, depth, &(q_q->ptr3));
@@ -1226,15 +1307,17 @@ BOOL reg_io_q_enum_key(char *desc,  REG_Q_ENUM_KEY *q_q, prs_struct *ps, int dep
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_enum_key(char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY * r_q, prs_struct *ps,
+                      int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_enum_key");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint16("key_name_len", ps, depth, &(r_q->key_name_len));
        prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
 
@@ -1252,7 +1335,8 @@ BOOL reg_io_r_enum_key(char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, int dep
 
        if (r_q->ptr2 != 0)
        {
-               prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2));
+               prs_uint8s(False, "pad2", ps, depth, r_q->pad2,
+                          sizeof(r_q->pad2));
        }
 
        prs_uint32("ptr3", ps, depth, &(r_q->ptr3));
@@ -1271,14 +1355,15 @@ BOOL reg_io_r_enum_key(char *desc,  REG_R_ENUM_KEY *r_q, prs_struct *ps, int dep
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
-                               char *key_name, uint32 access_mask)
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY * r_q, POLICY_HND *pol,
+                          char *key_name, uint32 access_mask)
 {
-       int len_name = strlen(key_name)+1;
+       int len_name = strlen(key_name) + 1;
 
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
-       memcpy(&(r_q->pol), pol, sizeof(r_q->pol));
+       r_q->pol = *pol;
 
        make_uni_hdr(&(r_q->hdr_name), len_name);
        make_unistr2(&(r_q->uni_name), key_name, len_name);
@@ -1292,21 +1377,23 @@ BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_open_entry(char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY * r_q, prs_struct *ps,
+                        int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_entry");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_q->pol), ps, depth);
-       smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+       smb_io_unihdr("", &(r_q->hdr_name), ps, depth);
        smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
 
        prs_align(ps);
-       
+
        prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
        prs_uint32("access_mask", ps, depth, &(r_q->access_mask));
 
@@ -1317,12 +1404,13 @@ BOOL reg_io_q_open_entry(char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int
 /*******************************************************************
 creates a structure.
 ********************************************************************/
-BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
-                               POLICY_HND *pol, uint32 status)
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY * r_r,
+                          POLICY_HND *pol, uint32 status)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
-       memcpy(&(r_r->pol), pol, sizeof(r_r->pol));
+       r_r->pol = *pol;
        r_r->status = status;
 
        return True;
@@ -1331,15 +1419,17 @@ BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_open_entry(char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY * r_r, prs_struct *ps,
+                        int depth)
 {
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_open_entry");
        depth++;
 
        prs_align(ps);
-       
+
        smb_io_pol_hnd("", &(r_r->pol), ps, depth);
 
        prs_uint32("status", ps, depth, &(r_r->status));
@@ -1350,12 +1440,13 @@ BOOL reg_io_r_open_entry(char *desc,  REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
-                               const char *msg, uint32 timeout, uint16 flags)
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN * q_i,
+                        const char *msg, uint32 timeout, uint16 flags)
 {
        int len = strlen(msg) + 1;
 
-       if (q_i == NULL) return False;
+       if (q_i == NULL)
+               return False;
 
        ZERO_STRUCTP(q_i);
 
@@ -1365,9 +1456,9 @@ BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
 
        make_uni_hdr(&q_i->hdr_msg, len);
        make_unistr2(&(q_i->uni_msg), msg, len);
-       
+
        q_i->timeout = timeout;
-       q_i->flags   = flags;
+       q_i->flags = flags;
 
        return True;
 }
@@ -1375,25 +1466,28 @@ BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_q_shutdown(char *desc,  REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_q, prs_struct *ps,
+                      int depth)
 {
-       if (q_q == NULL) return False;
+       if (q_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_q_shutdown");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("ptr_0", ps, depth, &(q_q->ptr_0));
        prs_uint32("ptr_1", ps, depth, &(q_q->ptr_1));
        prs_uint32("ptr_2", ps, depth, &(q_q->ptr_2));
-       
-       smb_io_unihdr ("hdr_msg", &(q_q->hdr_msg), ps, depth);
-       smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps, depth);
+
+       smb_io_unihdr("hdr_msg", &(q_q->hdr_msg), ps, depth);
+       smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("timeout", ps, depth, &(q_q->timeout));
-       prs_uint16("flags  ", ps, depth, &(q_q->flags  ));
+       prs_uint16("flags  ", ps, depth, &(q_q->flags));
        prs_align(ps);
 
        return True;
@@ -1402,17 +1496,18 @@ BOOL reg_io_q_shutdown(char *desc,  REG_Q_SHUTDOWN *q_q, prs_struct *ps, int dep
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL reg_io_r_shutdown(char *desc,  REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_q, prs_struct *ps,
+                      int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "reg_io_r_shutdown");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("status", ps, depth, &(r_q->status));
 
        return True;
 }
-
index cdda441980b52898c1a4ea0be165da305772dc43..d671bd98f9c683c6606772465a69d55dc5cdc798 100644 (file)
@@ -33,7 +33,7 @@ extern int DEBUGLEVEL;
 /*******************************************************************
 makes a SAMR_Q_CLOSE_HND structure.
 ********************************************************************/
-BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND * hnd)
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -49,7 +49,7 @@ BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND * q_c, POLICY_HND * hnd)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND * q_u,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -66,7 +66,7 @@ BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -87,7 +87,7 @@ BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
 makes a SAMR_Q_LOOKUP_DOMAIN structure.
 ********************************************************************/
 BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
-                              POLICY_HND * pol, const char *dom_name)
+                              POLICY_HND *pol, const char *dom_name)
 {
        int len_name = strlen(dom_name);
 
@@ -108,7 +108,7 @@ BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -132,7 +132,7 @@ BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
 makes a SAMR_R_LOOKUP_DOMAIN structure.
 ********************************************************************/
 BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
-                              DOM_SID * dom_sid, uint32 status)
+                              DOM_SID *dom_sid, uint32 status)
 {
        if (r_u == NULL)
                return False;
@@ -154,7 +154,7 @@ BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -181,7 +181,7 @@ BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u,
-                           const POLICY_HND * dom_pol, const DOM_SID * sid)
+                           const POLICY_HND *dom_pol, const DOM_SID *sid)
 {
        if (q_u == NULL)
                return False;
@@ -198,7 +198,7 @@ BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D * q_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -221,7 +221,7 @@ BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -240,8 +240,8 @@ BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
-                            const POLICY_HND * connect_pol, uint32 flags,
-                            const DOM_SID * sid)
+                            const POLICY_HND *connect_pol, uint32 flags,
+                            const DOM_SID *sid)
 {
        if (q_u == NULL)
                return False;
@@ -259,7 +259,7 @@ BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -284,7 +284,7 @@ BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -305,7 +305,7 @@ BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
-                                  POLICY_HND * user_pol)
+                                  POLICY_HND *user_pol)
 {
        if (q_u == NULL)
                return False;
@@ -321,7 +321,7 @@ BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -338,7 +338,7 @@ BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -360,7 +360,7 @@ BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
-                              const POLICY_HND * user_pol, uint32 sec_info)
+                              const POLICY_HND *user_pol, uint32 sec_info)
 {
        if (q_u == NULL)
                return False;
@@ -378,7 +378,7 @@ BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -399,7 +399,7 @@ BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
-                               POLICY_HND * domain_pol, uint16 switch_value)
+                               POLICY_HND *domain_pol, uint16 switch_value)
 {
        if (q_u == NULL)
                return False;
@@ -416,7 +416,7 @@ BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -453,7 +453,7 @@ BOOL make_unk_info3(SAM_UNK_INFO_3 * u_3)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 * u_3,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (u_3 == NULL)
                return False;
@@ -488,7 +488,7 @@ BOOL make_unk_info6(SAM_UNK_INFO_6 * u_6)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 * u_6,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (u_6 == NULL)
                return False;
@@ -522,7 +522,7 @@ BOOL make_unk_info7(SAM_UNK_INFO_7 * u_7)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 * u_7,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (u_7 == NULL)
                return False;
@@ -558,7 +558,7 @@ BOOL make_unk_info12(SAM_UNK_INFO_12 * u_12)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (u_12 == NULL)
                return False;
@@ -618,7 +618,7 @@ BOOL make_unk_info2(SAM_UNK_INFO_2 * u_2, char *domain, char *server)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 * u_2,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (u_2 == NULL)
                return False;
@@ -680,7 +680,7 @@ BOOL make_unk_info1(SAM_UNK_INFO_1 * u_1)
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 * u_1,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (u_1 == NULL)
                return False;
@@ -729,7 +729,7 @@ BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -811,7 +811,7 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
 reads or writes a SAMR_R_QUERY_SEC_OBJ structure.
 ********************************************************************/
 BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -836,7 +836,7 @@ reads or writes a SAM_STR1 structure.
 ********************************************************************/
 static BOOL sam_io_sam_str1(char *desc, SAM_STR1 * sam, uint32 acct_buf,
                            uint32 name_buf, uint32 desc_buf,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -885,7 +885,7 @@ static BOOL make_sam_entry1(SAM_ENTRY1 * sam, uint32 user_idx,
 reads or writes a SAM_ENTRY1 structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 * sam,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -912,8 +912,7 @@ static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 * sam,
 reads or writes a SAM_STR2 structure.
 ********************************************************************/
 static BOOL sam_io_sam_str2(char *desc, SAM_STR2 * sam, uint32 acct_buf,
-                           uint32 desc_buf,
-                           prs_struct * ps, int depth)
+                           uint32 desc_buf, prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -958,7 +957,7 @@ static BOOL make_sam_entry2(SAM_ENTRY2 * sam, uint32 user_idx,
 reads or writes a SAM_ENTRY2 structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 * sam,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -984,8 +983,7 @@ static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 * sam,
 reads or writes a SAM_STR3 structure.
 ********************************************************************/
 static BOOL sam_io_sam_str3(char *desc, SAM_STR3 * sam, uint32 acct_buf,
-                           uint32 desc_buf,
-                           prs_struct * ps, int depth)
+                           uint32 desc_buf, prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -1029,7 +1027,7 @@ static BOOL make_sam_entry3(SAM_ENTRY3 * sam, uint32 grp_idx,
 reads or writes a SAM_ENTRY3 structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry3(char *desc, SAM_ENTRY3 * sam,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -1072,7 +1070,7 @@ static BOOL make_sam_entry4(SAM_ENTRY4 * sam, uint32 user_idx,
 reads or writes a SAM_ENTRY4 structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry4(char *desc, SAM_ENTRY4 * sam,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -1110,7 +1108,7 @@ static BOOL make_sam_entry5(SAM_ENTRY5 * sam, uint32 grp_idx,
 reads or writes a SAM_ENTRY5 structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry5(char *desc, SAM_ENTRY5 * sam,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -1146,7 +1144,7 @@ BOOL make_sam_entry(SAM_ENTRY * sam, uint32 len_sam_name, uint32 rid)
 reads or writes a SAM_ENTRY structure.
 ********************************************************************/
 static BOOL sam_io_sam_entry(char *desc, SAM_ENTRY * sam,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (sam == NULL)
                return False;
@@ -1165,7 +1163,7 @@ static BOOL sam_io_sam_entry(char *desc, SAM_ENTRY * sam,
 /*******************************************************************
 makes a SAMR_Q_ENUM_DOM_USERS structure.
 ********************************************************************/
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND * pol,
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND *pol,
                                uint32 start_idx,
                                uint16 acb_mask, uint16 unk_1, uint32 size)
 {
@@ -1188,7 +1186,7 @@ BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS * q_e, POLICY_HND * pol,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS * q_e,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -1248,7 +1246,7 @@ BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1312,7 +1310,7 @@ BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
 /*******************************************************************
 makes a SAMR_Q_QUERY_DISPINFO structure.
 ********************************************************************/
-BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND * pol,
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
                                uint16 switch_level, uint32 start_idx,
                                uint32 max_entries)
 {
@@ -1336,7 +1334,7 @@ BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND * pol,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -1412,7 +1410,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam,
                                  uint32 num_entries,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1492,7 +1490,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam,
                                  uint32 num_entries,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1571,7 +1569,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam,
                                  uint32 num_entries,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1649,7 +1647,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
                                  uint32 num_entries,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1724,7 +1722,7 @@ reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 * sam,
                                  uint32 num_entries,
-                                 prs_struct * ps, int depth)
+                                 prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -1786,7 +1784,7 @@ BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -1859,7 +1857,7 @@ BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
 makes a SAMR_Q_OPEN_GROUP structure.
 ********************************************************************/
 BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
-                           const POLICY_HND * hnd,
+                           const POLICY_HND *hnd,
                            uint32 access_mask, uint32 rid)
 {
        if (q_c == NULL || hnd == NULL)
@@ -1878,7 +1876,7 @@ BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP * q_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -1900,7 +1898,7 @@ BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP * r_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -1950,7 +1948,7 @@ BOOL make_samr_group_info1(GROUP_INFO1 * gr1,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (gr1 == NULL)
                return False;
@@ -2000,7 +1998,7 @@ BOOL make_samr_group_info4(GROUP_INFO4 * gr4, const char *acct_desc)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (gr4 == NULL)
                return False;
@@ -2022,7 +2020,7 @@ BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
 reads or writes a structure.
 ********************************************************************/
 static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR * ctr,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (ctr == NULL)
                return False;
@@ -2065,7 +2063,7 @@ static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR * ctr,
 makes a SAMR_Q_CREATE_DOM_GROUP structure.
 ********************************************************************/
 BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
-                                 POLICY_HND * pol, const char *acct_desc)
+                                 POLICY_HND *pol, const char *acct_desc)
 {
        int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
        if (q_e == NULL || pol == NULL)
@@ -2088,7 +2086,7 @@ BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2114,7 +2112,7 @@ BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2136,7 +2134,7 @@ BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
 makes a SAMR_Q_DELETE_DOM_GROUP structure.
 ********************************************************************/
 BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
-                                 POLICY_HND * hnd)
+                                 POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -2152,7 +2150,7 @@ BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP * q_c,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -2169,7 +2167,7 @@ BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2190,7 +2188,7 @@ BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
 makes a SAMR_Q_DEL_GROUPMEM structure.
 ********************************************************************/
 BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
-                             POLICY_HND * pol, uint32 rid)
+                             POLICY_HND *pol, uint32 rid)
 {
        if (q_e == NULL || pol == NULL)
                return False;
@@ -2208,7 +2206,7 @@ BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2229,7 +2227,7 @@ BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
 /*******************************************************************
 makes a SAMR_R_DEL_GROUPMEM structure.
 ********************************************************************/
-BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND * pol,
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
                              uint32 status)
 {
        if (r_u == NULL)
@@ -2247,7 +2245,7 @@ BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND * pol,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2267,7 +2265,7 @@ BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
 makes a SAMR_Q_ADD_GROUPMEM structure.
 ********************************************************************/
 BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
-                             POLICY_HND * pol, uint32 rid)
+                             POLICY_HND *pol, uint32 rid)
 {
        if (q_e == NULL || pol == NULL)
                return False;
@@ -2287,7 +2285,7 @@ BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2309,7 +2307,7 @@ BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
 /*******************************************************************
 makes a SAMR_R_ADD_GROUPMEM structure.
 ********************************************************************/
-BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND * pol,
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
                              uint32 status)
 {
        if (r_u == NULL)
@@ -2327,7 +2325,7 @@ BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND * pol,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2347,7 +2345,7 @@ BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
 makes a SAMR_Q_SET_GROUPINFO structure.
 ********************************************************************/
 BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
-                              POLICY_HND * pol, GROUP_INFO_CTR * ctr)
+                              POLICY_HND *pol, GROUP_INFO_CTR * ctr)
 {
        if (q_e == NULL || pol == NULL)
                return False;
@@ -2365,7 +2363,7 @@ BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2403,7 +2401,7 @@ BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2422,7 +2420,7 @@ BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
 makes a SAMR_Q_QUERY_GROUPINFO structure.
 ********************************************************************/
 BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
-                                POLICY_HND * pol, uint16 switch_level)
+                                POLICY_HND *pol, uint16 switch_level)
 {
        if (q_e == NULL || pol == NULL)
                return False;
@@ -2441,7 +2439,7 @@ BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2481,7 +2479,7 @@ BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2507,7 +2505,7 @@ BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
 /*******************************************************************
 makes a SAMR_Q_QUERY_GROUPMEM structure.
 ********************************************************************/
-BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND * hnd)
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -2523,7 +2521,7 @@ BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND * hnd)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -2577,7 +2575,7 @@ BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -2602,10 +2600,10 @@ BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
                        prs_uint32("num_rids", ps, depth, &(r_u->num_rids));
                        if (r_u->num_rids != 0)
                        {
-                               r_u->rid = (uint32 *) Realloc(r_u->rid,
-                                                             sizeof(r_u->rid
-                                                                    [0]) *
-                                                             r_u->num_rids);
+                               r_u->rid = (uint32 *)Realloc(r_u->rid,
+                                                            sizeof(r_u->rid
+                                                                   [0]) *
+                                                            r_u->num_rids);
                                if (r_u->rid == NULL)
                                {
                                        samr_free_r_query_groupmem(r_u);
@@ -2624,11 +2622,11 @@ BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
 
                        if (r_u->num_attrs != 0)
                        {
-                               r_u->attr = (uint32 *) Realloc(r_u->attr,
-                                                              sizeof
-                                                              (r_u->attr[0])
-                                                              *
-                                                              r_u->num_attrs);
+                               r_u->attr = (uint32 *)Realloc(r_u->attr,
+                                                             sizeof
+                                                             (r_u->attr[0])
+                                                             *
+                                                             r_u->num_attrs);
                                if (r_u->attr == NULL)
                                {
                                        samr_free_r_query_groupmem(r_u);
@@ -2675,7 +2673,7 @@ void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u)
 makes a SAMR_Q_QUERY_USERGROUPS structure.
 ********************************************************************/
 BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
-                                 POLICY_HND * hnd)
+                                 POLICY_HND *hnd)
 {
        if (q_u == NULL || hnd == NULL)
                return False;
@@ -2691,7 +2689,7 @@ BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -2742,7 +2740,7 @@ BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
-                 prs_struct * ps, int depth)
+                 prs_struct *ps, int depth)
 {
        uint32 i;
        if (gid == NULL)
@@ -2786,7 +2784,7 @@ BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -2819,7 +2817,7 @@ BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
 makes a SAMR_Q_ENUM_DOMAINS structure.
 ********************************************************************/
 BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
-                             const POLICY_HND * pol,
+                             const POLICY_HND *pol,
                              uint32 start_idx, uint32 size)
 {
        if (q_e == NULL || pol == NULL)
@@ -2839,7 +2837,7 @@ BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS * q_e,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -2896,7 +2894,7 @@ BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -2964,7 +2962,7 @@ BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
 makes a SAMR_Q_ENUM_DOM_GROUPS structure.
 ********************************************************************/
 BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
-                                const POLICY_HND * pol,
+                                const POLICY_HND *pol,
                                 uint32 start_idx, uint32 size)
 {
        if (q_e == NULL || pol == NULL)
@@ -2984,7 +2982,7 @@ BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS * q_e,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -3041,7 +3039,7 @@ BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -3105,7 +3103,7 @@ BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
 makes a SAMR_Q_ENUM_DOM_ALIASES structure.
 ********************************************************************/
 BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
-                                 POLICY_HND * pol, uint32 start_idx,
+                                 POLICY_HND *pol, uint32 start_idx,
                                  uint32 size)
 {
        if (q_e == NULL || pol == NULL)
@@ -3126,7 +3124,7 @@ BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -3183,7 +3181,7 @@ BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -3265,7 +3263,7 @@ BOOL make_samr_alias_info3(ALIAS_INFO3 * al3, const char *acct_desc)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (al3 == NULL)
                return False;
@@ -3287,7 +3285,7 @@ BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (ctr == NULL)
                return False;
@@ -3324,7 +3322,7 @@ BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
 makes a SAMR_Q_QUERY_ALIASINFO structure.
 ********************************************************************/
 BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
-                                const POLICY_HND * pol, uint16 switch_level)
+                                const POLICY_HND *pol, uint16 switch_level)
 {
        if (q_e == NULL || pol == NULL)
                return False;
@@ -3342,7 +3340,7 @@ BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (q_e == NULL)
                return False;
@@ -3382,7 +3380,7 @@ BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -3409,7 +3407,7 @@ BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
 makes a SAMR_Q_SET_ALIASINFO structure.
 ********************************************************************/
 BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
-                              const POLICY_HND * hnd, ALIAS_INFO_CTR * ctr)
+                              const POLICY_HND *hnd, ALIAS_INFO_CTR * ctr)
 {
        if (q_u == NULL)
                return False;
@@ -3426,7 +3424,7 @@ BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO * q_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -3446,7 +3444,7 @@ BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -3465,7 +3463,7 @@ BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
 makes a SAMR_Q_QUERY_USERALIASES structure.
 ********************************************************************/
 BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
-                                  const POLICY_HND * hnd,
+                                  const POLICY_HND *hnd,
                                   uint32 num_sids,
                                   uint32 *ptr_sid, DOM_SID2 * sid)
 {
@@ -3490,7 +3488,7 @@ BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES * q_u,
 reads or writes a SAMR_Q_QUERY_USERALIASES structure.
 ********************************************************************/
 BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        fstring tmp;
        uint32 i;
@@ -3511,9 +3509,9 @@ BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
 
        if (q_u->num_sids2 != 0)
        {
-               q_u->ptr_sid = (uint32 *) Realloc(q_u->ptr_sid,
-                                                 sizeof(q_u->ptr_sid[0]) *
-                                                 q_u->num_sids2);
+               q_u->ptr_sid = (uint32 *)Realloc(q_u->ptr_sid,
+                                                sizeof(q_u->ptr_sid[0]) *
+                                                q_u->num_sids2);
                if (q_u->ptr_sid == NULL)
                {
                        samr_free_q_query_useraliases(q_u);
@@ -3609,7 +3607,7 @@ BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
-                 prs_struct * ps, int depth)
+                 prs_struct *ps, int depth)
 {
        fstring tmp;
        uint32 i;
@@ -3655,7 +3653,7 @@ BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -3682,7 +3680,7 @@ BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
 /*******************************************************************
 makes a SAMR_Q_OPEN_ALIAS structure.
 ********************************************************************/
-BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND * pol,
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND *pol,
                            uint32 unknown_0, uint32 rid)
 {
        if (q_u == NULL)
@@ -3704,7 +3702,7 @@ BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS * q_u, const POLICY_HND * pol,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -3726,7 +3724,7 @@ BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
-                         prs_struct * ps, int depth)
+                         prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -3747,7 +3745,7 @@ BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
 makes a SAMR_Q_LOOKUP_RIDS structure.
 ********************************************************************/
 BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
-                            const POLICY_HND * pol, uint32 flags,
+                            const POLICY_HND *pol, uint32 flags,
                             uint32 num_rids, const uint32 *rid)
 {
        if (q_u == NULL)
@@ -3761,7 +3759,7 @@ BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
        q_u->flags = flags;
        q_u->ptr = 0;
        q_u->num_rids2 = num_rids;
-       q_u->rid = (uint32 *) memdup(rid, num_rids * sizeof(q_u->rid[0]));
+       q_u->rid = (uint32 *)memdup(rid, num_rids * sizeof(q_u->rid[0]));
 
        return True;
 }
@@ -3770,7 +3768,7 @@ BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        uint32 i;
        fstring tmp;
@@ -3797,8 +3795,8 @@ BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS * q_u,
 
        if (q_u->num_rids2 != 0)
        {
-               q_u->rid = (uint32 *) Realloc(q_u->rid, sizeof(q_u->rid[0]) *
-                                             q_u->num_rids2);
+               q_u->rid = (uint32 *)Realloc(q_u->rid, sizeof(q_u->rid[0]) *
+                                            q_u->num_rids2);
                if (q_u->rid == NULL)
                {
                        samr_free_q_lookup_rids(q_u);
@@ -3841,7 +3839,7 @@ makes a SAMR_R_LOOKUP_RIDS structure.
 ********************************************************************/
 BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
                             uint32 num_names, UNIHDR * hdr_name,
-                            UNISTR2 * uni_name, uint32 *type)
+                            UNISTR2 *uni_name, uint32 *type)
 {
        if (r_u == NULL)
                return False;
@@ -3884,7 +3882,7 @@ BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        uint32 i;
        fstring tmp;
@@ -3910,9 +3908,9 @@ BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
                        return False;
                }
 
-               r_u->uni_name = (UNISTR2 *) Realloc(r_u->uni_name,
-                                                   r_u->num_names2 *
-                                                   sizeof(r_u->uni_name[0]));
+               r_u->uni_name = (UNISTR2 *)Realloc(r_u->uni_name,
+                                                  r_u->num_names2 *
+                                                  sizeof(r_u->uni_name[0]));
                if (r_u->uni_name == NULL)
                {
                        free(r_u->hdr_name);
@@ -3940,8 +3938,8 @@ BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
 
        if (r_u->ptr_types != 0 && r_u->num_types1 != 0)
        {
-               r_u->type = (uint32 *) Realloc(r_u->type, r_u->num_types2 *
-                                              sizeof(r_u->type[0]));
+               r_u->type = (uint32 *)Realloc(r_u->type, r_u->num_types2 *
+                                             sizeof(r_u->type[0]));
                if (r_u->type == NULL)
                {
                        if (r_u->uni_name != NULL)
@@ -3998,7 +3996,7 @@ void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS * r_u)
 /*******************************************************************
 makes a SAMR_Q_OPEN_ALIAS structure.
 ********************************************************************/
-BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND * hnd)
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND *hnd)
 {
        if (q_u == NULL)
                return False;
@@ -4015,7 +4013,7 @@ BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS * q_u, POLICY_HND * hnd)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4032,7 +4030,7 @@ BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4053,7 +4051,7 @@ BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
 makes a SAMR_Q_CREATE_DOM_ALIAS structure.
 ********************************************************************/
 BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
-                                 POLICY_HND * hnd, const char *acct_desc)
+                                 POLICY_HND *hnd, const char *acct_desc)
 {
        int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
        if (q_u == NULL)
@@ -4075,7 +4073,7 @@ BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4101,7 +4099,7 @@ BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4124,8 +4122,8 @@ BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
 /*******************************************************************
 makes a SAMR_Q_ADD_ALIASMEM structure.
 ********************************************************************/
-BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND * hnd,
-                             DOM_SID * sid)
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND *hnd,
+                             DOM_SID *sid)
 {
        if (q_u == NULL)
                return False;
@@ -4142,7 +4140,7 @@ BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM * q_u, POLICY_HND * hnd,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4162,7 +4160,7 @@ BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4181,8 +4179,8 @@ BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
 /*******************************************************************
 makes a SAMR_Q_DEL_ALIASMEM structure.
 ********************************************************************/
-BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND * hnd,
-                             DOM_SID * sid)
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND *hnd,
+                             DOM_SID *sid)
 {
        if (q_u == NULL)
                return False;
@@ -4199,7 +4197,7 @@ BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM * q_u, POLICY_HND * hnd,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4219,7 +4217,7 @@ BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4238,7 +4236,7 @@ BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
 makes a SAMR_Q_DELETE_DOM_ALIAS structure.
 ********************************************************************/
 BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
-                                 POLICY_HND * hnd)
+                                 POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -4254,7 +4252,7 @@ BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4287,7 +4285,7 @@ BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
-                               prs_struct * ps, int depth)
+                               prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4307,7 +4305,7 @@ BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
 makes a SAMR_Q_QUERY_ALIASMEM structure.
 ********************************************************************/
 BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
-                               const POLICY_HND * hnd)
+                               const POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -4323,7 +4321,7 @@ BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4371,7 +4369,7 @@ BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        uint32 i;
        uint32 ptr_sid[MAX_LOOKUP_SIDS];
@@ -4420,7 +4418,7 @@ BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
 makes a SAMR_Q_LOOKUP_NAMES structure.
 ********************************************************************/
 BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u,
-                             const POLICY_HND * pol, uint32 flags,
+                             const POLICY_HND *pol, uint32 flags,
                              uint32 num_names, char **name)
 {
        uint32 i;
@@ -4450,7 +4448,7 @@ BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        uint32 i;
 
@@ -4568,7 +4566,7 @@ BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        uint32 i;
        fstring tmp;
@@ -4685,7 +4683,7 @@ void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES * r_l)
 makes a SAMR_Q_DELETE_DOM_USER structure.
 ********************************************************************/
 BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
-                                POLICY_HND * hnd)
+                                POLICY_HND *hnd)
 {
        if (q_c == NULL || hnd == NULL)
                return False;
@@ -4701,7 +4699,7 @@ BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4718,7 +4716,7 @@ BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4738,7 +4736,7 @@ BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
-                          const POLICY_HND * pol,
+                          const POLICY_HND *pol,
                           uint32 access_mask, uint32 rid)
 {
        if (q_u == NULL)
@@ -4757,7 +4755,7 @@ BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER * q_u,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4781,7 +4779,7 @@ BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
-                        prs_struct * ps, int depth)
+                        prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4803,7 +4801,7 @@ BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
-                            POLICY_HND * pol,
+                            POLICY_HND *pol,
                             const char *name,
                             uint32 acb_info, uint32 access_mask)
 {
@@ -4829,7 +4827,7 @@ BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4858,7 +4856,7 @@ BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
-                          prs_struct * ps, int depth)
+                          prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -4882,7 +4880,7 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
 makes a SAMR_Q_QUERY_USERINFO structure.
 ********************************************************************/
 BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
-                               POLICY_HND * hnd, uint16 switch_value)
+                               POLICY_HND *hnd, uint16 switch_value)
 {
        if (q_u == NULL || hnd == NULL)
                return False;
@@ -4899,7 +4897,7 @@ BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -4921,7 +4919,7 @@ BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
 reads or writes a LOGON_HRS structure.
 ********************************************************************/
 static BOOL sam_io_logon_hrs(char *desc, LOGON_HRS * hrs,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (hrs == NULL)
                return False;
@@ -4955,27 +4953,10 @@ BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr,
 
        DEBUG(5, ("make_sam_user_info12\n"));
 
-       if (lm_pwd == NULL)
-       {
-               ZERO_STRUCT(usr->lm_pwd);
-               usr->lm_pwd_active = 0;
-       }
-       else
-       {
-               memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
-               usr->lm_pwd_active = 1;
-       }
-
-       if (nt_pwd == NULL)
-       {
-               ZERO_STRUCT(usr->nt_pwd);
-               usr->nt_pwd_active = 0;
-       }
-       else
-       {
-               memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
-               usr->nt_pwd_active = 1;
-       }
+       usr->lm_pwd_active =
+               Memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd)) ? 1 : 0;
+       usr->nt_pwd_active =
+               Memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd)) ? 1 : 0;
 
        return True;
 }
@@ -4984,7 +4965,7 @@ BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr,
 reads or writes a structure.
 ********************************************************************/
 BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (u == NULL)
                return False;
@@ -5025,7 +5006,7 @@ BOOL make_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info)
 reads or writes a structure.
 ********************************************************************/
 BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 * usr,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (usr == NULL)
                return False;
@@ -5093,7 +5074,7 @@ BOOL make_sam_user_info11(SAM_USER_INFO_11 * usr,
 reads or writes a structure.
 ********************************************************************/
 BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (usr == NULL)
                return False;
@@ -5168,7 +5149,7 @@ BOOL make_sam_user_info24(SAM_USER_INFO_24 * usr,
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (usr == NULL)
                return False;
@@ -5201,16 +5182,8 @@ BOOL make_sam_user_info23W(SAM_USER_INFO_23 * usr, const NTTIME * logon_time,    /*
                           const NTTIME * pass_last_set_time,   /* all zeros */
                           const NTTIME * pass_can_change_time, /* all zeros */
                           const NTTIME * pass_must_change_time,        /* all zeros */
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * desc,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str,
-                          const UNISTR2 * mung_dial, uint32 user_rid,  /* 0x0000 0000 */
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name, const UNISTR2 *home_dir, const UNISTR2 *dir_drive, const UNISTR2 *log_scr, const UNISTR2 *prof_path, const UNISTR2 *desc, const UNISTR2 *wkstas, const UNISTR2 *unk_str, const UNISTR2 *mung_dial, uint32 user_rid,        /* 0x0000 0000 */
                           uint32 group_rid,
                           uint32 acb_info,
                           uint32 unknown_3,
@@ -5279,14 +5252,7 @@ BOOL make_sam_user_info23W(SAM_USER_INFO_23 * usr, const NTTIME * logon_time,    /*
        usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
        usr->padding4 = 0;
 
-       if (hrs)
-       {
-               memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
-       }
-       else
-       {
-               memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
-       }
+       Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
 
        return True;
 }
@@ -5375,14 +5341,7 @@ BOOL make_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,  /* all z
        usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
        usr->padding4 = 0;
 
-       if (hrs)
-       {
-               memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
-       }
-       else
-       {
-               memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
-       }
+       Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
 
        return True;
 }
@@ -5391,7 +5350,7 @@ BOOL make_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
 reads or writes a structure.
 ********************************************************************/
 static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 * usr,
-                              prs_struct * ps, int depth)
+                              prs_struct *ps, int depth)
 {
        if (usr == NULL)
                return False;
@@ -5512,16 +5471,16 @@ BOOL make_sam_user_info21W(SAM_USER_INFO_21 * usr,
                           const NTTIME * pass_last_set_time,
                           const NTTIME * pass_can_change_time,
                           const NTTIME * pass_must_change_time,
-                          const UNISTR2 * user_name,
-                          const UNISTR2 * full_name,
-                          const UNISTR2 * home_dir,
-                          const UNISTR2 * dir_drive,
-                          const UNISTR2 * log_scr,
-                          const UNISTR2 * prof_path,
-                          const UNISTR2 * desc,
-                          const UNISTR2 * wkstas,
-                          const UNISTR2 * unk_str,
-                          const UNISTR2 * mung_dial,
+                          const UNISTR2 *user_name,
+                          const UNISTR2 *full_name,
+                          const UNISTR2 *home_dir,
+                          const UNISTR2 *dir_drive,
+                          const UNISTR2 *log_scr,
+                          const UNISTR2 *prof_path,
+                          const UNISTR2 *desc,
+                          const UNISTR2 *wkstas,
+                          const UNISTR2 *unk_str,
+                          const UNISTR2 *mung_dial,
                           const uchar lm_pwd[16],
                           const uchar nt_pwd[16],
                           uint32 user_rid,
@@ -5561,22 +5520,8 @@ BOOL make_sam_user_info21W(SAM_USER_INFO_21 * usr,
        make_uni_hdr(&(usr->hdr_unknown_str), len_unknown_str);
        make_uni_hdr(&(usr->hdr_munged_dial), len_munged_dial);
 
-       if (lm_pwd == NULL)
-       {
-               ZERO_STRUCT(usr->lm_pwd);
-       }
-       else
-       {
-               memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
-       }
-       if (nt_pwd == NULL)
-       {
-               ZERO_STRUCT(usr->nt_pwd);
-       }
-       else
-       {
-               memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
-       }
+       Memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
+       Memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
 
        usr->user_rid = user_rid;
        usr->group_rid = group_rid;
@@ -5603,14 +5548,7 @@ BOOL make_sam_user_info21W(SAM_USER_INFO_21 * usr,
        usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
        usr->padding4 = 0;
 
-       if (hrs)
-       {
-               memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
-       }
-       else
-       {
-               memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
-       }
+       Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
 
        return True;
 }
@@ -5705,14 +5643,7 @@ BOOL make_sam_user_info21A(SAM_USER_INFO_21 * usr,
        usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
        usr->padding4 = 0;
 
-       if (hrs)
-       {
-               memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
-       }
-       else
-       {
-               memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
-       }
+       Memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
 
        return True;
 }
@@ -5721,7 +5652,7 @@ BOOL make_sam_user_info21A(SAM_USER_INFO_21 * usr,
 reads or writes a structure.
 ********************************************************************/
 BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (usr == NULL)
                return False;
@@ -5863,7 +5794,9 @@ uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR * ctr,
 
                        ctr->info.id = (SAM_USER_INFO_11 *) Realloc(NULL,
                                                                    sizeof
-                                                                   (*ctr->info.id11));
+                                                                   (*ctr->
+                                                                    info.
+                                                                    id11));
                        make_sam_user_info11(ctr->info.id11, &expire,
                                             "BROOKFIELDS$",    /* name */
                                             0x03ef,    /* user rid */
@@ -5954,7 +5887,7 @@ BOOL make_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, const uchar * sess_key,
 reads or writes a structure.
 ********************************************************************/
 static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR * ctr,
-                                prs_struct * ps, int depth)
+                                prs_struct *ps, int depth)
 {
        BOOL ret;
        if (ctr == NULL)
@@ -6130,7 +6063,7 @@ BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6164,7 +6097,7 @@ BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
 makes a SAMR_Q_SET_USERINFO structure.
 ********************************************************************/
 BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
-                             POLICY_HND * hnd,
+                             POLICY_HND *hnd,
                              uint16 switch_value, void *info)
 {
        uchar sess_key[16];
@@ -6195,7 +6128,7 @@ BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6248,7 +6181,7 @@ BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6268,7 +6201,7 @@ BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
 makes a SAMR_Q_SET_USERINFO2 structure.
 ********************************************************************/
 BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
-                              POLICY_HND * hnd,
+                              POLICY_HND *hnd,
                               uint16 switch_value, SAM_USERINFO_CTR * ctr)
 {
        uint8 usr_sess_key[16];
@@ -6315,7 +6248,7 @@ BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6366,7 +6299,7 @@ BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
-                            prs_struct * ps, int depth)
+                            prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6409,7 +6342,7 @@ BOOL make_samr_q_connect(SAMR_Q_CONNECT * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT * q_u,
-                      prs_struct * ps, int depth)
+                      prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6433,7 +6366,7 @@ BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
-                      prs_struct * ps, int depth)
+                      prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6473,7 +6406,7 @@ BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON * q_u)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON * q_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6495,7 +6428,7 @@ BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON * r_u,
-                           prs_struct * ps, int depth)
+                           prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6536,7 +6469,7 @@ BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6563,7 +6496,7 @@ BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
@@ -6609,7 +6542,7 @@ BOOL make_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512])
 reads or writes a SAMR_ENC_PASSWD structure.
 ********************************************************************/
 BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD * pwd,
-                       prs_struct * ps, int depth)
+                       prs_struct *ps, int depth)
 {
        if (pwd == NULL)
                return False;
@@ -6655,7 +6588,7 @@ BOOL make_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16])
 reads or writes a SAMR_ENC_HASH structure.
 ********************************************************************/
 BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH * hsh,
-                     prs_struct * ps, int depth)
+                     prs_struct *ps, int depth)
 {
        if (hsh == NULL)
                return False;
@@ -6714,7 +6647,7 @@ BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
@@ -6766,7 +6699,7 @@ BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status)
 reads or writes a structure.
 ********************************************************************/
 BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
-                             prs_struct * ps, int depth)
+                             prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
index e082d445a5d64d0608f2f33c60ff8c055cd6fd5a..4e92b998d503f50e9165b225461db0ac4f356a02 100644 (file)
@@ -32,25 +32,26 @@ extern int DEBUGLEVEL;
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask)
+BOOL make_sec_access(SEC_ACCESS * t, uint32 mask)
 {
+       ZERO_STRUCTP(t);
        t->mask = mask;
-
        return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
+BOOL sec_io_access(char *desc, SEC_ACCESS * t, prs_struct *ps, int depth)
 {
-       if (t == NULL) return False;
+       if (t == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_access");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32("mask", ps, depth, &(t->mask));
 
        return True;
@@ -60,8 +61,11 @@ BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+BOOL make_sec_ace(SEC_ACE * t, const DOM_SID *sid, uint8 type,
+                 SEC_ACCESS mask, uint8 flag)
 {
+       ZERO_STRUCTP(t);
+
        t->type = type;
        t->flags = flag;
        t->size = sid_size(sid) + 8;
@@ -75,29 +79,31 @@ BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 f
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
+BOOL sec_io_ace(char *desc, SEC_ACE * t, prs_struct *ps, int depth)
 {
        uint32 old_offset;
        uint32 offset_ace_size;
-       if (t == NULL) return False;
+       if (t == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_ace");
        depth++;
 
        prs_align(ps);
-       
+
        old_offset = ps->offset;
 
-       prs_uint8     ("type ", ps, depth, &(t->type));
-       prs_uint8     ("flags", ps, depth, &(t->flags));
-       prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_ace_size);
+       prs_uint8("type ", ps, depth, &(t->type));
+       prs_uint8("flags", ps, depth, &(t->flags));
+       prs_uint16_pre("size ", ps, depth, &(t->size), &offset_ace_size);
 
-       sec_io_access   ("info ", &t->info, ps, depth);
+       sec_io_access("info ", &t->info, ps, depth);
        prs_align(ps);
-       smb_io_dom_sid("sid  ", &t->sid , ps, depth);
+       smb_io_dom_sid("sid  ", &t->sid, ps, depth);
        prs_align(ps);
 
-       prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size, old_offset);
+       prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size,
+                       old_offset);
 
        return True;
 }
@@ -105,12 +111,15 @@ BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
 /*******************************************************************
 makes a structure.  
 ********************************************************************/
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
+BOOL make_sec_acl(SEC_ACL * t, uint16 revision, int num_aces, SEC_ACE * ace)
 {
        int i;
+
+       ZERO_STRUCTP(t);
+
        t->revision = revision;
        t->num_aces = num_aces;
-       t->size = 4;
+       t->size = 8;
        t->ace = ace;
 
        for (i = 0; i < num_aces; i++)
@@ -124,9 +133,10 @@ BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
 /*******************************************************************
 frees a structure.  
 ********************************************************************/
-void free_sec_acl(SEC_ACL *t)
+void free_sec_acl(SEC_ACL * t)
 {
-       if (t == NULL) return;
+       if (t == NULL)
+               return;
        if (t->ace != NULL)
        {
                free(t->ace);
@@ -141,35 +151,36 @@ reads or writes a structure.
 first of the xx_io_xx functions that allocates its data structures
  for you as it reads them.
 ********************************************************************/
-BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
+BOOL sec_io_acl(char *desc, SEC_ACL * t, prs_struct *ps, int depth)
 {
        uint32 i;
        uint32 old_offset;
        uint32 offset_acl_size;
 
-       if (t == NULL) return False;
+       if (t == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_acl");
        depth++;
 
        prs_align(ps);
-       
+
        old_offset = ps->offset;
 
        prs_uint16("revision", ps, depth, &(t->revision));
-       prs_uint16_pre("size     ", ps, depth, &(t->size     ), &offset_acl_size);
-       prs_uint32("num_aces ", ps, depth, &(t->num_aces ));
+       prs_uint16_pre("size     ", ps, depth, &(t->size), &offset_acl_size);
+       prs_uint32("num_aces ", ps, depth, &(t->num_aces));
 
        if (ps->io && t->num_aces != 0)
        {
                /* reading */
-               t->ace = (SEC_ACE*)malloc(sizeof(t->ace[0]) * t->num_aces);
+               t->ace = (SEC_ACE *) malloc(sizeof(t->ace[0]) * t->num_aces);
                ZERO_STRUCTP(t->ace);
-               }
+       }
 
        if (t->ace == NULL && t->num_aces != 0)
        {
-               DEBUG(0,("INVALID ACL\n"));
+               DEBUG(0, ("INVALID ACL\n"));
                ps->offset = 0xfffffffe;
                return False;
        }
@@ -177,13 +188,14 @@ BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
        for (i = 0; i < MIN(t->num_aces, MAX_SEC_ACES); i++)
        {
                fstring tmp;
-               slprintf(tmp, sizeof(tmp)-1, "ace[%02d]: ", i);
+               slprintf(tmp, sizeof(tmp) - 1, "ace[%02d]: ", i);
                sec_io_ace(tmp, &t->ace[i], ps, depth);
        }
 
        prs_align(ps);
 
-       prs_uint16_post("size     ", ps, depth, &t->size    , offset_acl_size, old_offset);
+       prs_uint16_post("size     ", ps, depth, &t->size, offset_acl_size,
+                       old_offset);
 
        return True;
 }
@@ -192,24 +204,26 @@ BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
 /*******************************************************************
 makes a structure
 ********************************************************************/
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
-                       DOM_SID *owner_sid, DOM_SID *grp_sid,
-                               SEC_ACL *sacl, SEC_ACL *dacl)
+int make_sec_desc(SEC_DESC * t, uint16 revision, uint16 type,
+                 DOM_SID *owner_sid, DOM_SID *grp_sid,
+                 SEC_ACL * sacl, SEC_ACL * dacl)
 {
        uint32 offset;
 
+       ZERO_STRUCTP(t);
+
        t->revision = revision;
-       t->type     = type;
+       t->type = type;
 
        t->off_owner_sid = 0;
-       t->off_grp_sid   = 0;
-       t->off_sacl      = 0;
-       t->off_dacl      = 0;
+       t->off_grp_sid = 0;
+       t->off_sacl = 0;
+       t->off_dacl = 0;
 
-       t->dacl      = dacl;
-       t->sacl      = sacl;
+       t->dacl = dacl;
+       t->sacl = sacl;
        t->owner_sid = owner_sid;
-       t->grp_sid   = grp_sid;
+       t->grp_sid = grp_sid;
 
        offset = 0x0;
 
@@ -221,6 +235,7 @@ int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
                }
                t->off_dacl = offset;
                offset += dacl->size;
+               offset = ((offset + 3) & ~3);
        }
 
        if (sacl != NULL)
@@ -231,6 +246,7 @@ int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
                }
                t->off_sacl = offset;
                offset += sacl->size;
+               offset = ((offset + 3) & ~3);
        }
 
        if (owner_sid != NULL)
@@ -241,6 +257,7 @@ int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
                }
                t->off_owner_sid = offset;
                offset += sid_size(owner_sid);
+               offset = ((offset + 3) & ~3);
        }
 
        if (grp_sid != NULL)
@@ -260,7 +277,7 @@ int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
 /*******************************************************************
 frees a structure
 ********************************************************************/
-void free_sec_desc(SEC_DESC *t)
+void free_sec_desc(SEC_DESC * t)
 {
        if (t->dacl != NULL)
        {
@@ -290,70 +307,75 @@ void free_sec_desc(SEC_DESC *t)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
+BOOL sec_io_desc(char *desc, SEC_DESC * t, prs_struct *ps, int depth)
 {
 #if 0
        uint32 off_owner_sid;
-       uint32 off_grp_sid  ;
-       uint32 off_sacl     ;
-       uint32 off_dacl     ;
+       uint32 off_grp_sid;
+       uint32 off_sacl;
+       uint32 off_dacl;
 #endif
        uint32 old_offset;
-       uint32 max_offset = 0; /* after we're done, move offset to end */
+       uint32 max_offset = 0;  /* after we're done, move offset to end */
 
-       if (t == NULL) return False;
+       if (t == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_desc");
        depth++;
 
        prs_align(ps);
-       
+
        /* start of security descriptor stored for back-calc offset purposes */
        old_offset = ps->offset;
        max_offset = old_offset;
 
-       prs_uint16("revision ", ps, depth, &(t->revision ));
-       prs_uint16("type     ", ps, depth, &(t->type     ));
+       prs_uint16("revision ", ps, depth, &(t->revision));
+       prs_uint16("type     ", ps, depth, &(t->type));
 
        prs_uint32("off_owner_sid", ps, depth, &(t->off_owner_sid));
-       prs_uint32("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ));
-       prs_uint32("off_sacl     ", ps, depth, &(t->off_sacl     ));
-       prs_uint32("off_dacl     ", ps, depth, &(t->off_dacl     ));
+       prs_uint32("off_grp_sid  ", ps, depth, &(t->off_grp_sid));
+       prs_uint32("off_sacl     ", ps, depth, &(t->off_sacl));
+       prs_uint32("off_dacl     ", ps, depth, &(t->off_dacl));
 #if 0
-       prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid), &off_owner_sid);
-       prs_uint32_pre("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ), &off_grp_sid  );
-       prs_uint32_pre("off_sacl     ", ps, depth, &(t->off_sacl     ), &off_sacl     );
-       prs_uint32_pre("off_dacl     ", ps, depth, &(t->off_dacl     ), &off_dacl     );
+       prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid),
+                      &off_owner_sid);
+       prs_uint32_pre("off_grp_sid  ", ps, depth, &(t->off_grp_sid),
+                      &off_grp_sid);
+       prs_uint32_pre("off_sacl     ", ps, depth, &(t->off_sacl), &off_sacl);
+       prs_uint32_pre("off_dacl     ", ps, depth, &(t->off_dacl), &off_dacl);
 #endif
        max_offset = MAX(max_offset, ps->offset);
 
        if (IS_BITS_SET_ALL(t->type, SEC_DESC_DACL_PRESENT))
        {
 #if 0
-               prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl     ), off_dacl     , ps->offset - old_offset);
+               prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl),
+                               off_dacl, ps->offset - old_offset);
 #endif
                ps->offset = old_offset + t->off_dacl;
                if (ps->io)
                {
                        /* reading */
-                       t->dacl = (SEC_ACL*)malloc(sizeof(*t->dacl));
+                       t->dacl = (SEC_ACL *) malloc(sizeof(*t->dacl));
                        ZERO_STRUCTP(t->dacl);
                }
 
                if (t->dacl == NULL)
                {
-                       DEBUG(0,("INVALID DACL\n"));
+                       DEBUG(0, ("INVALID DACL\n"));
                        ps->offset = 0xfffffffe;
                        return False;
                }
 
-               sec_io_acl     ("dacl"        , t->dacl       , ps, depth);
+               sec_io_acl("dacl", t->dacl, ps, depth);
                prs_align(ps);
        }
 #if 0
        else
        {
-               prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl     ), off_dacl     , 0);
+               prs_uint32_post("off_dacl    ", ps, depth, &(t->off_dacl),
+                               off_dacl, 0);
        }
 #endif
 
@@ -362,66 +384,71 @@ BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
        if (IS_BITS_SET_ALL(t->type, SEC_DESC_SACL_PRESENT))
        {
 #if 0
-               prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl  ), off_sacl  , ps->offset - old_offset);
+               prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl),
+                               off_sacl, ps->offset - old_offset);
 #endif
                ps->offset = old_offset + t->off_sacl;
                if (ps->io)
                {
                        /* reading */
-                       t->sacl = (SEC_ACL*)malloc(sizeof(*t->sacl));
+                       t->sacl = (SEC_ACL *) malloc(sizeof(*t->sacl));
                        ZERO_STRUCTP(t->sacl);
                }
 
                if (t->sacl == NULL)
                {
-                       DEBUG(0,("INVALID SACL\n"));
+                       DEBUG(0, ("INVALID SACL\n"));
                        ps->offset = 0xfffffffe;
                        return False;
                }
 
-               sec_io_acl     ("sacl"      , t->sacl       , ps, depth);
+               sec_io_acl("sacl", t->sacl, ps, depth);
                prs_align(ps);
        }
 #if 0
        else
        {
-               prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl  ), off_sacl  , 0);
+               prs_uint32_post("off_sacl  ", ps, depth, &(t->off_sacl),
+                               off_sacl, 0);
        }
 #endif
 
        max_offset = MAX(max_offset, ps->offset);
 
 #if 0
-       prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid), off_owner_sid, ps->offset - old_offset);
+       prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid),
+                       off_owner_sid, ps->offset - old_offset);
 #endif
        if (t->off_owner_sid != 0)
        {
                if (ps->io)
                {
                        ps->offset = old_offset + t->off_owner_sid;
-                       }
+               }
                if (ps->io)
                {
                        /* reading */
-                       t->owner_sid = (DOM_SID*)malloc(sizeof(*t->owner_sid));
+                       t->owner_sid =
+                               (DOM_SID *)malloc(sizeof(*t->owner_sid));
                        ZERO_STRUCTP(t->owner_sid);
                }
 
                if (t->owner_sid == NULL)
                {
-                       DEBUG(0,("INVALID OWNER SID\n"));
+                       DEBUG(0, ("INVALID OWNER SID\n"));
                        ps->offset = 0xfffffffe;
                        return False;
                }
 
-               smb_io_dom_sid("owner_sid ", t->owner_sid , ps, depth);
+               smb_io_dom_sid("owner_sid ", t->owner_sid, ps, depth);
                prs_align(ps);
        }
 
        max_offset = MAX(max_offset, ps->offset);
 
 #if 0
-       prs_uint32_post("off_grp_sid  ", ps, depth, &(t->off_grp_sid  ), off_grp_sid  , ps->offset - old_offset);
+       prs_uint32_post("off_grp_sid  ", ps, depth, &(t->off_grp_sid),
+                       off_grp_sid, ps->offset - old_offset);
 #endif
        if (t->off_grp_sid != 0)
        {
@@ -433,13 +460,13 @@ BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
                if (ps->io)
                {
                        /* reading */
-                       t->grp_sid = (DOM_SID*)malloc(sizeof(*t->grp_sid));
+                       t->grp_sid = (DOM_SID *)malloc(sizeof(*t->grp_sid));
                        ZERO_STRUCTP(t->grp_sid);
                }
 
                if (t->grp_sid == NULL)
                {
-                       DEBUG(0,("INVALID GROUP SID\n"));
+                       DEBUG(0, ("INVALID GROUP SID\n"));
                        ps->offset = 0xfffffffe;
                        return False;
                }
@@ -458,13 +485,13 @@ BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
 /*******************************************************************
 creates a SEC_DESC_BUF structure.
 ********************************************************************/
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
+BOOL make_sec_desc_buf(SEC_DESC_BUF * buf, int len, SEC_DESC * data)
 {
        ZERO_STRUCTP(buf);
 
        /* max buffer size (allocated size) */
        buf->max_len = len;
-       buf->undoc       = 0;
+       buf->undoc = 0;
        buf->len = data != NULL ? len : 0;
        buf->sec = data;
 
@@ -474,9 +501,10 @@ BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
 /*******************************************************************
 frees a SEC_DESC_BUF structure.
 ********************************************************************/
-void free_sec_desc_buf(SEC_DESC_BUF *buf)
+void free_sec_desc_buf(SEC_DESC_BUF * buf)
 {
-       if (buf == NULL) return;
+       if (buf == NULL)
+               return;
        if (buf->sec != NULL)
        {
                free_sec_desc(buf->sec);
@@ -489,35 +517,37 @@ void free_sec_desc_buf(SEC_DESC_BUF *buf)
 /*******************************************************************
 reads or writes a SEC_DESC_BUF structure.
 ********************************************************************/
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF * sec, prs_struct *ps,
+                    int depth)
 {
        uint32 off_len;
        uint32 off_max_len;
        uint32 old_offset;
        uint32 size;
 
-       if (sec == NULL) return False;
+       if (sec == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_desc_buf");
        depth++;
 
        prs_align(ps);
-       
+
        prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len);
-       prs_uint32    ("undoc  ", ps, depth, &(sec->undoc  ));
-       prs_uint32_pre("len    ", ps, depth, &(sec->len    ), &off_len);
+       prs_uint32("undoc  ", ps, depth, &(sec->undoc));
+       prs_uint32_pre("len    ", ps, depth, &(sec->len), &off_len);
 
        old_offset = ps->offset;
 
        if (sec->len != 0 && ps->io)
        {
                /* reading */
-               sec->sec = (SEC_DESC*)malloc(sizeof(*sec->sec));
+               sec->sec = (SEC_DESC *) malloc(sizeof(*sec->sec));
                ZERO_STRUCTP(sec->sec);
 
                if (sec->sec == NULL)
                {
-                       DEBUG(0,("INVALID SEC_DESC\n"));
+                       DEBUG(0, ("INVALID SEC_DESC\n"));
                        ps->offset = 0xfffffffe;
                        return False;
                }
@@ -530,13 +560,14 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
        }
 
        prs_align(ps);
-       
+
        size = ps->offset - old_offset - 8;
-       prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size + 8);
-       prs_uint32_post("len    ", ps, depth, &(sec->len    ), off_len    , size == 0 ? 0 : size + 8);
+       prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len,
+                       size == 0 ? sec->max_len : size + 8);
+       prs_uint32_post("len    ", ps, depth, &(sec->len), off_len,
+                       size == 0 ? 0 : size + 8);
 
        ps->offset = old_offset + size + 8;
 
        return True;
 }
-
index 6da133a2a57ad3fb5aea89c53558d81845e53ace..cbe5a7057a0361c3547fd1d4f08b2f7996d2fd68 100644 (file)
@@ -123,8 +123,8 @@ static BOOL srv_io_sh_info1_hdr(char *desc, SH_INFO_1 * sh1,
  makes a SHARE_INFO_1 structure
 ********************************************************************/
 static BOOL make_srv_share_info_1(SHARE_INFO_1 * sh1,
-                          const char *net_name, uint32 type,
-                          const char *remark)
+                                 const char *net_name, uint32 type,
+                                 const char *remark)
 {
        if (sh1 == NULL)
                return False;
@@ -847,7 +847,7 @@ BOOL make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM * q_n,
        q_n->share_level = share_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       q_n->enum_hnd = *hnd;
 
        return True;
 }
@@ -1395,7 +1395,7 @@ BOOL make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM * q_n,
        q_n->sess_level = sess_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       q_n->enum_hnd = *hnd;
 
        return True;
 }
@@ -1752,7 +1752,7 @@ BOOL make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM * q_n,
        q_n->conn_level = conn_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       q_n->enum_hnd = *hnd;
 
        return True;
 }
@@ -2077,7 +2077,7 @@ BOOL make_srv_q_net_tprt_enum(SRV_Q_NET_TPRT_ENUM * q_n,
        q_n->tprt_level = tprt_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       q_n->enum_hnd = *hnd;
 
        return True;
 }
@@ -2409,7 +2409,7 @@ BOOL make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM * q_n,
        q_n->file_level = file_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       q_n->enum_hnd = *hnd;
 
        return True;
 }
index 755dba86a82584464bed4489a0a2aa70c1871a57..6d6271840e22ee51704e034deb10f90873535cb9 100644 (file)
@@ -31,14 +31,14 @@ extern int DEBUGLEVEL;
 /*******************************************************************
  make_svc_q_open_sc_man
  ********************************************************************/
-BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
-                                   const char *server, const char *database,
-                                   uint32 des_access)
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN * q_u,
+                           const char *server, const char *database,
+                           uint32 des_access)
 {
-       DEBUG(5,("make_svc_q_open_sc_man\n"));
+       DEBUG(5, ("make_svc_q_open_sc_man\n"));
 
        make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
-       make_buf_unistr2(&(q_u->uni_db_name ), &(q_u->ptr_db_name), database);
+       make_buf_unistr2(&(q_u->uni_db_name), &(q_u->ptr_db_name), database);
        q_u->des_access = des_access;
 
        return True;
@@ -47,9 +47,11 @@ BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
 /*******************************************************************
 reads or writes a SVC_Q_OPEN_SC_MAN structure.
 ********************************************************************/
-BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN * q_u, prs_struct *ps,
+                         int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_open_sc_man");
        depth++;
@@ -57,11 +59,12 @@ BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, in
        prs_align(ps);
 
        prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
-       smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps,
+                      depth);
        prs_align(ps);
 
        prs_uint32("ptr_db_name", ps, depth, &(q_u->ptr_db_name));
-       smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth);
        prs_align(ps);
 
        prs_uint32("des_access", ps, depth, &(q_u->des_access));
@@ -73,9 +76,11 @@ BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, in
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_open_sc_man(char *desc,  SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN * r_u, prs_struct *ps,
+                         int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_open_sc_man");
        depth++;
@@ -92,15 +97,14 @@ BOOL svc_io_r_open_sc_man(char *desc,  SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, i
 /*******************************************************************
  make_svc_q_open_service
  ********************************************************************/
-BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
-                                    POLICY_HND *hnd,
-                                    const char *server,
-                                    uint32 des_access)
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE * q_u,
+                            POLICY_HND *hnd,
+                            const char *server, uint32 des_access)
 {
-       DEBUG(5,("make_svc_q_open_service\n"));
+       DEBUG(5, ("make_svc_q_open_service\n"));
 
-       memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol));
-       make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1);
+       q_u->scman_pol = *hnd;
+       make_unistr2(&(q_u->uni_svc_name), server, strlen(server) + 1);
        q_u->des_access = des_access;
 
 
@@ -110,9 +114,11 @@ BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
 /*******************************************************************
 reads or writes a SVC_Q_OPEN_SERVICE structure.
 ********************************************************************/
-BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE * q_u,
+                          prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_open_service");
        depth++;
@@ -122,7 +128,7 @@ BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps,
        smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
        prs_align(ps);
 
-       smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth);
        prs_align(ps);
 
        prs_uint32("des_access", ps, depth, &(q_u->des_access));
@@ -134,9 +140,11 @@ BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_open_service(char *desc,  SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE * r_u,
+                          prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_open_service");
        depth++;
@@ -153,14 +161,15 @@ BOOL svc_io_r_open_service(char *desc,  SVC_R_OPEN_SERVICE *r_u, prs_struct *ps,
 /*******************************************************************
 makes an SVC_Q_STOP_SERVICE structure.
 ********************************************************************/
-BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
-                               uint32 unk)
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE * q_c, POLICY_HND *hnd,
+                            uint32 unk)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_stop_service\n"));
+       DEBUG(5, ("make_svc_q_stop_service\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
        q_c->unknown = unk;
 
        return True;
@@ -169,9 +178,11 @@ BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a SVC_Q_STOP_SERVICE structure.
 ********************************************************************/
-BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth)
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE * q_s,
+                          prs_struct *ps, int depth)
 {
-       if (q_s == NULL) return False;
+       if (q_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_stop_service");
        depth++;
@@ -188,9 +199,11 @@ BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_stop_service(char *desc,  SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth)
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE * r_s,
+                          prs_struct *ps, int depth)
 {
-       if (r_s == NULL) return False;
+       if (r_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_stop_service");
        depth++;
@@ -210,24 +223,24 @@ BOOL svc_io_r_stop_service(char *desc,  SVC_R_STOP_SERVICE *r_s, prs_struct *ps,
 /*******************************************************************
 makes an SVC_Q_START_SERVICE structure.
 ********************************************************************/
-BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
-                               uint32 argc,
-                               char **argv)
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE * q_c, POLICY_HND *hnd,
+                             uint32 argc, char **argv)
 {
        uint32 i;
 
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_start_service\n"));
+       DEBUG(5, ("make_svc_q_start_service\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
        q_c->argc = argc;
        q_c->ptr_args = 1;
        q_c->argc2 = argc;
 
        for (i = 0; i < argc; i++)
        {
-               size_t len_argv = argv[i] != NULL ? strlen(argv[i])+1 : 0;
+               size_t len_argv = argv[i] != NULL ? strlen(argv[i]) + 1 : 0;
                q_c->ptr_argv[i] = argv[i] != NULL ? 1 : 0;
                make_unistr2(&(q_c->argv[i]), argv[i], len_argv);
        }
@@ -238,9 +251,11 @@ BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a SVC_Q_START_SERVICE structure.
 ********************************************************************/
-BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth)
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE * q_s,
+                           prs_struct *ps, int depth)
 {
-       if (q_s == NULL) return False;
+       if (q_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_start_service");
        depth++;
@@ -249,7 +264,7 @@ BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps
        smb_io_pol_hnd("", &(q_s->pol), ps, depth);
 
        prs_align(ps);
-       prs_uint32("argc    ", ps, depth, &(q_s->argc    ));
+       prs_uint32("argc    ", ps, depth, &(q_s->argc));
        prs_uint32("ptr_args", ps, depth, &(q_s->ptr_args));
 
        if (q_s->ptr_args != 0)
@@ -265,11 +280,12 @@ BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps
 
                for (i = 0; i < q_s->argc2; i++)
                {
-                       prs_uint32("", ps, depth, &(q_s->ptr_argv[i])); 
+                       prs_uint32("", ps, depth, &(q_s->ptr_argv[i]));
                }
                for (i = 0; i < q_s->argc2; i++)
                {
-                       smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i], ps, depth); 
+                       smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i],
+                                      ps, depth);
                        prs_align(ps);
                }
        }
@@ -280,9 +296,11 @@ BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_start_service(char *desc,  SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth)
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE * r_s,
+                           prs_struct *ps, int depth)
 {
-       if (r_s == NULL) return False;
+       if (r_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_start_service");
        depth++;
@@ -295,25 +313,30 @@ BOOL svc_io_r_start_service(char *desc,  SVC_R_START_SERVICE *r_s, prs_struct *p
 /*******************************************************************
  make_svc_query_svc_cfg
  ********************************************************************/
-BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
-                               uint32 service_type, uint32 start_type,
-                               uint32 error_control,
-                               char* bin_path_name, char* load_order_grp, 
-                               uint32 tag_id,
-                               char* dependencies, char* service_start_name,
-                               char* disp_name)
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG * q_u,
+                           uint32 service_type, uint32 start_type,
+                           uint32 error_control,
+                           char *bin_path_name, char *load_order_grp,
+                           uint32 tag_id,
+                           char *dependencies, char *service_start_name,
+                           char *disp_name)
 {
-       DEBUG(5,("make_svc_query_svc_cfg\n"));
+       DEBUG(5, ("make_svc_query_svc_cfg\n"));
 
        q_u->service_type = service_type;
        q_u->start_type = start_type;
        q_u->error_control = error_control;
-       make_buf_unistr2(&(q_u->uni_bin_path_name     ), &(q_u->ptr_bin_path_name     ), bin_path_name     );
-       make_buf_unistr2(&(q_u->uni_load_order_grp    ), &(q_u->ptr_load_order_grp    ), load_order_grp    );
+       make_buf_unistr2(&(q_u->uni_bin_path_name), &(q_u->ptr_bin_path_name),
+                        bin_path_name);
+       make_buf_unistr2(&(q_u->uni_load_order_grp),
+                        &(q_u->ptr_load_order_grp), load_order_grp);
        q_u->tag_id = tag_id;
-       make_buf_unistr2(&(q_u->uni_dependencies      ), &(q_u->ptr_dependencies      ), dependencies      );
-       make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
-       make_buf_unistr2(&(q_u->uni_display_name      ), &(q_u->ptr_display_name      ), disp_name         );
+       make_buf_unistr2(&(q_u->uni_dependencies), &(q_u->ptr_dependencies),
+                        dependencies);
+       make_buf_unistr2(&(q_u->uni_service_start_name),
+                        &(q_u->ptr_service_start_name), service_start_name);
+       make_buf_unistr2(&(q_u->uni_display_name), &(q_u->ptr_display_name),
+                        disp_name);
 
        return True;
 }
@@ -321,34 +344,48 @@ BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
 /*******************************************************************
 reads or writes a QUERY_SERVICE_CONFIG structure.
 ********************************************************************/
-BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG * q_u,
+                         prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_query_svc_cfg");
        depth++;
 
        prs_align(ps);
 
-       prs_uint32("service_type          ", ps, depth, &(q_u->service_type          ));
-       prs_uint32("start_type            ", ps, depth, &(q_u->start_type            ));
-       prs_uint32("error_control         ", ps, depth, &(q_u->error_control         ));
-       prs_uint32("ptr_bin_path_name     ", ps, depth, &(q_u->ptr_bin_path_name     ));
-       prs_uint32("ptr_load_order_grp    ", ps, depth, &(q_u->ptr_load_order_grp    ));
-       prs_uint32("tag_id                ", ps, depth, &(q_u->tag_id                ));
-       prs_uint32("ptr_dependencies      ", ps, depth, &(q_u->ptr_dependencies      ));
-       prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
-       prs_uint32("ptr_display_name      ", ps, depth, &(q_u->ptr_display_name      ));
+       prs_uint32("service_type          ", ps, depth, &(q_u->service_type));
+       prs_uint32("start_type            ", ps, depth, &(q_u->start_type));
+       prs_uint32("error_control         ", ps, depth,
+                  &(q_u->error_control));
+       prs_uint32("ptr_bin_path_name     ", ps, depth,
+                  &(q_u->ptr_bin_path_name));
+       prs_uint32("ptr_load_order_grp    ", ps, depth,
+                  &(q_u->ptr_load_order_grp));
+       prs_uint32("tag_id                ", ps, depth, &(q_u->tag_id));
+       prs_uint32("ptr_dependencies      ", ps, depth,
+                  &(q_u->ptr_dependencies));
+       prs_uint32("ptr_service_start_name", ps, depth,
+                  &(q_u->ptr_service_start_name));
+       prs_uint32("ptr_display_name      ", ps, depth,
+                  &(q_u->ptr_display_name));
 
-       smb_io_unistr2("uni_bin_path_name     ", &(q_u->uni_bin_path_name     ), q_u->ptr_bin_path_name     , ps, depth); 
+       smb_io_unistr2("uni_bin_path_name     ", &(q_u->uni_bin_path_name),
+                      q_u->ptr_bin_path_name, ps, depth);
        prs_align(ps);
-       smb_io_unistr2("uni_load_order_grp    ", &(q_u->uni_load_order_grp    ), q_u->ptr_load_order_grp    , ps, depth); 
+       smb_io_unistr2("uni_load_order_grp    ", &(q_u->uni_load_order_grp),
+                      q_u->ptr_load_order_grp, ps, depth);
        prs_align(ps);
-       smb_io_unistr2("uni_dependencies      ", &(q_u->uni_dependencies      ), q_u->ptr_dependencies      , ps, depth); 
+       smb_io_unistr2("uni_dependencies      ", &(q_u->uni_dependencies),
+                      q_u->ptr_dependencies, ps, depth);
        prs_align(ps);
-       smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth); 
+       smb_io_unistr2("uni_service_start_name",
+                      &(q_u->uni_service_start_name),
+                      q_u->ptr_service_start_name, ps, depth);
        prs_align(ps);
-       smb_io_unistr2("uni_display_name      ", &(q_u->uni_display_name      ), q_u->ptr_display_name      , ps, depth); 
+       smb_io_unistr2("uni_display_name      ", &(q_u->uni_display_name),
+                      q_u->ptr_display_name, ps, depth);
        prs_align(ps);
 
        return True;
@@ -357,15 +394,17 @@ BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps,
 /*******************************************************************
 makes an SVC_Q_ENUM_SVCS_STATUS structure.
 ********************************************************************/
-BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
-                               uint32 service_type, uint32 service_state,
-                               uint32 buf_size, uint32 resume_hnd )
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS * q_c,
+                                POLICY_HND *hnd, uint32 service_type,
+                                uint32 service_state, uint32 buf_size,
+                                uint32 resume_hnd)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_enum_svcs_status\n"));
+       DEBUG(5, ("make_svc_q_enum_svcs_status\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
        q_c->service_type = service_type;
        q_c->service_state = service_state;
        q_c->buf_size = buf_size;
@@ -377,22 +416,24 @@ BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS * q_u,
+                              prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_enum_svcs_status");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->pol), ps, depth);
        prs_align(ps);
 
-       prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
+       prs_uint32("service_type ", ps, depth, &(q_u->service_type));
        prs_uint32("service_state", ps, depth, &(q_u->service_state));
-       prs_uint32("buf_size     ", ps, depth, &(q_u->buf_size     ));
-       smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth); 
+       prs_uint32("buf_size     ", ps, depth, &(q_u->buf_size));
+       smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth);
 
        return True;
 }
@@ -400,19 +441,20 @@ BOOL svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_str
 /*******************************************************************
 makes an SVC_R_ENUM_SVCS_STATUS structure.
 ********************************************************************/
-BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c, 
-                               ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
-                               uint32 num_svcs, ENUM_HND *resume_hnd,
-                               uint32 dos_status)
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS * r_c,
+                                ENUM_SRVC_STATUS * svcs,
+                                uint32 more_buf_size, uint32 num_svcs,
+                                ENUM_HND * resume_hnd, uint32 dos_status)
 {
-       if (r_c == NULL) return False;
+       if (r_c == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_r_enum_svcs_status\n"));
+       DEBUG(5, ("make_svc_r_enum_svcs_status\n"));
 
-       r_c->svcs          = svcs;
+       r_c->svcs = svcs;
        r_c->more_buf_size = more_buf_size;
-       r_c->num_svcs      = num_svcs;
-       memcpy(&(r_c->resume_hnd), resume_hnd, sizeof(ENUM_HND));
+       r_c->num_svcs = num_svcs;
+       r_c->resume_hnd = *resume_hnd;
        r_c->dos_status = dos_status;
 
        return True;
@@ -426,16 +468,18 @@ not COMMUNICATE and get some CONSISTENCY TO THEIR DATA STRUCTURES!
 ARGH!
 
 ********************************************************************/
-BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth)
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS * svc,
+                              prs_struct *ps, int depth)
 {
        uint32 i;
-       if (svc == NULL) return False;
+       if (svc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_enum_svcs_status");
        depth++;
 
        prs_align(ps);
-       
+
        /*
         * format is actually as laid out in SVC_R_ENUM_SVCS_STATUS.
         * the reason for all the jumping about, which is horrible
@@ -462,23 +506,27 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
 
                prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
                prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
-               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
+               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
                prs_uint32("dos_status", ps, depth, &(svc->dos_status));
 
                new_offset = ps->offset;
                ps->offset = buf_offset;
 
-               svc->svcs = (ENUM_SRVC_STATUS*)Realloc(NULL,
-                           svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+               svc->svcs = (ENUM_SRVC_STATUS *) Realloc(NULL,
+                                                        svc->num_svcs *
+                                                        sizeof
+                                                        (ENUM_SRVC_STATUS));
 
                if (svc->svcs == NULL)
                {
-                       DEBUG(0,("svc_io_r_enum_svcs_status: Realloc failed\n"));
+                       DEBUG(0,
+                             ("svc_io_r_enum_svcs_status: Realloc failed\n"));
                        ps->offset = 0x7fffffff;
                        return False;
                }
 
-               memset(svc->svcs, 0,  svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+               memset(svc->svcs, 0,
+                      svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
 
                for (i = 0; i < svc->num_svcs; i++)
                {
@@ -489,17 +537,20 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
 
                        prs_uint32("srvc_offset", ps, depth, &srvc_offset);
                        prs_uint32("disp_offset", ps, depth, &disp_offset);
-                       svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
+                       svc_io_svc_status("status", &svc->svcs[i].status, ps,
+                                         depth);
 
                        old_offset = ps->offset;
 
                        ps->offset = buf_offset + srvc_offset;
-                       slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
-                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+                       slprintf(name, sizeof(name) - 1, "srvc[%02d]", i);
+                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps,
+                                     depth);
 
                        ps->offset = buf_offset + disp_offset;
-                       slprintf(name, sizeof(name)-1, "disp[%02d]", i);
-                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+                       slprintf(name, sizeof(name) - 1, "disp[%02d]", i);
+                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps,
+                                     depth);
 
                        ps->offset = old_offset;
                }
@@ -514,7 +565,8 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
                uint32 old_buf_offset;
                uint32 srvc_offset = 9 * sizeof(uint32) * svc->num_svcs;
 
-               prs_uint32_pre("buf_size", ps, depth, &svc->buf_size, &buf_offset);
+               prs_uint32_pre("buf_size", ps, depth, &svc->buf_size,
+                              &buf_offset);
                old_buf_offset = ps->offset;
 
                srvc_offset += old_buf_offset;
@@ -537,11 +589,12 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
                        prs_uint32("srvc_offset", ps, depth, &srvc_offset);
                        srvc_offset += old_buf_offset;
 
-                       slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+                       slprintf(name, sizeof(name) - 1, "srvc[%02d]", i);
 
                        old_offset = ps->offset;
                        ps->offset = srvc_offset;
-                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps,
+                                     depth);
                        srvc_offset = ps->offset;
                        ps->offset = old_offset;
 
@@ -553,11 +606,12 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
                        prs_uint32("disp_offset", ps, depth, &srvc_offset);
                        srvc_offset += old_buf_offset;
 
-                       slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+                       slprintf(name, sizeof(name) - 1, "disp[%02d]", i);
 
                        old_offset = ps->offset;
                        ps->offset = srvc_offset;
-                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps,
+                                     depth);
                        srvc_offset = ps->offset;
                        ps->offset = old_offset;
 
@@ -565,10 +619,13 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
                         * store status info
                         */
 
-                       svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
+                       svc_io_svc_status("status", &svc->svcs[i].status, ps,
+                                         depth);
                }
 
-               prs_uint32_post("buf_size", ps, depth, &svc->buf_size, buf_offset, srvc_offset - buf_offset - sizeof(uint32));
+               prs_uint32_post("buf_size", ps, depth, &svc->buf_size,
+                               buf_offset,
+                               srvc_offset - buf_offset - sizeof(uint32));
 
                ps->offset = srvc_offset;
 
@@ -576,7 +633,7 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
 
                prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
                prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
-               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
+               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
                prs_uint32("dos_status", ps, depth, &(svc->dos_status));
        }
 
@@ -586,9 +643,11 @@ BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_stru
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth)
+BOOL svc_io_svc_status(char *desc, SVC_STATUS * svc, prs_struct *ps,
+                      int depth)
 {
-       if (svc == NULL) return False;
+       if (svc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_svc_status");
        depth++;
@@ -599,7 +658,8 @@ BOOL svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth)
        prs_uint32("current_state", ps, depth, &(svc->current_state));
        prs_uint32("controls_accepted", ps, depth, &(svc->controls_accepted));
        prs_uint32("win32_exit_code", ps, depth, &(svc->win32_exit_code));
-       prs_uint32("svc_specific_exit_code", ps, depth, &(svc->svc_specific_exit_code));
+       prs_uint32("svc_specific_exit_code", ps, depth,
+                  &(svc->svc_specific_exit_code));
        prs_uint32("check_point", ps, depth, &(svc->check_point));
        prs_uint32("wait_hint", ps, depth, &(svc->wait_hint));
 
@@ -609,14 +669,15 @@ BOOL svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth)
 /*******************************************************************
 makes an SVC_Q_QUERY_SVC_CONFIG structure.
 ********************************************************************/
-BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
-                               uint32 buf_size)
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG * q_c,
+                                POLICY_HND *hnd, uint32 buf_size)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_query_svc_config\n"));
+       DEBUG(5, ("make_svc_q_query_svc_config\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
        q_c->buf_size = buf_size;
 
        return True;
@@ -625,16 +686,18 @@ BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG * q_u,
+                              prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_query_svc_config");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->pol), ps, depth);
        prs_align(ps);
        prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
 
@@ -644,15 +707,15 @@ BOOL svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_str
 /*******************************************************************
 makes an SVC_R_QUERY_SVC_CONFIG structure.
 ********************************************************************/
-BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, 
-                               QUERY_SERVICE_CONFIG *cfg,
-                               uint32 buf_size)
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG * r_c,
+                                QUERY_SERVICE_CONFIG * cfg, uint32 buf_size)
 {
-       if (r_c == NULL) return False;
+       if (r_c == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_r_query_svc_config\n"));
+       DEBUG(5, ("make_svc_r_query_svc_config\n"));
 
-       r_c->cfg      = cfg;
+       r_c->cfg = cfg;
        r_c->buf_size = buf_size;
 
        return True;
@@ -661,18 +724,20 @@ BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_query_svc_config(char *desc,  SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG * r_u,
+                              prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_query_svc_config");
        depth++;
 
        prs_align(ps);
 
-       svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth); 
+       svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth);
        prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
-       prs_uint32("status  ", ps, depth, &(r_u->status  ));
+       prs_uint32("status  ", ps, depth, &(r_u->status));
 
        return True;
 }
@@ -680,19 +745,21 @@ BOOL svc_io_r_query_svc_config(char *desc,  SVC_R_QUERY_SVC_CONFIG *r_u, prs_str
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME * q_u,
+                             prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_query_disp_name");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
        prs_align(ps);
 
-       smb_io_unistr2("uni_svc_name", &(q_u->uni_svc_name), 1, ps, depth); 
+       smb_io_unistr2("uni_svc_name", &(q_u->uni_svc_name), 1, ps, depth);
        prs_align(ps);
 
        prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
@@ -703,20 +770,22 @@ BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME * r_u,
+                             prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_query_disp_name");
        depth++;
 
        prs_align(ps);
 
-       smb_io_unistr2("uni_disp_name", &(r_u->uni_disp_name), 1, ps, depth); 
+       smb_io_unistr2("uni_disp_name", &(r_u->uni_disp_name), 1, ps, depth);
        prs_align(ps);
 
        prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
-       prs_uint32("status  ", ps, depth, &(r_u->status  ));
+       prs_uint32("status  ", ps, depth, &(r_u->status));
 
        return True;
 }
@@ -724,13 +793,14 @@ BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct
 /*******************************************************************
 makes an SVC_Q_CLOSE structure.
 ********************************************************************/
-BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_svc_q_close(SVC_Q_CLOSE * q_c, POLICY_HND *hnd)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       if (q_c == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_close\n"));
+       DEBUG(5, ("make_svc_q_close\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+       q_c->pol = *hnd;
 
        return True;
 }
@@ -738,16 +808,17 @@ BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_close(char *desc,  SVC_Q_CLOSE *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE * q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_close");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->pol), ps, depth);
        prs_align(ps);
 
        return True;
@@ -756,16 +827,17 @@ BOOL svc_io_q_close(char *desc,  SVC_Q_CLOSE *q_u, prs_struct *ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE * r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_close");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(r_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(r_u->pol), ps, depth);
        prs_align(ps);
 
        prs_uint32("status", ps, depth, &(r_u->status));
@@ -776,33 +848,39 @@ BOOL svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
 /*******************************************************************
 makes an SVC_Q_CHANGE_SVC_CONFIG structure.
 ********************************************************************/
-BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
-                               uint32 service_type, uint32 start_type,
-                               uint32 unknown_0,
-                               uint32 error_control,
-                               char* bin_path_name, char* load_order_grp, 
-                               uint32 tag_id,
-                               char* dependencies, char* service_start_name,
-                               char* password,
-                               char* disp_name)
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG * q_u,
+                                 POLICY_HND *hnd, uint32 service_type,
+                                 uint32 start_type, uint32 unknown_0,
+                                 uint32 error_control, char *bin_path_name,
+                                 char *load_order_grp, uint32 tag_id,
+                                 char *dependencies,
+                                 char *service_start_name, char *password,
+                                 char *disp_name)
 {
-       if (q_u == NULL || hnd == NULL) return False;
+       if (q_u == NULL || hnd == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_q_change_svc_config\n"));
+       DEBUG(5, ("make_svc_q_change_svc_config\n"));
 
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+       q_u->pol = *hnd;
 
        q_u->service_type = service_type;
        q_u->start_type = start_type;
        q_u->unknown_0 = unknown_0;
        q_u->error_control = error_control;
-       make_buf_unistr2(&(q_u->uni_bin_path_name     ), &(q_u->ptr_bin_path_name     ), bin_path_name     );
-       make_buf_unistr2(&(q_u->uni_load_order_grp    ), &(q_u->ptr_load_order_grp    ), load_order_grp    );
+       make_buf_unistr2(&(q_u->uni_bin_path_name), &(q_u->ptr_bin_path_name),
+                        bin_path_name);
+       make_buf_unistr2(&(q_u->uni_load_order_grp),
+                        &(q_u->ptr_load_order_grp), load_order_grp);
        q_u->tag_id = tag_id;
-       make_buf_unistr2(&(q_u->uni_dependencies      ), &(q_u->ptr_dependencies      ), dependencies      );
-       make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
-       make_buf_string2(&(q_u->str_password          ), &(q_u->ptr_password          ), password          );
-       make_buf_unistr2(&(q_u->uni_display_name      ), &(q_u->ptr_display_name      ), disp_name         );
+       make_buf_unistr2(&(q_u->uni_dependencies), &(q_u->ptr_dependencies),
+                        dependencies);
+       make_buf_unistr2(&(q_u->uni_service_start_name),
+                        &(q_u->ptr_service_start_name), service_start_name);
+       make_buf_string2(&(q_u->str_password), &(q_u->ptr_password),
+                        password);
+       make_buf_unistr2(&(q_u->uni_display_name), &(q_u->ptr_display_name),
+                        disp_name);
 
        return True;
 }
@@ -810,43 +888,58 @@ BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_change_svc_config(char *desc,  SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG * q_u,
+                               prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_change_svc_config");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
+       smb_io_pol_hnd("", &(q_u->pol), ps, depth);
        prs_align(ps);
 
-       prs_uint32("service_type          ", ps, depth, &(q_u->service_type          ));
-       prs_uint32("start_type            ", ps, depth, &(q_u->start_type            ));
-       prs_uint32("unknown_0             ", ps, depth, &(q_u->unknown_0             ));
-       prs_uint32("error_control         ", ps, depth, &(q_u->error_control         ));
-       prs_uint32("ptr_bin_path_name     ", ps, depth, &(q_u->ptr_bin_path_name     ));
-       smb_io_unistr2("uni_bin_path_name     ", &(q_u->uni_bin_path_name     ), q_u->ptr_bin_path_name     , ps, depth); 
+       prs_uint32("service_type          ", ps, depth, &(q_u->service_type));
+       prs_uint32("start_type            ", ps, depth, &(q_u->start_type));
+       prs_uint32("unknown_0             ", ps, depth, &(q_u->unknown_0));
+       prs_uint32("error_control         ", ps, depth,
+                  &(q_u->error_control));
+       prs_uint32("ptr_bin_path_name     ", ps, depth,
+                  &(q_u->ptr_bin_path_name));
+       smb_io_unistr2("uni_bin_path_name     ", &(q_u->uni_bin_path_name),
+                      q_u->ptr_bin_path_name, ps, depth);
        prs_align(ps);
 
-       prs_uint32("ptr_load_order_grp    ", ps, depth, &(q_u->ptr_load_order_grp    ));
-       smb_io_unistr2("uni_load_order_grp    ", &(q_u->uni_load_order_grp    ), q_u->ptr_load_order_grp    , ps, depth); 
+       prs_uint32("ptr_load_order_grp    ", ps, depth,
+                  &(q_u->ptr_load_order_grp));
+       smb_io_unistr2("uni_load_order_grp    ", &(q_u->uni_load_order_grp),
+                      q_u->ptr_load_order_grp, ps, depth);
        prs_align(ps);
-       prs_uint32("tag_id                ", ps, depth, &(q_u->tag_id                ));
-       prs_uint32("ptr_dependencies      ", ps, depth, &(q_u->ptr_dependencies      ));
-       smb_io_unistr2("uni_dependencies      ", &(q_u->uni_dependencies      ), q_u->ptr_dependencies      , ps, depth); 
+       prs_uint32("tag_id                ", ps, depth, &(q_u->tag_id));
+       prs_uint32("ptr_dependencies      ", ps, depth,
+                  &(q_u->ptr_dependencies));
+       smb_io_unistr2("uni_dependencies      ", &(q_u->uni_dependencies),
+                      q_u->ptr_dependencies, ps, depth);
        prs_align(ps);
-       prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
-       smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth); 
+       prs_uint32("ptr_service_start_name", ps, depth,
+                  &(q_u->ptr_service_start_name));
+       smb_io_unistr2("uni_service_start_name",
+                      &(q_u->uni_service_start_name),
+                      q_u->ptr_service_start_name, ps, depth);
        prs_align(ps);
-       prs_uint32("ptr_password          ", ps, depth, &(q_u->ptr_password          ));
+       prs_uint32("ptr_password          ", ps, depth, &(q_u->ptr_password));
 
-       smb_io_string2("str_password          ", &(q_u->str_password          ), q_u->ptr_display_name      , ps, depth); 
+       smb_io_string2("str_password          ", &(q_u->str_password),
+                      q_u->ptr_display_name, ps, depth);
        prs_align(ps);
 
-       prs_uint32("ptr_display_name      ", ps, depth, &(q_u->ptr_display_name      ));
-       smb_io_unistr2("uni_display_name      ", &(q_u->uni_display_name      ), q_u->ptr_display_name      , ps, depth); 
+       prs_uint32("ptr_display_name      ", ps, depth,
+                  &(q_u->ptr_display_name));
+       smb_io_unistr2("uni_display_name      ", &(q_u->uni_display_name),
+                      q_u->ptr_display_name, ps, depth);
        prs_align(ps);
 
        return True;
@@ -855,12 +948,13 @@ BOOL svc_io_q_change_svc_config(char *desc,  SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_s
 /*******************************************************************
 makes an SVC_R_CHANGE_SVC_CONFIG structure.
 ********************************************************************/
-BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c, 
-                               uint32 unknown_0, uint32 status)
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG * r_c,
+                                 uint32 unknown_0, uint32 status)
 {
-       if (r_c == NULL) return False;
+       if (r_c == NULL)
+               return False;
 
-       DEBUG(5,("make_svc_r_change_svc_config\n"));
+       DEBUG(5, ("make_svc_r_change_svc_config\n"));
 
        r_c->unknown_0 = unknown_0;
        r_c->status = status;
@@ -871,9 +965,11 @@ BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_change_svc_config(char *desc,  SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG * r_u,
+                               prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_change_svc_config");
        depth++;
@@ -881,7 +977,7 @@ BOOL svc_io_r_change_svc_config(char *desc,  SVC_R_CHANGE_SVC_CONFIG *r_u, prs_s
        prs_align(ps);
 
        prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
-       prs_uint32("status   ", ps, depth, &(r_u->status   ));
+       prs_uint32("status   ", ps, depth, &(r_u->status));
 
        return True;
 }
@@ -889,10 +985,11 @@ BOOL svc_io_r_change_svc_config(char *desc,  SVC_R_CHANGE_SVC_CONFIG *r_u, prs_s
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
+BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 * q_u,
                        prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_q_unknown_3");
        depth++;
@@ -905,10 +1002,11 @@ BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 * r_u,
                        prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "svc_io_r_unknown_3");
        depth++;
index c8b522d6e7916b2971a6920a8db9732a3e15252f..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
+.libs
 *.lo
index 0e1d3b5581aeb3bcacc1254b7d65e9a220b34e40..b87f23c84dfa17d0fd494ec858ec99f90ff374dc 100644 (file)
@@ -40,15 +40,15 @@ static BOOL set_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
        char *dev = strdup(name);
        if (dev != NULL)
        {
-               if (set_policy_state(cache, hnd, NULL, (void*)dev))
+               if (set_policy_state(cache, hnd, NULL, (void *)dev))
                {
-                       DEBUG(3,("Registry setting policy name=%s\n", name));
+                       DEBUG(3, ("Registry setting policy name=%s\n", name));
                        return True;
                }
                free(dev);
        }
 
-       DEBUG(3,("Error setting policy name=%s\n", name));
+       DEBUG(3, ("Error setting policy name=%s\n", name));
        return False;
 }
 #endif
@@ -58,81 +58,79 @@ static BOOL set_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
 static BOOL get_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
                                fstring name)
 {
-       char *dev = (char*)get_policy_state_info(cache, hnd);
+       char *dev = (char *)get_policy_state_info(cache, hnd);
 
        if (dev != NULL)
        {
                fstrcpy(name, dev);
-               DEBUG(5,("getting policy reg name=%s\n", name));
+               DEBUG(5, ("getting policy reg name=%s\n", name));
                return True;
        }
 
-       DEBUG(3,("Error getting policy reg name\n"));
+       DEBUG(3, ("Error getting policy reg name\n"));
        return False;
 }
 
 /*******************************************************************
  api_reg_close
  ********************************************************************/
-static BOOL api_reg_close( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_reg_close(rpcsrv_struct * p, prs_struct *data,
+                         prs_struct *rdata)
 {
-        REG_Q_CLOSE q_r;
-        REG_R_CLOSE r_u;
-        ZERO_STRUCT(q_r);
-        ZERO_STRUCT(r_u);
-        /* grab the reg unknown 1 */
-        if (!reg_io_q_close("", &q_r, data, 0))
+       REG_Q_CLOSE q_r;
+       REG_R_CLOSE r_u;
+       ZERO_STRUCT(q_r);
+       ZERO_STRUCT(r_u);
+
+       /* grab the reg unknown 1 */
+       if (!reg_io_q_close("", &q_r, data, 0))
        {
                return False;
        }
 
-        memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
-        /* construct reply.  always indicate success */
-        r_u.status = _reg_close(&r_u.pol);
-        /* store the response in the SMB stream */
-        return reg_io_r_close("", &r_u, rdata, 0);
-}            
+       r_u.pol = q_r.pol;
+
+       /* construct reply.  always indicate success */
+       r_u.status = _reg_close(&r_u.pol);
+
+       /* store the response in the SMB stream */
+       return reg_io_r_close("", &r_u, rdata, 0);
+}
 
 /*******************************************************************
  api_reg_open
  ********************************************************************/
-static BOOL api_reg_open( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_reg_open(rpcsrv_struct * p, prs_struct *data,
+                        prs_struct *rdata)
 {
-        REG_Q_OPEN_HKLM q_u;
-        REG_R_OPEN_HKLM r_u;
-        ZERO_STRUCT(q_u);
-        ZERO_STRUCT(r_u);
-        /* grab the reg open */
-        if (!reg_io_q_open_hklm("", &q_u, data, 0))
+       REG_Q_OPEN_HKLM q_u;
+       REG_R_OPEN_HKLM r_u;
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       /* grab the reg open */
+       if (!reg_io_q_open_hklm("", &q_u, data, 0))
        {
                return False;
        }
 
-        r_u.status = _reg_open(&r_u.pol, q_u.access_mask);
-        /* store the response in the SMB stream */
-        return reg_io_r_open_hklm("", &r_u, rdata, 0); 
+       r_u.status = _reg_open(&r_u.pol, q_u.access_mask);
+
+       /* store the response in the SMB stream */
+       return reg_io_r_open_hklm("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_reg_open_entry
  ********************************************************************/
-static BOOL api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_reg_open_entry(rpcsrv_struct * p, prs_struct *data,
+                              prs_struct *rdata)
 {
        uint32 status;
-       
+
        POLICY_HND entry_pol;
        REG_Q_OPEN_ENTRY q_u;
-       REG_R_OPEN_ENTRY r_u; 
+       REG_R_OPEN_ENTRY r_u;
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
@@ -143,20 +141,22 @@ static BOOL api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
        }
 
        /* construct reply. */
-       status = _reg_open_entry(&q_u.pol,&q_u.uni_name,q_u.unknown_0,q_u.access_mask,&entry_pol);
-       
+       status =
+               _reg_open_entry(&q_u.pol, &q_u.uni_name, q_u.unknown_0,
+                               q_u.access_mask, &entry_pol);
+
        make_reg_r_open_entry(&r_u, &entry_pol, status);
 
        /* store the response in the SMB stream */
-       return reg_io_r_open_entry("", &r_u, rdata, 0); 
+       return reg_io_r_open_entry("", &r_u, rdata, 0);
 }
 
 
 /*******************************************************************
  api_reg_info
  ********************************************************************/
-static BOOL api_reg_info( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_reg_info(rpcsrv_struct * p, prs_struct *data,
+                        prs_struct *rdata)
 {
        REG_R_INFO r_u;
        REG_Q_INFO q_u;
@@ -170,7 +170,7 @@ static BOOL api_reg_info( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(buf);
 
 
-       /* grab the reg unknown 0x11*/
+       /* grab the reg unknown 0x11 */
        if (!reg_io_q_info("", &q_u, data, 0))
        {
                return False;
@@ -183,27 +183,25 @@ static BOOL api_reg_info( rpcsrv_struct *p, prs_struct *data,
        make_reg_r_info(&r_u, &type, &buf, status);
 
        /* store the response in the SMB stream */
-       return reg_io_r_info("", &r_u, rdata, 0);       
+       return reg_io_r_info("", &r_u, rdata, 0);
 }
 
 
 /*******************************************************************
  array of \PIPE\reg operations
  ********************************************************************/
-static const struct api_struct api_reg_cmds[] =
-{
-       { "REG_CLOSE"        , REG_CLOSE        , api_reg_close        },
-       { "REG_OPEN_ENTRY"   , REG_OPEN_ENTRY   , api_reg_open_entry   },
-       { "REG_OPEN"         , REG_OPEN_HKLM    , api_reg_open         },
-       { "REG_INFO"         , REG_INFO         , api_reg_info         },
-       { NULL,                0                , NULL                 }
+static const struct api_struct api_reg_cmds[] = {
+       {"REG_CLOSE", REG_CLOSE, api_reg_close},
+       {"REG_OPEN_ENTRY", REG_OPEN_ENTRY, api_reg_open_entry},
+       {"REG_OPEN", REG_OPEN_HKLM, api_reg_open},
+       {"REG_INFO", REG_INFO, api_reg_info},
+       {NULL, 0, NULL}
 };
 
 /*******************************************************************
  receives a reg pipe and responds.
  ********************************************************************/
-BOOL api_reg_rpc(rpcsrv_struct *p)
+BOOL api_reg_rpc(rpcsrv_struct * p)
 {
        return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds);
 }
-
index 1c334c6f01d3a5387533cfa5e80bad82bdd680e6..3580276c96e1c4e4c728061153c890e162383ee5 100644 (file)
@@ -31,7 +31,8 @@ extern int DEBUGLEVEL;
 /*******************************************************************
  api_samr_close_hnd
  ********************************************************************/
-static BOOL api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_close_hnd(rpcsrv_struct * p, prs_struct *data,
+                              prs_struct *rdata)
 {
        SAMR_Q_CLOSE_HND q_u;
        SAMR_R_CLOSE_HND r_u;
@@ -40,7 +41,7 @@ static BOOL api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *
                return False;
        }
        r_u.status = _samr_close(&q_u.pol);
-       memcpy(&r_u.pol, &q_u.pol, sizeof(q_u.pol));
+       r_u.pol = q_u.pol;
        return samr_io_r_close_hnd("", &r_u, rdata, 0);
 }
 
@@ -48,7 +49,8 @@ static BOOL api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *
 /*******************************************************************
  api_samr_unknown_2d
  ********************************************************************/
-static BOOL api_samr_unknown_2d( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_2d(rpcsrv_struct * p, prs_struct *data,
+                               prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_2D q_u;
        SAMR_R_UNKNOWN_2D r_u;
@@ -63,7 +65,8 @@ static BOOL api_samr_unknown_2d( rpcsrv_struct *p, prs_struct *data, prs_struct
 /*******************************************************************
  api_samr_open_domain
  ********************************************************************/
-static BOOL api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_domain(rpcsrv_struct * p, prs_struct *data,
+                                prs_struct *rdata)
 {
        SAMR_Q_OPEN_DOMAIN q_u;
        SAMR_R_OPEN_DOMAIN r_u;
@@ -74,8 +77,7 @@ static BOOL api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct
 
 
        r_u.status = _samr_open_domain(&q_u.connect_pol, q_u.flags,
-                                      &q_u.dom_sid.sid,
-                                      &r_u.domain_pol);
+                                      &q_u.dom_sid.sid, &r_u.domain_pol);
 
        return samr_io_r_open_domain("", &r_u, rdata, 0);
 }
@@ -83,7 +85,8 @@ static BOOL api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct
 /*******************************************************************
  api_samr_usrdom_pwinfo
  ********************************************************************/
-static BOOL api_samr_get_usrdom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_get_usrdom_pwinfo(rpcsrv_struct * p, prs_struct *data,
+                                      prs_struct *rdata)
 {
        SAMR_Q_GET_USRDOM_PWINFO q_u;
        SAMR_R_GET_USRDOM_PWINFO r_u;
@@ -94,8 +97,8 @@ static BOOL api_samr_get_usrdom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_
 
 
        r_u.status = _samr_get_usrdom_pwinfo(&q_u.user_pol,
-                                     &r_u.unknown_0, &r_u.unknown_1,
-                                     &r_u.unknown_2);
+                                            &r_u.unknown_0, &r_u.unknown_1,
+                                            &r_u.unknown_2);
 
        return samr_io_r_get_usrdom_pwinfo("", &r_u, rdata, 0);
 }
@@ -104,7 +107,8 @@ static BOOL api_samr_get_usrdom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_
 /*******************************************************************
  api_samr_query_sec_obj
  ********************************************************************/
-static BOOL api_samr_query_sec_obj( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_sec_obj(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SAMR_Q_QUERY_SEC_OBJ q_u;
        SAMR_R_QUERY_SEC_OBJ r_u;
@@ -122,7 +126,7 @@ static BOOL api_samr_query_sec_obj( rpcsrv_struct *p, prs_struct *data, prs_stru
        {
                return False;
        }
-       r_u.ptr = 1; /* man, we don't have any choice!  NT bombs otherwise! */
+       r_u.ptr = 1;            /* man, we don't have any choice!  NT bombs otherwise! */
        return samr_io_r_query_sec_obj("", &r_u, rdata, 0);
 }
 
@@ -130,7 +134,8 @@ static BOOL api_samr_query_sec_obj( rpcsrv_struct *p, prs_struct *data, prs_stru
 /*******************************************************************
  api_samr_enum_dom_users
  ********************************************************************/
-static BOOL api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_users(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_USERS q_e;
        SAMR_R_ENUM_DOM_USERS r_e;
@@ -148,9 +153,9 @@ static BOOL api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_str
 
 
        r_e.status = _samr_enum_dom_users(&q_e.pol, &q_e.start_idx,
-                                     q_e.acb_mask, q_e.unknown_1, q_e.max_size,
-                                     &r_e.sam, &r_e.uni_acct_name,
-                                     &num_entries);
+                                         q_e.acb_mask, q_e.unknown_1,
+                                         q_e.max_size, &r_e.sam,
+                                         &r_e.uni_acct_name, &num_entries);
 
        make_samr_r_enum_dom_users(&r_e, q_e.start_idx, num_entries);
 
@@ -165,7 +170,8 @@ static BOOL api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_add_groupmem
  ********************************************************************/
-static BOOL api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_add_groupmem(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_ADD_GROUPMEM q_e;
        SAMR_R_ADD_GROUPMEM r_e;
@@ -187,7 +193,8 @@ static BOOL api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_del_groupmem
  ********************************************************************/
-static BOOL api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_groupmem(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_DEL_GROUPMEM q_e;
        SAMR_R_DEL_GROUPMEM r_e;
@@ -209,7 +216,8 @@ static BOOL api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_add_aliasmem
  ********************************************************************/
-static BOOL api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_add_aliasmem(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_ADD_ALIASMEM q_e;
        SAMR_R_ADD_ALIASMEM r_e;
@@ -231,7 +239,8 @@ static BOOL api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_del_aliasmem
  ********************************************************************/
-static BOOL api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_aliasmem(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_DEL_ALIASMEM q_e;
        SAMR_R_DEL_ALIASMEM r_e;
@@ -249,7 +258,8 @@ static BOOL api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_enum_domains
  ********************************************************************/
-static BOOL api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_domains(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOMAINS q_e;
        SAMR_R_ENUM_DOMAINS r_e;
@@ -267,9 +277,9 @@ static BOOL api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struc
 
 
        r_e.status = _samr_enum_domains(&q_e.pol, &q_e.start_idx,
-                                     q_e.max_size,
-                                     &r_e.sam, &r_e.uni_dom_name,
-                                     &num_entries);
+                                       q_e.max_size,
+                                       &r_e.sam, &r_e.uni_dom_name,
+                                       &num_entries);
 
        make_samr_r_enum_domains(&r_e, q_e.start_idx, num_entries);
 
@@ -284,7 +294,8 @@ static BOOL api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_enum_dom_groups
  ********************************************************************/
-static BOOL api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_groups(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_GROUPS q_e;
        SAMR_R_ENUM_DOM_GROUPS r_e;
@@ -303,9 +314,9 @@ static BOOL api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_st
 
 
        r_e.status = _samr_enum_dom_groups(&q_e.pol, &q_e.start_idx,
-                                     q_e.max_size,
-                                     &r_e.sam, &r_e.uni_grp_name,
-                                     &num_entries);
+                                          q_e.max_size,
+                                          &r_e.sam, &r_e.uni_grp_name,
+                                          &num_entries);
 
        make_samr_r_enum_dom_groups(&r_e, q_e.start_idx, num_entries);
 
@@ -320,7 +331,8 @@ static BOOL api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_st
 /*******************************************************************
  api_samr_enum_dom_aliases
  ********************************************************************/
-static BOOL api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_aliases(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_ALIASES q_e;
        SAMR_R_ENUM_DOM_ALIASES r_e;
@@ -339,9 +351,9 @@ static BOOL api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_s
 
 
        r_e.status = _samr_enum_dom_aliases(&q_e.pol, &q_e.start_idx,
-                                     q_e.max_size,
-                                     &r_e.sam, &r_e.uni_grp_name,
-                                     &num_entries);
+                                           q_e.max_size,
+                                           &r_e.sam, &r_e.uni_grp_name,
+                                           &num_entries);
 
        make_samr_r_enum_dom_aliases(&r_e, q_e.start_idx, num_entries);
 
@@ -356,7 +368,8 @@ static BOOL api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_s
 /*******************************************************************
  api_samr_query_dispinfo
  ********************************************************************/
-static BOOL api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dispinfo(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_QUERY_DISPINFO q_e;
        SAMR_R_QUERY_DISPINFO r_e;
@@ -376,13 +389,11 @@ static BOOL api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_str
        }
 
        status = _samr_query_dispinfo(&q_e.domain_pol,
-                               q_e.switch_level,
-                               q_e.start_idx,
-                               q_e.max_entries,
-                               q_e.max_size,
-                               &data_size,
-                               &num_entries,
-                               &ctr);
+                                     q_e.switch_level,
+                                     q_e.start_idx,
+                                     q_e.max_entries,
+                                     q_e.max_size,
+                                     &data_size, &num_entries, &ctr);
 
        make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
                                   q_e.switch_level, &ctr, status);
@@ -397,7 +408,8 @@ static BOOL api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_delete_dom_user
  ********************************************************************/
-static BOOL api_samr_delete_dom_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_user(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SAMR_Q_DELETE_DOM_USER q_u;
        SAMR_R_DELETE_DOM_USER r_u;
@@ -411,14 +423,15 @@ static BOOL api_samr_delete_dom_user( rpcsrv_struct *p, prs_struct *data, prs_st
        }
 
        r_u.status = _samr_delete_dom_user(&q_u.user_pol);
-       memcpy(&r_u.pol, &q_u.user_pol, sizeof(q_u.user_pol));
+       r_u.pol = q_u.user_pol;
        return samr_io_r_delete_dom_user("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_delete_dom_group
  ********************************************************************/
-static BOOL api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_group(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_DELETE_DOM_GROUP q_u;
        SAMR_R_DELETE_DOM_GROUP r_u;
@@ -432,7 +445,7 @@ static BOOL api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_s
        }
 
        r_u.status = _samr_delete_dom_group(&q_u.group_pol);
-       memcpy(&r_u.pol, &q_u.group_pol, sizeof(q_u.group_pol));
+       r_u.pol = q_u.group_pol;
        return samr_io_r_delete_dom_group("", &r_u, rdata, 0);
 }
 
@@ -440,7 +453,8 @@ static BOOL api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_s
 /*******************************************************************
  api_samr_query_groupmem
  ********************************************************************/
-static BOOL api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_groupmem(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_QUERY_GROUPMEM q_u;
        SAMR_R_QUERY_GROUPMEM r_u;
@@ -459,8 +473,7 @@ static BOOL api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_str
                return False;
        }
 
-       status = _samr_query_groupmem(&q_u.group_pol,
-                                          &num_rids, &rid, &attr);
+       status = _samr_query_groupmem(&q_u.group_pol, &num_rids, &rid, &attr);
        make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
        ret = samr_io_r_query_groupmem("", &r_u, rdata, 0);
        samr_free_r_query_groupmem(&r_u);
@@ -471,7 +484,8 @@ static BOOL api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_query_groupinfo
  ********************************************************************/
-static BOOL api_samr_set_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_groupinfo(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SAMR_Q_SET_GROUPINFO q_e;
        SAMR_R_SET_GROUPINFO r_e;
@@ -495,7 +509,8 @@ static BOOL api_samr_set_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_stru
 /*******************************************************************
  api_samr_query_groupinfo
  ********************************************************************/
-static BOOL api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_groupinfo(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SAMR_Q_QUERY_GROUPINFO q_e;
        SAMR_R_QUERY_GROUPINFO r_e;
@@ -505,7 +520,7 @@ static BOOL api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_st
        ZERO_STRUCT(q_e);
        ZERO_STRUCT(r_e);
        ZERO_STRUCT(ctr);
-       
+
        if (!samr_io_q_query_groupinfo("", &q_e, data, 0))
        {
                return False;
@@ -522,7 +537,8 @@ static BOOL api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_st
 /*******************************************************************
  api_samr_query_aliasinfo
  ********************************************************************/
-static BOOL api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasinfo(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SAMR_Q_QUERY_ALIASINFO q_e;
        SAMR_R_QUERY_ALIASINFO r_e;
@@ -532,7 +548,7 @@ static BOOL api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_st
        ZERO_STRUCT(q_e);
        ZERO_STRUCT(r_e);
        ZERO_STRUCT(ctr);
-       
+
        if (!samr_io_q_query_aliasinfo("", &q_e, data, 0))
        {
                return False;
@@ -549,7 +565,8 @@ static BOOL api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_st
 /*******************************************************************
  api_samr_query_useraliases
  ********************************************************************/
-static BOOL api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_useraliases(rpcsrv_struct * p, prs_struct *data,
+                                      prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERALIASES q_u;
        SAMR_R_QUERY_USERALIASES r_u;
@@ -567,7 +584,7 @@ static BOOL api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_
        }
 
        status = _samr_query_useraliases(&q_u.pol, q_u.ptr_sid, q_u.sid,
-                                        &num_rids, &rid);
+                                        &num_rids, &rid);
        samr_free_q_query_useraliases(&q_u);
        make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
        return samr_io_r_query_useraliases("", &r_u, rdata, 0);
@@ -577,7 +594,8 @@ static BOOL api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_
 /*******************************************************************
  api_samr_delete_dom_alias
  ********************************************************************/
-static BOOL api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_alias(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_DELETE_DOM_ALIAS q_u;
        SAMR_R_DELETE_DOM_ALIAS r_u;
@@ -598,7 +616,8 @@ static BOOL api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_s
 /*******************************************************************
  api_samr_query_aliasmem
  ********************************************************************/
-static BOOL api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasmem(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_QUERY_ALIASMEM q_u;
        SAMR_R_QUERY_ALIASMEM r_u;
@@ -631,17 +650,18 @@ static BOOL api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_lookup_names
  ********************************************************************/
-static BOOL api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_names(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_LOOKUP_NAMES q_u;
        SAMR_R_LOOKUP_NAMES r_u;
 
-       uint32 rid [MAX_SAM_ENTRIES];
+       uint32 rid[MAX_SAM_ENTRIES];
        uint32 type[MAX_SAM_ENTRIES];
-       uint32 num_rids  = 0;
+       uint32 num_rids = 0;
        uint32 num_types = 0;
 
-       uint32 status     = 0;
+       uint32 status = 0;
 
        if (!samr_io_q_lookup_names("", &q_u, data, 0))
        {
@@ -649,8 +669,8 @@ static BOOL api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struc
        }
 
        status = _samr_lookup_names(&q_u.pol, q_u.num_names1,
-                                    q_u.flags, q_u.ptr, q_u.uni_name,
-                                    &num_rids, rid, &num_types, type);
+                                   q_u.flags, q_u.ptr, q_u.uni_name,
+                                   &num_rids, rid, &num_types, type);
        samr_free_q_lookup_names(&q_u);
        make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
        return samr_io_r_lookup_names("", &r_u, rdata, 0);
@@ -659,7 +679,8 @@ static BOOL api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_chgpasswd_user
  ********************************************************************/
-static BOOL api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_chgpasswd_user(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_CHGPASSWD_USER q_u;
        SAMR_R_CHGPASSWD_USER r_u;
@@ -686,16 +707,16 @@ static BOOL api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_str
        }
        if (q_u.nt_newpass.ptr)
        {
-               nt_newpass = q_u.nt_newpass.pass;
+               nt_newpass = q_u.nt_newpass.pass;
        }
        if (q_u.nt_oldhash.ptr)
        {
-               nt_oldhash = q_u.nt_oldhash.hash;
-        }
+               nt_oldhash = q_u.nt_oldhash.hash;
+       }
        r_u.status = _samr_chgpasswd_user(&q_u.uni_dest_host,
-                                 &q_u.uni_user_name,
-                                 nt_newpass, nt_oldhash,
-                                 lm_newpass, lm_oldhash);
+                                         &q_u.uni_user_name,
+                                         nt_newpass, nt_oldhash,
+                                         lm_newpass, lm_oldhash);
        return samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
 }
 
@@ -703,7 +724,8 @@ static BOOL api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_get_dom_pwinfo
  ********************************************************************/
-static BOOL api_samr_get_dom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_get_dom_pwinfo(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_GET_DOM_PWINFO q_u;
        SAMR_R_GET_DOM_PWINFO r_u;
@@ -714,9 +736,7 @@ static BOOL api_samr_get_dom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_str
        }
 
        r_u.status = _samr_get_dom_pwinfo(&q_u.uni_srv_name,
-                           &r_u.unk_0,
-                           &r_u.unk_1,
-                           &r_u.unk_2);
+                                         &r_u.unk_0, &r_u.unk_1, &r_u.unk_2);
        return samr_io_r_get_dom_pwinfo("", &r_u, rdata, 0);
 }
 
@@ -724,7 +744,8 @@ static BOOL api_samr_get_dom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_lookup_rids
  ********************************************************************/
-static BOOL api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_rids(rpcsrv_struct * p, prs_struct *data,
+                                prs_struct *rdata)
 {
        SAMR_Q_LOOKUP_RIDS q_u;
        SAMR_R_LOOKUP_RIDS r_u;
@@ -743,9 +764,9 @@ static BOOL api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct
        }
 
        status = _samr_lookup_rids(&q_u.pol, q_u.num_rids1,
-                                   q_u.flags, q_u.rid,
-                                   &num_names, 
-                                   &hdr_names, &uni_names, &types);
+                                  q_u.flags, q_u.rid,
+                                  &num_names,
+                                  &hdr_names, &uni_names, &types);
        samr_free_q_lookup_rids(&q_u);
        make_samr_r_lookup_rids(&r_u, num_names, hdr_names, uni_names, types);
        return samr_io_r_lookup_rids("", &r_u, rdata, 0);
@@ -755,7 +776,8 @@ static BOOL api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct
 /*******************************************************************
  api_samr_open_user
  ********************************************************************/
-static BOOL api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_user(rpcsrv_struct * p, prs_struct *data,
+                              prs_struct *rdata)
 {
        SAMR_Q_OPEN_USER q_u;
        SAMR_R_OPEN_USER r_u;
@@ -765,8 +787,8 @@ static BOOL api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *
        }
 
        r_u.status = _samr_open_user(&q_u.domain_pol,
-                                          q_u.access_mask, q_u.user_rid,
-                                         &r_u.user_pol);
+                                    q_u.access_mask, q_u.user_rid,
+                                    &r_u.user_pol);
        return samr_io_r_open_user("", &r_u, rdata, 0);
 }
 
@@ -774,7 +796,8 @@ static BOOL api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *
 /*******************************************************************
  api_samr_query_userinfo
  ********************************************************************/
-static BOOL api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_userinfo(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERINFO q_u;
        SAMR_R_QUERY_USERINFO r_u;
@@ -793,13 +816,16 @@ static BOOL api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_str
 
        if (q_u.switch_value == 0x12)
        {
-               DEBUG(0,("api_samr_query_userinfo: possible password attack (info level 0x12)\n"));
+               DEBUG(0,
+                     ("api_samr_query_userinfo: possible password attack (info level 0x12)\n"));
 
                status = NT_STATUS_INVALID_INFO_CLASS;
        }
        else
        {
-               status = _samr_query_userinfo(&q_u.pol, q_u.switch_value, &ctr);
+               status =
+                       _samr_query_userinfo(&q_u.pol, q_u.switch_value,
+                                            &ctr);
        }
        make_samr_r_query_userinfo(&r_u, &ctr, status);
        return samr_io_r_query_userinfo("", &r_u, rdata, 0);
@@ -809,7 +835,8 @@ static BOOL api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_set_userinfo2
  ********************************************************************/
-static BOOL api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_userinfo2(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SAMR_Q_SET_USERINFO2 q_u;
        SAMR_R_SET_USERINFO2 r_u;
@@ -835,7 +862,8 @@ static BOOL api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_stru
 /*******************************************************************
  api_samr_set_userinfo
  ********************************************************************/
-static BOOL api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_userinfo(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_SET_USERINFO q_u;
        SAMR_R_SET_USERINFO r_u;
@@ -861,7 +889,8 @@ static BOOL api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struc
 /*******************************************************************
  api_samr_query_usergroups
  ********************************************************************/
-static BOOL api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_usergroups(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_QUERY_USERGROUPS q_u;
        SAMR_R_QUERY_USERGROUPS r_u;
@@ -888,7 +917,8 @@ static BOOL api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_s
 /*******************************************************************
  api_samr_create_dom_alias
  ********************************************************************/
-static BOOL api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_dom_alias(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_CREATE_DOM_ALIAS q_u;
        SAMR_R_CREATE_DOM_ALIAS r_u;
@@ -902,15 +932,16 @@ static BOOL api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_s
        }
 
        r_u.status = _samr_create_dom_alias(&q_u.dom_pol, &q_u.uni_acct_desc,
-                                           q_u.access_mask,
-                                           &r_u.alias_pol, &r_u.rid);
+                                           q_u.access_mask,
+                                           &r_u.alias_pol, &r_u.rid);
        return samr_io_r_create_dom_alias("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_create_dom_group
  ********************************************************************/
-static BOOL api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_dom_group(rpcsrv_struct * p, prs_struct *data,
+                                     prs_struct *rdata)
 {
        SAMR_Q_CREATE_DOM_GROUP q_u;
        SAMR_R_CREATE_DOM_GROUP r_u;
@@ -924,9 +955,9 @@ static BOOL api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_s
        }
 
        r_u.status = _samr_create_dom_group(&q_u.pol,
-                                           &q_u.uni_acct_desc,
-                                           q_u.access_mask,
-                                           &r_u.pol, &r_u.rid);
+                                           &q_u.uni_acct_desc,
+                                           q_u.access_mask,
+                                           &r_u.pol, &r_u.rid);
 
        /* store the response in the SMB stream */
        return samr_io_r_create_dom_group("", &r_u, rdata, 0);
@@ -935,7 +966,8 @@ static BOOL api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_s
 /*******************************************************************
  api_samr_query_dom_info
  ********************************************************************/
-static BOOL api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dom_info(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SAMR_Q_QUERY_DOMAIN_INFO q_e;
        SAMR_R_QUERY_DOMAIN_INFO r_u;
@@ -954,7 +986,8 @@ static BOOL api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_str
 
 
        switch_value = q_e.switch_value;
-       status = _samr_query_dom_info(&q_e.domain_pol, q_e.switch_value, &ctr);
+       status =
+               _samr_query_dom_info(&q_e.domain_pol, q_e.switch_value, &ctr);
        make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
 
        /* store the response in the SMB stream */
@@ -964,7 +997,8 @@ static BOOL api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_str
 /*******************************************************************
  api_samr_create_user
  ********************************************************************/
-static BOOL api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_user(rpcsrv_struct * p, prs_struct *data,
+                                prs_struct *rdata)
 {
        SAMR_Q_CREATE_USER q_u;
        SAMR_R_CREATE_USER r_u;
@@ -978,18 +1012,18 @@ static BOOL api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct
        }
 
        r_u.status = _samr_create_user(&q_u.domain_pol,
-                                          &q_u.uni_name, q_u.acb_info, 
-                                          q_u.access_mask,
-                                          &r_u.user_pol,
-                                          &r_u.unknown_0,
-                                          &r_u.user_rid);
+                                      &q_u.uni_name, q_u.acb_info,
+                                      q_u.access_mask,
+                                      &r_u.user_pol,
+                                      &r_u.unknown_0, &r_u.user_rid);
        return samr_io_r_create_user("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_connect_anon
  ********************************************************************/
-static BOOL api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect_anon(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SAMR_Q_CONNECT_ANON q_u;
        SAMR_R_CONNECT_ANON r_u;
@@ -1003,15 +1037,15 @@ static BOOL api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struc
        }
 
        r_u.status = _samr_connect_anon(NULL,
-                                       q_u.access_mask,
-                                       &r_u.connect_pol);
+                                       q_u.access_mask, &r_u.connect_pol);
        return samr_io_r_connect_anon("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_connect
  ********************************************************************/
-static BOOL api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect(rpcsrv_struct * p, prs_struct *data,
+                            prs_struct *rdata)
 {
        SAMR_Q_CONNECT q_u;
        SAMR_R_CONNECT r_u;
@@ -1025,16 +1059,15 @@ static BOOL api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rd
        }
 
        r_u.status = _samr_connect(&q_u.uni_srv_name,
-                                  q_u.access_mask,
-                                  &r_u.connect_pol);
+                                  q_u.access_mask, &r_u.connect_pol);
        return samr_io_r_connect("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_open_alias
  ********************************************************************/
-static BOOL api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-                                
+static BOOL api_samr_open_alias(rpcsrv_struct * p, prs_struct *data,
+                               prs_struct *rdata)
 {
        SAMR_Q_OPEN_ALIAS q_u;
        SAMR_R_OPEN_ALIAS r_u;
@@ -1048,7 +1081,9 @@ static BOOL api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct
        }
 
 
-       r_u.status = _samr_open_alias(&q_u.dom_pol, q_u.unknown_0, q_u.rid_alias, &r_u.pol);
+       r_u.status =
+               _samr_open_alias(&q_u.dom_pol, q_u.unknown_0, q_u.rid_alias,
+                                &r_u.pol);
 
        /* store the response in the SMB stream */
        return samr_io_r_open_alias("", &r_u, rdata, 0);
@@ -1057,8 +1092,8 @@ static BOOL api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct
 /*******************************************************************
  api_samr_open_group
  ********************************************************************/
-static BOOL api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-                                
+static BOOL api_samr_open_group(rpcsrv_struct * p, prs_struct *data,
+                               prs_struct *rdata)
 {
        SAMR_Q_OPEN_GROUP q_u;
        SAMR_R_OPEN_GROUP r_u;
@@ -1072,14 +1107,15 @@ static BOOL api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct
        }
 
        r_u.status = _samr_open_group(&q_u.domain_pol, q_u.access_mask,
-                                      q_u.rid_group, &r_u.pol);
+                                     q_u.rid_group, &r_u.pol);
        return samr_io_r_open_group("", &r_u, rdata, 0);
 }
 
 /*******************************************************************
  api_samr_lookup_domain
  ********************************************************************/
-static BOOL api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_domain(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SAMR_Q_LOOKUP_DOMAIN q_u;
        SAMR_R_LOOKUP_DOMAIN r_u;
@@ -1094,7 +1130,9 @@ static BOOL api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_stru
                return False;
        }
 
-       status = _samr_lookup_domain(&q_u.connect_pol, &q_u.uni_domain, &dom_sid);
+       status =
+               _samr_lookup_domain(&q_u.connect_pol, &q_u.uni_domain,
+                                   &dom_sid);
        make_samr_r_lookup_domain(&r_u, &dom_sid, status);
 
        /* store the response in the SMB stream */
@@ -1104,59 +1142,76 @@ static BOOL api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_stru
 /*******************************************************************
  array of \PIPE\samr operations
  ********************************************************************/
-static const struct api_struct api_samr_cmds [] =
-{
-       { "SAMR_CLOSE_HND"        , SAMR_CLOSE_HND        , api_samr_close_hnd        },
-       { "SAMR_CONNECT"          , SAMR_CONNECT          , api_samr_connect          },
-       { "SAMR_CONNECT_ANON"     , SAMR_CONNECT_ANON     , api_samr_connect_anon     },
-       { "SAMR_ENUM_DOMAINS"     , SAMR_ENUM_DOMAINS     , api_samr_enum_domains     },
-       { "SAMR_ENUM_DOM_USERS"   , SAMR_ENUM_DOM_USERS   , api_samr_enum_dom_users   },
-       { "SAMR_ENUM_DOM_GROUPS"  , SAMR_ENUM_DOM_GROUPS  , api_samr_enum_dom_groups  },
-       { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
-       { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
-       { "SAMR_QUERY_ALIASMEM"   , SAMR_QUERY_ALIASMEM   , api_samr_query_aliasmem   },
-       { "SAMR_QUERY_GROUPMEM"   , SAMR_QUERY_GROUPMEM   , api_samr_query_groupmem   },
-       { "SAMR_ADD_ALIASMEM"     , SAMR_ADD_ALIASMEM     , api_samr_add_aliasmem     },
-       { "SAMR_DEL_ALIASMEM"     , SAMR_DEL_ALIASMEM     , api_samr_del_aliasmem     },
-       { "SAMR_ADD_GROUPMEM"     , SAMR_ADD_GROUPMEM     , api_samr_add_groupmem     },
-       { "SAMR_DEL_GROUPMEM"     , SAMR_DEL_GROUPMEM     , api_samr_del_groupmem     },
-       { "SAMR_DELETE_DOM_USER"  , SAMR_DELETE_DOM_USER  , api_samr_delete_dom_user  },
-       { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
-       { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
-       { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
-       { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
-       { "SAMR_LOOKUP_NAMES"     , SAMR_LOOKUP_NAMES     , api_samr_lookup_names     },
-       { "SAMR_OPEN_USER"        , SAMR_OPEN_USER        , api_samr_open_user        },
-       { "SAMR_QUERY_USERINFO"   , SAMR_QUERY_USERINFO   , api_samr_query_userinfo   },
-       { "SAMR_SET_USERINFO"     , SAMR_SET_USERINFO     , api_samr_set_userinfo     },
-       { "SAMR_SET_USERINFO2"    , SAMR_SET_USERINFO2    , api_samr_set_userinfo2    },
-       { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info   },
-       { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
-       { "SAMR_QUERY_DISPINFO"   , SAMR_QUERY_DISPINFO   , api_samr_query_dispinfo   },
-       { "SAMR_QUERY_DISPINFO3"  , SAMR_QUERY_DISPINFO3  , api_samr_query_dispinfo   },
-       { "SAMR_QUERY_DISPINFO4"  , SAMR_QUERY_DISPINFO4  , api_samr_query_dispinfo   },
-       { "SAMR_QUERY_ALIASINFO"  , SAMR_QUERY_ALIASINFO  , api_samr_query_aliasinfo  },
-       { "SAMR_QUERY_GROUPINFO"  , SAMR_QUERY_GROUPINFO  , api_samr_query_groupinfo  },
-       { "SAMR_SET_GROUPINFO"    , SAMR_SET_GROUPINFO    , api_samr_set_groupinfo  },
-       { "SAMR_CREATE_USER"      , SAMR_CREATE_USER      , api_samr_create_user      },
-       { "SAMR_LOOKUP_RIDS"      , SAMR_LOOKUP_RIDS      , api_samr_lookup_rids      },
-       { "SAMR_GET_DOM_PWINFO"   , SAMR_GET_DOM_PWINFO   , api_samr_get_dom_pwinfo       },
-       { "SAMR_CHGPASSWD_USER"   , SAMR_CHGPASSWD_USER   , api_samr_chgpasswd_user   },
-       { "SAMR_OPEN_ALIAS"       , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
-       { "SAMR_OPEN_GROUP"       , SAMR_OPEN_GROUP       , api_samr_open_group       },
-       { "SAMR_OPEN_DOMAIN"      , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
-       { "SAMR_UNKNOWN_2D"       , SAMR_UNKNOWN_2D       , api_samr_unknown_2d       },
-       { "SAMR_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
-       { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj    },
-       { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
-       { NULL                    , 0                     , NULL                      }
+static const struct api_struct api_samr_cmds[] = {
+       {"SAMR_CLOSE_HND", SAMR_CLOSE_HND, api_samr_close_hnd},
+       {"SAMR_CONNECT", SAMR_CONNECT, api_samr_connect},
+       {"SAMR_CONNECT_ANON", SAMR_CONNECT_ANON, api_samr_connect_anon},
+       {"SAMR_ENUM_DOMAINS", SAMR_ENUM_DOMAINS, api_samr_enum_domains},
+       {"SAMR_ENUM_DOM_USERS", SAMR_ENUM_DOM_USERS, api_samr_enum_dom_users},
+       
+               {"SAMR_ENUM_DOM_GROUPS", SAMR_ENUM_DOM_GROUPS,
+        api_samr_enum_dom_groups},
+       {"SAMR_ENUM_DOM_ALIASES", SAMR_ENUM_DOM_ALIASES,
+        api_samr_enum_dom_aliases},
+       {"SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES,
+        api_samr_query_useraliases},
+       {"SAMR_QUERY_ALIASMEM", SAMR_QUERY_ALIASMEM, api_samr_query_aliasmem},
+       {"SAMR_QUERY_GROUPMEM", SAMR_QUERY_GROUPMEM, api_samr_query_groupmem},
+       {"SAMR_ADD_ALIASMEM", SAMR_ADD_ALIASMEM, api_samr_add_aliasmem},
+       {"SAMR_DEL_ALIASMEM", SAMR_DEL_ALIASMEM, api_samr_del_aliasmem},
+       {"SAMR_ADD_GROUPMEM", SAMR_ADD_GROUPMEM, api_samr_add_groupmem},
+       {"SAMR_DEL_GROUPMEM", SAMR_DEL_GROUPMEM, api_samr_del_groupmem},
+       
+               {"SAMR_DELETE_DOM_USER", SAMR_DELETE_DOM_USER,
+        api_samr_delete_dom_user},
+       {"SAMR_DELETE_DOM_GROUP", SAMR_DELETE_DOM_GROUP,
+        api_samr_delete_dom_group},
+       {"SAMR_DELETE_DOM_ALIAS", SAMR_DELETE_DOM_ALIAS,
+        api_samr_delete_dom_alias},
+       {"SAMR_CREATE_DOM_GROUP", SAMR_CREATE_DOM_GROUP,
+        api_samr_create_dom_group},
+       {"SAMR_CREATE_DOM_ALIAS", SAMR_CREATE_DOM_ALIAS,
+        api_samr_create_dom_alias},
+       {"SAMR_LOOKUP_NAMES", SAMR_LOOKUP_NAMES, api_samr_lookup_names},
+       {"SAMR_OPEN_USER", SAMR_OPEN_USER, api_samr_open_user},
+       {"SAMR_QUERY_USERINFO", SAMR_QUERY_USERINFO, api_samr_query_userinfo},
+       {"SAMR_SET_USERINFO", SAMR_SET_USERINFO, api_samr_set_userinfo},
+       {"SAMR_SET_USERINFO2", SAMR_SET_USERINFO2, api_samr_set_userinfo2},
+       
+               {"SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO,
+        api_samr_query_dom_info},
+       {"SAMR_QUERY_USERGROUPS", SAMR_QUERY_USERGROUPS,
+        api_samr_query_usergroups},
+       {"SAMR_QUERY_DISPINFO", SAMR_QUERY_DISPINFO, api_samr_query_dispinfo},
+       {"SAMR_QUERY_DISPINFO3", SAMR_QUERY_DISPINFO3, api_samr_query_dispinfo},
+       {"SAMR_QUERY_DISPINFO4", SAMR_QUERY_DISPINFO4, api_samr_query_dispinfo},
+       
+               {"SAMR_QUERY_ALIASINFO", SAMR_QUERY_ALIASINFO,
+        api_samr_query_aliasinfo},
+       {"SAMR_QUERY_GROUPINFO", SAMR_QUERY_GROUPINFO,
+        api_samr_query_groupinfo},
+       {"SAMR_SET_GROUPINFO", SAMR_SET_GROUPINFO, api_samr_set_groupinfo},
+       {"SAMR_CREATE_USER", SAMR_CREATE_USER, api_samr_create_user},
+       {"SAMR_LOOKUP_RIDS", SAMR_LOOKUP_RIDS, api_samr_lookup_rids},
+       {"SAMR_GET_DOM_PWINFO", SAMR_GET_DOM_PWINFO, api_samr_get_dom_pwinfo},
+       {"SAMR_CHGPASSWD_USER", SAMR_CHGPASSWD_USER, api_samr_chgpasswd_user},
+       {"SAMR_OPEN_ALIAS", SAMR_OPEN_ALIAS, api_samr_open_alias},
+       {"SAMR_OPEN_GROUP", SAMR_OPEN_GROUP, api_samr_open_group},
+       {"SAMR_OPEN_DOMAIN", SAMR_OPEN_DOMAIN, api_samr_open_domain},
+       {"SAMR_UNKNOWN_2D", SAMR_UNKNOWN_2D, api_samr_unknown_2d},
+       {"SAMR_LOOKUP_DOMAIN", SAMR_LOOKUP_DOMAIN, api_samr_lookup_domain},
+       
+               {"SAMR_QUERY_SEC_OBJECT", SAMR_QUERY_SEC_OBJECT,
+        api_samr_query_sec_obj},
+       {"SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO,
+        api_samr_get_usrdom_pwinfo},
+       {NULL, 0, NULL}
 };
 
 /*******************************************************************
  receives a samr pipe and responds.
  ********************************************************************/
-BOOL api_samr_rpc(rpcsrv_struct *p)
+BOOL api_samr_rpc(rpcsrv_struct * p)
 {
-    return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
+       return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
 }
-
index 883b002527159cd45fc2c915066f0927d5c3212f..9d416896593566d47666bd9b48409620830c21c8 100644 (file)
@@ -32,8 +32,8 @@ extern pstring global_myname;
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_srv_get_info(rpcsrv_struct * p, prs_struct * data,
-                                    prs_struct * rdata)
+static BOOL api_srv_net_srv_get_info(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SRV_Q_NET_SRV_GET_INFO q_n;
        SRV_R_NET_SRV_GET_INFO r_n;
@@ -61,8 +61,8 @@ static BOOL api_srv_net_srv_get_info(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct * data,
-                                 prs_struct * rdata)
+static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SRV_Q_NET_FILE_ENUM q_n;
        SRV_R_NET_FILE_ENUM r_n;
@@ -89,7 +89,7 @@ static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct * data,
                                        q_n.preferred_len, &q_n.enum_hnd,
                                        &(r_n.total_entries), q_n.file_level);
 
-       memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+       r_n.enum_hnd = q_n.enum_hnd;
 
        /* store the response in the SMB stream */
        ret = srv_io_r_net_file_enum("", &r_n, rdata, 0);
@@ -101,8 +101,8 @@ static BOOL api_srv_net_file_enum(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct * data,
-                                 prs_struct * rdata)
+static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SRV_Q_NET_CONN_ENUM q_n;
        SRV_R_NET_CONN_ENUM r_n;
@@ -128,7 +128,7 @@ static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct * data,
                                        q_n.preferred_len, &q_n.enum_hnd,
                                        &(r_n.total_entries), q_n.conn_level);
 
-       memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+       r_n.enum_hnd = q_n.enum_hnd;
 
        /* store the response in the SMB stream */
        return srv_io_r_net_conn_enum("", &r_n, rdata, 0);
@@ -136,8 +136,8 @@ static BOOL api_srv_net_conn_enum(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct * data,
-                                 prs_struct * rdata)
+static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SRV_Q_NET_SESS_ENUM q_n;
        SRV_R_NET_SESS_ENUM r_n;
@@ -162,7 +162,7 @@ static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct * data,
                                        q_n.preferred_len, &q_n.enum_hnd,
                                        &(r_n.total_entries), q_n.sess_level);
 
-       memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+       r_n.enum_hnd = q_n.enum_hnd;
 
        /* store the response in the SMB stream */
        return srv_io_r_net_sess_enum("", &r_n, rdata, 0);
@@ -170,8 +170,8 @@ static BOOL api_srv_net_sess_enum(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct * data,
-                                  prs_struct * rdata)
+static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SRV_Q_NET_SHARE_ENUM q_n;
        SRV_R_NET_SHARE_ENUM r_n;
@@ -200,7 +200,7 @@ static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct * data,
                                         &(r_n.total_entries),
                                         q_n.share_level);
 
-       memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
+       r_n.enum_hnd = q_n.enum_hnd;
 
        /* store the response in the SMB stream */
        ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
@@ -210,8 +210,8 @@ static BOOL api_srv_net_share_enum(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_share_add(rpcsrv_struct * p, prs_struct * data,
-                                 prs_struct * rdata)
+static BOOL api_srv_net_share_add(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SRV_Q_NET_SHARE_ADD q_n;
        SRV_R_NET_SHARE_ADD r_n;
@@ -235,8 +235,8 @@ static BOOL api_srv_net_share_add(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_share_get_info(rpcsrv_struct * p, prs_struct * data,
-                                      prs_struct * rdata)
+static BOOL api_srv_net_share_get_info(rpcsrv_struct * p, prs_struct *data,
+                                      prs_struct *rdata)
 {
        SRV_Q_NET_SHARE_GET_INFO q_n;
        SRV_R_NET_SHARE_GET_INFO r_n;
@@ -270,8 +270,8 @@ static BOOL api_srv_net_share_get_info(rpcsrv_struct * p, prs_struct * data,
 
 /*******************************************************************
 ********************************************************************/
-static BOOL api_srv_net_remote_tod(rpcsrv_struct * p, prs_struct * data,
-                                  prs_struct * rdata)
+static BOOL api_srv_net_remote_tod(rpcsrv_struct * p, prs_struct *data,
+                                  prs_struct *rdata)
 {
        SRV_Q_NET_REMOTE_TOD q_n;
        SRV_R_NET_REMOTE_TOD r_n;
index 6962ef778c808511121e9e2cede5dc218e9e6d4b..81fe178116e0e500fc714b915d87f18d9790155b 100644 (file)
@@ -31,8 +31,8 @@ extern int DEBUGLEVEL;
 /*******************************************************************
  api_svc_close
  ********************************************************************/
-static BOOL api_svc_close( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_close(rpcsrv_struct * p, prs_struct *data,
+                         prs_struct *rdata)
 {
        SVC_Q_CLOSE q_r;
        SVC_R_CLOSE r_u;
@@ -45,7 +45,7 @@ static BOOL api_svc_close( rpcsrv_struct *p, prs_struct *data,
                return False;
        }
 
-       memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
+       r_u.pol = q_r.pol;
        r_u.status = _svc_close(&r_u.pol);
 
        /* store the response in the SMB stream */
@@ -55,8 +55,8 @@ static BOOL api_svc_close( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_open_service
  ********************************************************************/
-static BOOL api_svc_open_service( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_open_service(rpcsrv_struct * p, prs_struct *data,
+                                prs_struct *rdata)
 {
        SVC_Q_OPEN_SERVICE q_u;
        SVC_R_OPEN_SERVICE r_u;
@@ -69,10 +69,9 @@ static BOOL api_svc_open_service( rpcsrv_struct *p, prs_struct *data,
                return False;
        }
 
-       r_u.status = _svc_open_service(&q_u.scman_pol, 
-                                                &q_u.uni_svc_name,
-                                                q_u.des_access,
-                                                &r_u.pol);
+       r_u.status = _svc_open_service(&q_u.scman_pol,
+                                      &q_u.uni_svc_name,
+                                      q_u.des_access, &r_u.pol);
 
        /* store the response in the SMB stream */
        return svc_io_r_open_service("", &r_u, rdata, 0);
@@ -81,8 +80,8 @@ static BOOL api_svc_open_service( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_stop_service
  ********************************************************************/
-static BOOL api_svc_stop_service( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_stop_service(rpcsrv_struct * p, prs_struct *data,
+                                prs_struct *rdata)
 {
        SVC_Q_STOP_SERVICE q_u;
        SVC_R_STOP_SERVICE r_s;
@@ -96,14 +95,13 @@ static BOOL api_svc_stop_service( rpcsrv_struct *p, prs_struct *data,
        }
 
        r_s.status = _svc_stop_service(&q_u.pol,
-                                                q_u.unknown,
-                                                &r_s.unknown0,
-                                                &r_s.unknown1,
-                                                &r_s.unknown2,
-                                                &r_s.unknown3,
-                                                &r_s.unknown4,
-                                                &r_s.unknown5,
-                                                &r_s.unknown6);
+                                      q_u.unknown,
+                                      &r_s.unknown0,
+                                      &r_s.unknown1,
+                                      &r_s.unknown2,
+                                      &r_s.unknown3,
+                                      &r_s.unknown4,
+                                      &r_s.unknown5, &r_s.unknown6);
 
        /* store the response in the SMB stream */
        return svc_io_r_stop_service("", &r_s, rdata, 0);
@@ -112,8 +110,8 @@ static BOOL api_svc_stop_service( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_start_service
  ********************************************************************/
-static BOOL api_svc_start_service( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_start_service(rpcsrv_struct * p, prs_struct *data,
+                                 prs_struct *rdata)
 {
        SVC_Q_START_SERVICE q_u;
        SVC_R_START_SERVICE r_s;
@@ -127,9 +125,7 @@ static BOOL api_svc_start_service( rpcsrv_struct *p, prs_struct *data,
        }
 
        r_s.status = _svc_start_service(&q_u.pol,
-                                                 q_u.argc,
-                                                 q_u.argc2,
-                                                 q_u.argv);
+                                       q_u.argc, q_u.argc2, q_u.argv);
 
        /* store the response in the SMB stream */
        return svc_io_r_start_service("", &r_s, rdata, 0);
@@ -138,8 +134,8 @@ static BOOL api_svc_start_service( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_open_sc_man
  ********************************************************************/
-static BOOL api_svc_open_sc_man( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_open_sc_man(rpcsrv_struct * p, prs_struct *data,
+                               prs_struct *rdata)
 {
        SVC_Q_OPEN_SC_MAN q_u;
        SVC_R_OPEN_SC_MAN r_u;
@@ -153,9 +149,8 @@ static BOOL api_svc_open_sc_man( rpcsrv_struct *p, prs_struct *data,
        }
 
        r_u.status = _svc_open_sc_man(&q_u.uni_srv_name,
-                                               &q_u.uni_db_name,
-                                               q_u.des_access,
-                                               &r_u.pol);
+                                     &q_u.uni_db_name,
+                                     q_u.des_access, &r_u.pol);
 
        /* store the response in the SMB stream */
        return svc_io_r_open_sc_man("", &r_u, rdata, 0);
@@ -164,8 +159,8 @@ static BOOL api_svc_open_sc_man( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_enum_svcs_status
  ********************************************************************/
-static BOOL api_svc_enum_svcs_status( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_enum_svcs_status(rpcsrv_struct * p, prs_struct *data,
+                                    prs_struct *rdata)
 {
        SVC_Q_ENUM_SVCS_STATUS q_u;
        SVC_R_ENUM_SVCS_STATUS r_u;
@@ -185,17 +180,16 @@ static BOOL api_svc_enum_svcs_status( rpcsrv_struct *p, prs_struct *data,
        }
 
        buf_size = q_u.buf_size;
-       memcpy(&resume_hnd, &q_u.resume_hnd, sizeof(ENUM_HND));
+       resume_hnd = q_u.resume_hnd;
        status = _svc_enum_svcs_status(&q_u.pol,
-                                                q_u.service_type,
-                                                q_u.service_state,
-                                                &buf_size,
-                                                &resume_hnd,
-                                                svcs,
-                                                &more_buf_size,
-                                                &num_svcs);
-       make_svc_r_enum_svcs_status(&r_u, svcs, more_buf_size, num_svcs, &resume_hnd, status);
-       
+                                      q_u.service_type,
+                                      q_u.service_state,
+                                      &buf_size,
+                                      &resume_hnd,
+                                      svcs, &more_buf_size, &num_svcs);
+       make_svc_r_enum_svcs_status(&r_u, svcs, more_buf_size, num_svcs,
+                                   &resume_hnd, status);
+
        /* store the response in the SMB stream */
        return svc_io_r_enum_svcs_status("", &r_u, rdata, 0);
 }
@@ -203,8 +197,8 @@ static BOOL api_svc_enum_svcs_status( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_query_disp_name
  ********************************************************************/
-static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
-                                    prs_struct *rdata )
+static BOOL api_svc_query_disp_name(rpcsrv_struct * p, prs_struct *data,
+                                   prs_struct *rdata)
 {
        SVC_Q_QUERY_DISP_NAME q_u;
        SVC_R_QUERY_DISP_NAME r_u;
@@ -218,10 +212,9 @@ static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
        }
 
        r_u.status = _svc_query_disp_name(&q_u.scman_pol,
-                                                   &q_u.uni_svc_name,
-                                                   q_u.buf_size,
-                                                   &r_u.uni_disp_name,
-                                                   &r_u.buf_size);
+                                         &q_u.uni_svc_name,
+                                         q_u.buf_size,
+                                         &r_u.uni_disp_name, &r_u.buf_size);
 
        /* store the response in the SMB stream */
        return svc_io_r_query_disp_name("", &r_u, rdata, 0);
@@ -230,7 +223,7 @@ static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  api_svc_unknown_3
  ********************************************************************/
-static BOOL api_svc_unknown_3(rpcsrv_struct *p, prs_struct *data,
+static BOOL api_svc_unknown_3(rpcsrv_struct * p, prs_struct *data,
                              prs_struct *rdata)
 {
        SVC_Q_UNKNOWN_3 q_u;
@@ -253,24 +246,24 @@ static BOOL api_svc_unknown_3(rpcsrv_struct *p, prs_struct *data,
 /*******************************************************************
  array of \PIPE\svcctl operations
  ********************************************************************/
-static const struct api_struct api_svc_cmds[] =
-{
-       { "SVC_CLOSE"           , SVC_CLOSE           , api_svc_close            },
-       { "SVC_OPEN_SC_MAN"     , SVC_OPEN_SC_MAN     , api_svc_open_sc_man      },
-       { "SVC_OPEN_SERVICE"    , SVC_OPEN_SERVICE    , api_svc_open_service     },
-       { "SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS, api_svc_enum_svcs_status },
-       { "SVC_QUERY_DISP_NAME" , SVC_QUERY_DISP_NAME , api_svc_query_disp_name  },
-       { "SVC_START_SERVICE"   , SVC_START_SERVICE   , api_svc_start_service    },
-       { "SVC_STOP_SERVICE"    , SVC_STOP_SERVICE    , api_svc_stop_service     },
-       { "SVC_UNKNOWN_3"       , SVC_UNKNOWN_3       , api_svc_unknown_3        },
-       { NULL                  , 0                   , NULL                     }
+static const struct api_struct api_svc_cmds[] = {
+       {"SVC_CLOSE", SVC_CLOSE, api_svc_close},
+       {"SVC_OPEN_SC_MAN", SVC_OPEN_SC_MAN, api_svc_open_sc_man},
+       {"SVC_OPEN_SERVICE", SVC_OPEN_SERVICE, api_svc_open_service},
+       
+               {"SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS,
+        api_svc_enum_svcs_status},
+       {"SVC_QUERY_DISP_NAME", SVC_QUERY_DISP_NAME, api_svc_query_disp_name},
+       {"SVC_START_SERVICE", SVC_START_SERVICE, api_svc_start_service},
+       {"SVC_STOP_SERVICE", SVC_STOP_SERVICE, api_svc_stop_service},
+       {"SVC_UNKNOWN_3", SVC_UNKNOWN_3, api_svc_unknown_3},
+       {NULL, 0, NULL}
 };
 
 /*******************************************************************
  receives a svcctl pipe and responds.
  ********************************************************************/
-BOOL api_svcctl_rpc(rpcsrv_struct *p)
+BOOL api_svcctl_rpc(rpcsrv_struct * p)
 {
        return api_rpcTNP(p, "api_svc_rpc", api_svc_cmds);
 }
-
index c8b522d6e7916b2971a6920a8db9732a3e15252f..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
+.libs
 *.lo
index e342493d9beb3a5f39df6855a5efc963a03cc0fa..434accd2403d1bc5c1fec4373bc095157098194d 100644 (file)
@@ -31,8 +31,8 @@ extern int DEBUGLEVEL;
 
 #if 0
 static BOOL tdb_lookup_user_als(TDB_CONTEXT * tdb,
-                               const DOM_SID * sid,
-                               uint32 * num_rids, uint32 ** rids)
+                               const DOM_SID *sid,
+                               uint32 *num_rids, uint32 **rids)
 {
        prs_struct key;
        prs_struct data;
@@ -62,7 +62,7 @@ static BOOL tdb_lookup_user_als(TDB_CONTEXT * tdb,
 
 static BOOL tdb_lookup_user_grps(TDB_CONTEXT * tdb,
                                 uint32 rid,
-                                uint32 * num_gids, DOM_GID ** gids)
+                                uint32 *num_gids, DOM_GID ** gids)
 {
        prs_struct key;
        prs_struct data;
@@ -143,8 +143,8 @@ static BOOL tdb_store_user_grps(TDB_CONTEXT * tdb,
 }
 
 static BOOL tdb_store_user_als(TDB_CONTEXT * tdb,
-                              const DOM_SID * sid,
-                              uint32 num_rids, uint32 * rids)
+                              const DOM_SID *sid,
+                              uint32 num_rids, uint32 *rids)
 {
        prs_struct key;
        prs_struct data;
@@ -245,8 +245,8 @@ static BOOL tdb_set_userinfo_pwds(TDB_CONTEXT * tdb,
                return False;
        }
 
-       memcpy(usr.lm_pwd, lm_pwd, sizeof(usr.lm_pwd));
-       memcpy(usr.nt_pwd, nt_pwd, sizeof(usr.nt_pwd));
+       Memcpy(usr.lm_pwd, lm_pwd, sizeof(usr.lm_pwd));
+       Memcpy(usr.nt_pwd, nt_pwd, sizeof(usr.nt_pwd));
 
        if (!tdb_store_user(tdb, &usr))
        {
@@ -272,7 +272,7 @@ static BOOL tdb_set_userinfo_21(TDB_CONTEXT * tdb,
 {
        SAM_USER_INFO_21 usr;
        BOOL ret;
-       
+
        UNISTR2 *uni_user_name;
        UNISTR2 *uni_full_name;
        UNISTR2 *uni_home_dir;
@@ -295,42 +295,55 @@ static BOOL tdb_set_userinfo_21(TDB_CONTEXT * tdb,
                return False;
        }
 
-       uni_user_name = choose_unistr2( &usr21->uni_user_name, &usr.uni_user_name);
-       uni_full_name = choose_unistr2( &usr21->uni_full_name, &usr.uni_full_name);
-       uni_home_dir = choose_unistr2( &usr21->uni_home_dir, &usr.uni_home_dir);
-       uni_dir_drive = choose_unistr2( &usr21->uni_dir_drive, &usr.uni_dir_drive);
-       uni_logon_script = choose_unistr2( &usr21->uni_logon_script, &usr.uni_logon_script);
-       uni_profile_path = choose_unistr2( &usr21->uni_profile_path, &usr.uni_profile_path);
-       uni_acct_desc = choose_unistr2( &usr21->uni_acct_desc, &usr.uni_acct_desc);
-       uni_workstations = choose_unistr2( &usr21->uni_workstations, &usr.uni_workstations);
-       uni_unknown_str = choose_unistr2( &usr21->uni_unknown_str, &usr.uni_unknown_str);
-       uni_munged_dial = choose_unistr2( &usr21->uni_munged_dial, &usr.uni_munged_dial);
+       uni_user_name =
+               choose_unistr2(&usr21->uni_user_name, &usr.uni_user_name);
+       uni_full_name =
+               choose_unistr2(&usr21->uni_full_name, &usr.uni_full_name);
+       uni_home_dir =
+               choose_unistr2(&usr21->uni_home_dir, &usr.uni_home_dir);
+       uni_dir_drive =
+               choose_unistr2(&usr21->uni_dir_drive, &usr.uni_dir_drive);
+       uni_logon_script =
+               choose_unistr2(&usr21->uni_logon_script,
+                              &usr.uni_logon_script);
+       uni_profile_path =
+               choose_unistr2(&usr21->uni_profile_path,
+                              &usr.uni_profile_path);
+       uni_acct_desc =
+               choose_unistr2(&usr21->uni_acct_desc, &usr.uni_acct_desc);
+       uni_workstations =
+               choose_unistr2(&usr21->uni_workstations,
+                              &usr.uni_workstations);
+       uni_unknown_str =
+               choose_unistr2(&usr21->uni_unknown_str, &usr.uni_unknown_str);
+       uni_munged_dial =
+               choose_unistr2(&usr21->uni_munged_dial, &usr.uni_munged_dial);
 
        ret = make_sam_user_info21W(&usr,
-                                  &usr21->logon_time,
-                                  &usr21->logoff_time,
-                                  &usr21->kickoff_time,
-                                  &usr21->pass_last_set_time,
-                                  &usr21->pass_can_change_time,
-                                  &usr21->pass_must_change_time,
-                                  uni_user_name,
-                                  uni_full_name,
-                                  uni_home_dir,
-                                  uni_dir_drive,
-                                  uni_logon_script,
-                                  uni_profile_path,
-                                  uni_acct_desc,
-                                  uni_workstations,
-                                  uni_unknown_str,
-                                  uni_munged_dial,
-                                  usr.lm_pwd, usr.nt_pwd,
-                                  usr.user_rid,
-                                  usr21->group_rid,
-                                  usr21->acb_info,
-                                  usr21->unknown_3,
-                                  usr21->logon_divs,
-                                  &usr21->logon_hrs,
-                                  usr21->unknown_5, usr21->unknown_6);
+                                   &usr21->logon_time,
+                                   &usr21->logoff_time,
+                                   &usr21->kickoff_time,
+                                   &usr21->pass_last_set_time,
+                                   &usr21->pass_can_change_time,
+                                   &usr21->pass_must_change_time,
+                                   uni_user_name,
+                                   uni_full_name,
+                                   uni_home_dir,
+                                   uni_dir_drive,
+                                   uni_logon_script,
+                                   uni_profile_path,
+                                   uni_acct_desc,
+                                   uni_workstations,
+                                   uni_unknown_str,
+                                   uni_munged_dial,
+                                   usr.lm_pwd, usr.nt_pwd,
+                                   usr.user_rid,
+                                   usr21->group_rid,
+                                   usr21->acb_info,
+                                   usr21->unknown_3,
+                                   usr21->logon_divs,
+                                   &usr21->logon_hrs,
+                                   usr21->unknown_5, usr21->unknown_6);
 
        unistr2_free(uni_user_name);
        unistr2_free(uni_full_name);
@@ -366,7 +379,7 @@ static BOOL tdb_set_userinfo_23(TDB_CONTEXT * tdb,
 {
        SAM_USER_INFO_21 usr;
        BOOL ret;
-       
+
        UNISTR2 *uni_user_name;
        UNISTR2 *uni_full_name;
        UNISTR2 *uni_home_dir;
@@ -389,42 +402,55 @@ static BOOL tdb_set_userinfo_23(TDB_CONTEXT * tdb,
                return False;
        }
 
-       uni_user_name = choose_unistr2( &usr23->uni_user_name, &usr.uni_user_name);
-       uni_full_name = choose_unistr2( &usr23->uni_full_name, &usr.uni_full_name);
-       uni_home_dir = choose_unistr2( &usr23->uni_home_dir, &usr.uni_home_dir);
-       uni_dir_drive = choose_unistr2( &usr23->uni_dir_drive, &usr.uni_dir_drive);
-       uni_logon_script = choose_unistr2( &usr23->uni_logon_script, &usr.uni_logon_script);
-       uni_profile_path = choose_unistr2( &usr23->uni_profile_path, &usr.uni_profile_path);
-       uni_acct_desc = choose_unistr2( &usr23->uni_acct_desc, &usr.uni_acct_desc);
-       uni_workstations = choose_unistr2( &usr23->uni_workstations, &usr.uni_workstations);
-       uni_unknown_str = choose_unistr2( &usr23->uni_unknown_str, &usr.uni_unknown_str);
-       uni_munged_dial = choose_unistr2( &usr23->uni_munged_dial, &usr.uni_munged_dial);
+       uni_user_name =
+               choose_unistr2(&usr23->uni_user_name, &usr.uni_user_name);
+       uni_full_name =
+               choose_unistr2(&usr23->uni_full_name, &usr.uni_full_name);
+       uni_home_dir =
+               choose_unistr2(&usr23->uni_home_dir, &usr.uni_home_dir);
+       uni_dir_drive =
+               choose_unistr2(&usr23->uni_dir_drive, &usr.uni_dir_drive);
+       uni_logon_script =
+               choose_unistr2(&usr23->uni_logon_script,
+                              &usr.uni_logon_script);
+       uni_profile_path =
+               choose_unistr2(&usr23->uni_profile_path,
+                              &usr.uni_profile_path);
+       uni_acct_desc =
+               choose_unistr2(&usr23->uni_acct_desc, &usr.uni_acct_desc);
+       uni_workstations =
+               choose_unistr2(&usr23->uni_workstations,
+                              &usr.uni_workstations);
+       uni_unknown_str =
+               choose_unistr2(&usr23->uni_unknown_str, &usr.uni_unknown_str);
+       uni_munged_dial =
+               choose_unistr2(&usr23->uni_munged_dial, &usr.uni_munged_dial);
 
        ret = make_sam_user_info21W(&usr,
-                                  &usr23->logon_time,
-                                  &usr23->logoff_time,
-                                  &usr23->kickoff_time,
-                                  &usr23->pass_last_set_time,
-                                  &usr23->pass_can_change_time,
-                                  &usr23->pass_must_change_time,
-                                  uni_user_name,
-                                  uni_full_name,
-                                  uni_home_dir,
-                                  uni_dir_drive,
-                                  uni_logon_script,
-                                  uni_profile_path,
-                                  uni_acct_desc,
-                                  uni_workstations,
-                                  uni_unknown_str,
-                                  uni_munged_dial,
-                                  lm_pwd, nt_pwd,
-                                  usr.user_rid,
-                                  usr23->group_rid,
-                                  usr23->acb_info,
-                                  usr.unknown_3,
-                                  usr23->logon_divs,
-                                  &usr23->logon_hrs,
-                                  usr23->unknown_5, usr23->unknown_6);
+                                   &usr23->logon_time,
+                                   &usr23->logoff_time,
+                                   &usr23->kickoff_time,
+                                   &usr23->pass_last_set_time,
+                                   &usr23->pass_can_change_time,
+                                   &usr23->pass_must_change_time,
+                                   uni_user_name,
+                                   uni_full_name,
+                                   uni_home_dir,
+                                   uni_dir_drive,
+                                   uni_logon_script,
+                                   uni_profile_path,
+                                   uni_acct_desc,
+                                   uni_workstations,
+                                   uni_unknown_str,
+                                   uni_munged_dial,
+                                   lm_pwd, nt_pwd,
+                                   usr.user_rid,
+                                   usr23->group_rid,
+                                   usr23->acb_info,
+                                   usr.unknown_3,
+                                   usr23->logon_divs,
+                                   &usr23->logon_hrs,
+                                   usr23->unknown_5, usr23->unknown_6);
 
        unistr2_free(uni_user_name);
        unistr2_free(uni_full_name);
@@ -457,9 +483,8 @@ static BOOL tdb_set_userinfo_23(TDB_CONTEXT * tdb,
  samr_reply_get_usrdom_pwinfo
  ********************************************************************/
 uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
-                              uint16 * unknown_0,
-                              uint16 *unknown_1,
-                              uint32 * unknown_2)
+                              uint16 *unknown_0,
+                              uint16 *unknown_1, uint32 *unknown_2)
 {
        uint32 rid;
        TDB_CONTEXT *tdb = NULL;
@@ -484,7 +509,7 @@ uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
  samr_reply_query_usergroups
  ********************************************************************/
 uint32 _samr_query_usergroups(const POLICY_HND *pol,
-                             uint32 * num_groups, DOM_GID ** gids)
+                             uint32 *num_groups, DOM_GID ** gids)
 {
 #if 0
        uint32 rid;
@@ -516,8 +541,8 @@ uint32 _samr_query_usergroups(const POLICY_HND *pol,
  samr_reply_query_useraliases
  ********************************************************************/
 uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
-                              const uint32 * ptr_sid, const DOM_SID2 * sid,
-                              uint32 * num_aliases, uint32 ** rid)
+                              const uint32 *ptr_sid, const DOM_SID2 * sid,
+                              uint32 *num_aliases, uint32 **rid)
 {
 #if 0
        TDB_CONTEXT *tdb = NULL;
@@ -578,7 +603,7 @@ uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
        TDB_CONTEXT *tdb_usr = NULL;
        SAM_USER_INFO_21 usr;
 
-       DEBUG(10,("_samr_query_userinfo: %d\n", __LINE__));
+       DEBUG(10, ("_samr_query_userinfo: %d\n", __LINE__));
 
        /* find the policy handle.  open a policy on it. */
        if (!get_tdbsam(get_global_hnd_cache(), pol, &tdb_usr))
@@ -618,7 +643,7 @@ static BOOL set_user_info_24(TDB_CONTEXT * usr_tdb,
 
        for (i = 0; i < new_pw.uni_str_len; i++)
        {
-               new_pw.buffer[i] = SVAL(buf, i*2);
+               new_pw.buffer[i] = SVAL(buf, i * 2);
        }
 
        nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
@@ -673,7 +698,7 @@ static BOOL set_user_info_23(TDB_CONTEXT * usr_tdb,
 
        for (i = 0; i < new_pw.uni_str_len; i++)
        {
-               new_pw.buffer[i] = SVAL(buf, i*2);
+               new_pw.buffer[i] = SVAL(buf, i * 2);
        }
 
        nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
@@ -827,7 +852,8 @@ uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
 
                        if (!set_user_info_12(tdb_usr, id12))
                        {
-                               DEBUG(10, ("_samr_set_userinfo 0x12 failed\n"));
+                               DEBUG(10,
+                                     ("_samr_set_userinfo 0x12 failed\n"));
                                return NT_STATUS_ACCESS_DENIED;
                        }
                        break;
@@ -852,7 +878,7 @@ uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
 }
 
 static void create_user_info_21(SAM_USER_INFO_21 * usr,
-                               const UNISTR2 * uni_user_name,
+                               const UNISTR2 *uni_user_name,
                                uint16 acb_info, uint32 user_rid,
                                uint32 group_rid)
 {
@@ -908,10 +934,10 @@ static void create_user_info_21(SAM_USER_INFO_21 * usr,
  _samr_create_user
  ********************************************************************/
 uint32 _samr_create_user(const POLICY_HND *domain_pol,
-                        const UNISTR2 * uni_username,
+                        const UNISTR2 *uni_username,
                         uint16 acb_info, uint32 access_mask,
                         POLICY_HND *user_pol,
-                        uint32 * unknown_0, uint32 * user_rid)
+                        uint32 *unknown_0, uint32 *user_rid)
 {
        DOM_SID dom_sid;
        DOM_SID usr_sid;
@@ -943,6 +969,8 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
        uint32 *als_rids = NULL;
 #endif
 
+       POSIX_ID id;
+
        (*unknown_0) = 0x30;
        (*user_rid) = 0x0;
 
@@ -954,7 +982,7 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
        }
 
        sid_to_string(riddb, &dom_sid);
-       safe_strcat(riddb, "/dom.tdb", sizeof(riddb)-1);
+       safe_strcat(riddb, "/dom.tdb", sizeof(riddb) - 1);
 
        status1 = _samr_lookup_names(domain_pol, 1, 0x3e8, 1, uni_username,
                                     &num_rids, &rid, &num_types, &type);
@@ -1004,9 +1032,10 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
 
                for (i = 0; i < n_groups; i++)
                {
-                       if (surs_unixid_to_sam_sid(groups[i],
-                                                     SID_NAME_ALIAS,
-                                                     &grp_sid, True))
+                       id.id = groups[i];
+                       id.type = SURS_POSIX_GID_AS_ALS;
+
+                       if (surs_unixid_to_sam_sid(&id, &grp_sid, True))
                        {
                                uint32 grp_rid = 0xffffffff;
                                if (!sid_split_rid(&grp_sid, &grp_rid))
@@ -1022,9 +1051,11 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
                                        num_alss++;
                                }
                        }
-                       if (surs_unixid_to_sam_sid(groups[i],
-                                                     SID_NAME_DOM_GRP,
-                                                     &grp_sid, True))
+
+                       id.id = groups[i];
+                       id.type = SURS_POSIX_GID_AS_GRP;
+
+                       if (surs_unixid_to_sam_sid(&id, &grp_sid, True))
                        {
                                uint32 grp_rid = 0xffffffff;
                                if (!sid_split_rid(&grp_sid, &grp_rid))
@@ -1045,7 +1076,7 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
 #endif
        }
 
-       tdb_dom = tdb_open(passdb_path(riddb),0,0,O_RDWR, 600);
+       tdb_dom = tdb_open(passdb_path(riddb), 0, 0, O_RDWR, 600);
        if (tdb_dom == NULL || tdb_writelock(tdb_dom) != 0)
        {
                tdb_close(tdb_dom);
@@ -1087,8 +1118,10 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
        sid_copy(&sid, &usr_sid);
 
        /* create a User SID for the unix user */
-       if (!surs_unixid_to_sam_sid(pass->pw_uid, SID_NAME_USER, &usr_sid,
-                                      True))
+       id.id = pass->pw_uid;
+       id.type = SURS_POSIX_UID_AS_USR;
+
+       if (!surs_unixid_to_sam_sid(&id, &usr_sid, True))
        {
                DEBUG(0, ("create user: unix uid %d to RID failed\n",
                          pass->pw_uid));
@@ -1111,8 +1144,10 @@ uint32 _samr_create_user(const POLICY_HND *domain_pol,
        sid_copy(&sid, &grp_sid);
 
        /* create a Group SID for the unix user */
-       if (!surs_unixid_to_sam_sid
-           (pass->pw_gid, SID_NAME_DOM_GRP, &grp_sid, True))
+       id.id = pass->pw_gid;
+       id.type = SURS_POSIX_GID_AS_GRP;
+
+       if (!surs_unixid_to_sam_sid(&id, &grp_sid, True))
        {
                DEBUG(0, ("create user: unix uid %d to RID failed\n",
                          pass->pw_uid));
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 16996561a013a4f7e34e92a32386756f484745f7..b77f5bf174e6b7ebf37c548a2620b2e0511b6a3a 100644 (file)
@@ -110,6 +110,14 @@ END {
     gotstart = 1;
   }
 
+  if( $0 ~ /^hash_element/ ) {
+    gotstart = 1;
+  }
+
+  if( $0 ~ /^SMB_STRUCT_DIRENT/ ) {
+    gotstart = 1;
+  }
+
   if( $0 ~ /^UNISTR2|^LOCAL_GRP|^DOMAIN_GRP|^DOM_SID|^SEC_DESC/ ) {
     gotstart = 1;
   }
@@ -118,7 +126,7 @@ END {
     gotstart = 1;
   }
 
-  if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t/ ) {
+  if( $0 ~ /^TALLOC_CTX|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^smb_ucs1_t/ ) {
     gotstart = 1;
   }
 
index c8b522d6e7916b2971a6920a8db9732a3e15252f..455336d2ee61413b416887ac2fa4406bc198ef7f 100644 (file)
@@ -1 +1,2 @@
+.libs
 *.lo
index 96833286e2b84fe7db424612600a681961126466..deb9bae9d1c5a2f8bd7144b8941d3b4319a353f4 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    Blocking Locking functions
-   Copyright (C) Jeremy Allison 1998
+   Copyright (C) Jeremy Allison 1998-2000
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@
 
 extern int DEBUGLEVEL;
 extern int Client;
-extern int chain_size;
 extern char *OutBuffer;
 
 /****************************************************************************
@@ -210,21 +209,25 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
    * of smb_lkrng structs.
    */
 
-  for(i = blr->lock_num; i >= 0; i--) {
+  /*
+   * Ensure we don't do a remove on the lock that just failed,
+   * as under POSIX rules, if we have a lock already there, we
+   * will delete it (and we shouldn't) .....
+   */
+
+  for(i = blr->lock_num - 1; i >= 0; i--) {
     int dummy1;
     uint32 dummy2;
-    if(!large_file_format) {
-      count = IVAL(data,SMB_LKLEN_OFFSET(i));
-      offset = IVAL(data,SMB_LKOFF_OFFSET(i));
-    }
-#ifdef LARGE_SMB_OFF_T
-    else {
-      count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
-              ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
-      offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
-               ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
-    }
-#endif /* LARGE_SMB_OFF_T */
+    BOOL err;
+
+    count = get_lock_count( data, i, large_file_format, &err);
+    offset = get_lock_offset( data, i, large_file_format, &err);
+
+    /*
+     * We know err cannot be set as if it was the lock
+     * request would never have been queued. JRA.
+     */
+
     do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
   }
 
@@ -278,7 +281,7 @@ static BOOL process_lockread(blocking_lock_record *blr)
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
  
-  if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
+  if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) {
     if((errno != EACCES) && (errno != EAGAIN)) {
       /*
        * We have other than a "can't get lock" POSIX
@@ -315,7 +318,7 @@ static BOOL process_lockread(blocking_lock_record *blr)
   SSVAL(smb_buf(outbuf),1,nread);
 
   DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
-        fsp->fsp_name, fsp->fnum, numtoread, nread ) );
+        fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
 
   send_blocking_reply(outbuf,outsize);
   return True;
@@ -341,7 +344,7 @@ static BOOL process_lock(blocking_lock_record *blr)
   offset = IVAL(inbuf,smb_vwv3);
 
   errno = 0;
-  if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
+  if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) {
     if((errno != EACCES) && (errno != EAGAIN)) {
 
       /*
@@ -403,20 +406,17 @@ static BOOL process_lockingX(blocking_lock_record *blr)
    */
 
   for(; blr->lock_num < num_locks; blr->lock_num++) {
-    if(!large_file_format) {
-      count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num));
-      offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num));
-    }
-#ifdef LARGE_SMB_OFF_T
-    else {
-      count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(blr->lock_num))) << 32) |
-              ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(blr->lock_num)));
-      offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) |
-               ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num)));
-    }
-#endif /* LARGE_SMB_OFF_T */
+    BOOL err;
+
+    count = get_lock_count( data, blr->lock_num, large_file_format, &err);
+    offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
+
+    /*
+     * We know err cannot be set as if it was the lock
+     * request would never have been queued. JRA.
+     */
     errno = 0;
-    if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
+    if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
                 &eclass, &ecode))
       break;
   }
@@ -528,6 +528,16 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
   }
 }
 
+/****************************************************************************
+ Return True if the blocking lock queue has entries.
+*****************************************************************************/
+
+BOOL blocking_locks_pending(void)
+{
+  blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+  return (blr == NULL ? False : True);
+}
+
 /****************************************************************************
  Process the blocking lock queue. Note that this is only called as root.
 *****************************************************************************/
index 2b1abc9174ef0b5f1d30d69946c6dd0cd7458d8e..c4ec3981f8a7ee111ccd56307b6feb03d5843e53 100644 (file)
 extern int DEBUGLEVEL;
 
 #if ALLOW_CHANGE_PASSWORD
-#define MINPASSWDLENGTH 5
-#define BUFSIZE 512
 
 static int findpty(char **slave)
 {
        int master;
-#ifndef HAVE_GRANTPT
        static fstring line;
        DIR *dirp;
-       struct dirent *dentry;
        char *dpname;
-#endif /* !HAVE_GRANTPT */
 
 #if defined(HAVE_GRANTPT)
-       if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 1)
+       /* Try to open /dev/ptmx. If that fails, fall through to old method. */
+       if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 0)
        {
                grantpt(master);
                unlockpt(master);
-               *slave = ptsname(master);
+               *slave = (char *)ptsname(master);
                if (*slave == NULL)
                {
                        DEBUG(0,
@@ -86,15 +82,15 @@ static int findpty(char **slave)
                        return (master);
                }
        }
-#else /* HAVE_GRANTPT */
+#endif /* HAVE_GRANTPT */
+
        fstrcpy(line, "/dev/ptyXX");
 
        dirp = opendir("/dev");
        if (!dirp)
                return (-1);
-       while ((dentry = readdir(dirp)) != NULL)
+       while ((dpname = readdirname(dirp)) != NULL)
        {
-               dpname = dentry->d_name;
                if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5)
                {
                        DEBUG(3,
@@ -113,7 +109,6 @@ static int findpty(char **slave)
                }
        }
        closedir(dirp);
-#endif /* HAVE_GRANTPT */
        return (-1);
 }
 
@@ -228,99 +223,90 @@ static int dochild(int master, char *slavedev, const char *_name,
        return (True);
 }
 
-static int expect(int master, char *expected, char *buf)
+static int expect(int master, char *issue, char *expected)
 {
-       int n, m;
+       pstring buffer;
+       int attempts, timeout, nread, len;
+       BOOL match = False;
 
-       n = 0;
-       buf[0] = 0;
-       while (1)
+       for (attempts = 0; attempts < 2; attempts++)
        {
-               if (n >= BUFSIZE - 1)
+               if (!strequal(issue, "."))
                {
-                       return False;
+                       if (lp_passwd_chat_debug())
+                               DEBUG(100, ("expect: sending [%s]\n", issue));
+
+                       write(master, issue, strlen(issue));
                }
 
-               /* allow 4 seconds for some output to appear */
-               m =
-                       read_with_timeout(master, buf + n, 1, BUFSIZE - 1 - n,
-                                         4000);
-               if (m < 0)
-                       return False;
+               if (strequal(expected, "."))
+                       return True;
 
-               n += m;
-               buf[n] = 0;
+               timeout = 2000;
+               nread = 0;
+               buffer[nread] = 0;
 
+               while ((len = read_with_timeout(master, buffer + nread, 1,
+                                               sizeof(buffer) - nread - 1,
+                                               timeout)) > 0)
                {
-                       pstring s1, s2;
-                       pstrcpy(s1, buf);
-                       pstrcpy(s2, expected);
-                       if (do_match(s1, s2, False))
-                               return (True);
+                       nread += len;
+                       buffer[nread] = 0;
+
+                       if ((match = unix_do_match(buffer, expected, False)))
+                               timeout = 200;
                }
+
+               if (lp_passwd_chat_debug())
+                       DEBUG(100, ("expect: expected [%s] received [%s]\n",
+                                   expected, buffer));
+
+               if (match)
+                       break;
+
+               if (len < 0)
+               {
+                       DEBUG(2, ("expect: %s\n", strerror(errno)));
+                       return False;
        }
 }
 
-static void pwd_sub(char *buf)
-{
-       string_sub(buf, "\\n", "\n");
-       string_sub(buf, "\\r", "\r");
-       string_sub(buf, "\\s", " ");
-       string_sub(buf, "\\t", "\t");
+       return match;
 }
 
-static void writestring(int fd, char *s)
+static void pwd_sub(char *buf)
 {
-       int l;
-
-       l = strlen(s);
-       write(fd, s, l);
+       all_string_sub(buf, "\\n", "\n", 0);
+       all_string_sub(buf, "\\r", "\r", 0);
+       all_string_sub(buf, "\\s", " ", 0);
+       all_string_sub(buf, "\\t", "\t", 0);
 }
 
-
-static int talktochild(int master, char *chatsequence)
+static int talktochild(int master, char *seq)
 {
-       char buf[BUFSIZE];
        int count = 0;
-       char *ptr = chatsequence;
-       fstring chatbuf;
+       fstring issue, expected;
 
-       *buf = 0;
-       sleep(1);
+       fstrcpy(issue, ".");
 
-       while (next_token(&ptr, chatbuf, NULL, sizeof(chatbuf)))
+       while (next_token(&seq, expected, NULL, sizeof(expected)))
        {
-               BOOL ok = True;
+               pwd_sub(expected);
                count++;
-               pwd_sub(chatbuf);
-               if (!strequal(chatbuf, "."))
-                       ok = expect(master, chatbuf, buf);
-
-               if (lp_passwd_chat_debug())
-                       DEBUG(100,
-                             ("talktochild: chatbuf=[%s] responsebuf=[%s]\n",
-                              chatbuf, buf));
 
-               if (!ok)
+               if (!expect(master, issue, expected))
                {
-                       DEBUG(3, ("response %d incorrect\n", count));
-                       return (False);
+                       DEBUG(3, ("Response %d incorrect\n", count));
+                       return False;
                }
 
-               if (!next_token(&ptr, chatbuf, NULL, sizeof(chatbuf)))
-                       break;
-               pwd_sub(chatbuf);
-               if (!strequal(chatbuf, "."))
-                       writestring(master, chatbuf);
+               if (!next_token(&seq, issue, NULL, sizeof(issue)))
+                       fstrcpy(issue, ".");
 
-               if (lp_passwd_chat_debug())
-                       DEBUG(100, ("talktochild: sendbuf=[%s]\n", chatbuf));
+               pwd_sub(issue);
        }
 
-       if (count < 1)
-               return (False);
-
-       return (True);
+       return (count > 0);
 }
 
 
@@ -342,12 +328,20 @@ static BOOL chat_with_program(char *passwordprogram, const char *name,
                return (False);
        }
 
+       /*
+        * We need to temporarily stop CatchChild from eating
+        * SIGCLD signals as it also eats the exit status code. JRA.
+        */
+
+       CatchChildLeaveStatus();
+
        if ((pid = fork()) < 0)
        {
                DEBUG(3,
                      ("Cannot fork() child for password change: %s\n",
                       name));
                close(master);
+               CatchChild();
                return (False);
        }
 
@@ -362,13 +356,29 @@ static BOOL chat_with_program(char *passwordprogram, const char *name,
                        kill(pid, SIGKILL);     /* be sure to end this process */
                }
 
-               if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
+               while ((wpid = sys_waitpid(pid, &wstat, 0)) < 0)
+               {
+                       if (errno == EINTR)
+                       {
+                               errno = 0;
+                               continue;
+                       }
+                       break;
+               }
+
+               if (wpid < 0)
                {
                        DEBUG(3, ("The process is no longer waiting!\n\n"));
                        close(master);
+                       CatchChild();
                        return (False);
                }
 
+               /*
+                * Go back to ignoring children.
+                */
+               CatchChild();
+
                close(master);
 
                if (pid != wpid)
@@ -415,8 +425,14 @@ static BOOL chat_with_program(char *passwordprogram, const char *name,
                        dochild(master, slavedev, name, passwordprogram,
                                as_root);
 
-               if (as_root)
-                       unbecome_root(False);
+               /*
+                * The child should never return from dochild() ....
+                */
+
+               DEBUG(0,
+                     ("chat_with_program: Error: dochild() returned %d\n",
+                      chstat));
+               exit(1);
        }
 
        if (chstat)
@@ -431,8 +447,7 @@ BOOL chgpasswd(const char *_name, char *oldpass, char *newpass, BOOL as_root)
 {
        pstring passwordprogram;
        pstring chatsequence;
-       int i;
-       int len;
+       size_t i, len;
        fstring name;
 
        fstrcpy(name, _name);
@@ -445,11 +460,11 @@ BOOL chgpasswd(const char *_name, char *oldpass, char *newpass, BOOL as_root)
 
        /* Take the passed information and test it for minimum criteria */
        /* Minimum password length */
-       if (strlen(newpass) < MINPASSWDLENGTH)  /* too short, must be at least MINPASSWDLENGTH */
+       if (strlen(newpass) < lp_min_passwd_length())   /* too short, must be at least MINPASSWDLENGTH */
        {
-               DEBUG(2,
-                     ("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",
-                      name));
+               DEBUG(0,
+                     ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
+                      name, lp_min_passwd_length()));
                return (False); /* inform the user */
        }
 
@@ -503,11 +518,12 @@ BOOL chgpasswd(const char *_name, char *oldpass, char *newpass, BOOL as_root)
                }
        }
 
-       string_sub(passwordprogram, "%u", name);
-       all_string_sub(passwordprogram, "%o", oldpass, 0);
-       all_string_sub(passwordprogram, "%n", newpass, 0);
+       pstring_sub(passwordprogram, "%u", name);
+       /* note that we do NOT substitute the %o and %n in the password program
+          as this would open up a security hole where the user could use
+          a new password containing shell escape characters */
 
-       string_sub(chatsequence, "%u", name);
+       pstring_sub(chatsequence, "%u", name);
        all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring));
        all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
        return (chat_with_program
@@ -550,15 +566,8 @@ static BOOL check_oem_password(const char *user,
 
        BOOL nt_pass_set = (_ntdata != NULL && nthash != NULL);
 
-       if (_lmdata != NULL)
-       {
-               memcpy(lmdata, _lmdata, sizeof(lmdata));
-       }
-
-       if (_ntdata != NULL)
-       {
-               memcpy(ntdata, _ntdata, sizeof(ntdata));
-       }
+       Memcpy(lmdata, _lmdata, sizeof(lmdata));
+       Memcpy(ntdata, _ntdata, sizeof(ntdata));
 
        become_root(False);
        (*psmbpw) = smbpw = getsmbpwnam(user);
index f588f248487f46bc8b905d3f5b7f468e1efa78f6..905b1c5b947615905ddaafe4f85c231abd506bdc 100644 (file)
@@ -23,9 +23,6 @@
 
 extern int DEBUGLEVEL;
 
-extern int32 global_oplocks_open;
-
-
 /****************************************************************************
 run a file if it is a magic script
 ****************************************************************************/
@@ -72,6 +69,8 @@ static void close_filestruct(files_struct *fsp)
 {   
        connection_struct *conn = fsp->conn;
     
+    flush_write_cache(fsp, CLOSE_FLUSH);
+
        fsp->open = False;
        fsp->is_directory = False; 
     
@@ -80,13 +79,6 @@ static void close_filestruct(files_struct *fsp)
                free((char *)fsp->wbmpx_ptr);
                fsp->wbmpx_ptr = NULL; 
        }  
-     
-#if WITH_MMAP
-       if(fsp->mmap_ptr) {
-               munmap(fsp->mmap_ptr,fsp->mmap_size);
-               fsp->mmap_ptr = NULL;
-       }  
-#endif 
 }    
 
 /****************************************************************************
@@ -97,13 +89,15 @@ static void close_filestruct(files_struct *fsp)
  the closing of the connection. In the latter case printing and
  magic scripts are not run.
 ****************************************************************************/
-void close_file(files_struct *fsp, BOOL normal_close)
+
+static int close_normal_file(files_struct *fsp, BOOL normal_close)
 {
        SMB_DEV_T dev = fsp->fd_ptr->dev;
        SMB_INO_T inode = fsp->fd_ptr->inode;
-    BOOL last_reference = False;
-    BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
+       BOOL last_reference = False;
+       BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
        connection_struct *conn = fsp->conn;
+       int err = 0;
 
        remove_pending_lock_requests_by_fid(fsp);
 
@@ -118,10 +112,15 @@ void close_file(files_struct *fsp, BOOL normal_close)
                del_share_mode(fsp);
        }
 
-       if(fd_attempt_close(fsp) == 0)
+       if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+               release_file_oplock(fsp);
+
+       locking_close_file(fsp);
+
+       if(fd_attempt_close(fsp, &err) == 0)
                last_reference = True;
 
-    fsp->fd_ptr = NULL;
+        fsp->fd_ptr = NULL;
 
        if (lp_share_modes(SNUM(conn)))
                unlock_share_entry(conn, dev, inode);
@@ -161,30 +160,46 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
         }
     }
 
-       if(fsp->granted_oplock == True)
-               global_oplocks_open--;
-
-       fsp->sent_oplock_break = False;
-
-       DEBUG(2,("%s closed file %s (numopen=%d)\n",
+       DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
                 conn->user,fsp->fsp_name,
-                conn->num_files_open));
+                conn->num_files_open, err ? strerror(err) : ""));
 
        if (fsp->fsp_name) {
                string_free(&fsp->fsp_name);
        }
 
        file_free(fsp);
+
+       return err;
 }
 
 /****************************************************************************
  Close a directory opened by an NT SMB call. 
 ****************************************************************************/
   
-void close_directory(files_struct *fsp)
+static int close_directory(files_struct *fsp, BOOL normal_close)
 {
        remove_pending_change_notify_requests_by_fid(fsp);
 
+       /*
+        * NT can set delete_on_close of the last open
+        * reference to a directory also.
+        */
+
+       if (normal_close && fsp->directory_delete_on_close) {
+               BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
+               DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
+                       fsp->fsp_name, ok ? "succeeded" : "failed" ));
+
+               /*
+                * Ensure we remove any change notify requests that would
+                * now fail as the directory has been deleted.
+                */
+
+               if(ok)
+                       remove_pending_change_notify_requests_by_filename(fsp);
+    }
+
        /*
         * Do the code common to files and directories.
         */
@@ -194,5 +209,35 @@ void close_directory(files_struct *fsp)
                string_free(&fsp->fsp_name);
        
        file_free(fsp);
+
+       return 0;
+}
+
+/****************************************************************************
+ Close a file opened with null permissions in order to read permissions.
+****************************************************************************/
+
+static int close_statfile(files_struct *fsp, BOOL normal_close)
+{
+       close_filestruct(fsp);
+       
+       if (fsp->fsp_name)
+               string_free(&fsp->fsp_name);
+       
+       file_free(fsp);
+
+       return 0;
 }
 
+/****************************************************************************
+ Close a directory opened by an NT SMB call. 
+****************************************************************************/
+  
+int close_file(files_struct *fsp, BOOL normal_close)
+{
+       if(fsp->is_directory)
+               return close_directory(fsp, normal_close);
+       else if(fsp->stat_open)
+               return close_statfile(fsp, normal_close);
+       return close_normal_file(fsp, normal_close);
+}
index fcec05acce7ad7e56c43079dc821c4b1953de363..83289b218483c9fa8f1ad71890c7cefb088864d9 100644 (file)
@@ -110,16 +110,15 @@ connection_struct *conn_new(void)
 
        ZERO_STRUCTP(conn);
        conn->cnum = i;
-       conn->smbd_pid = getpid();
 
        bitmap_set(bmap, i);
 
        num_open++;
 
-       string_init(&conn->user,"");
-       string_init(&conn->dirpath,"");
-       string_init(&conn->connectpath,"");
-       string_init(&conn->origpath,"");
+       string_set(&conn->user,"");
+       string_set(&conn->dirpath,"");
+       string_set(&conn->connectpath,"");
+       string_set(&conn->origpath,"");
        
        DLIST_ADD(Connections, conn);
 
index fc025bc826a01403fe3196b1c74b8531b7331f07..f049b473046508706fa317fc9e53e5918ee7768e 100644 (file)
@@ -27,6 +27,11 @@ static TDB_CONTEXT *tdb;
 
 extern int DEBUGLEVEL;
 
+#ifdef WITH_UTMP
+static void utmp_yield(pid_t pid, const connection_struct *conn);
+static void utmp_claim(const struct connections_data *crec, const connection_struct *conn);
+#endif
+
 /****************************************************************************
 delete a connection record
 ****************************************************************************/
@@ -48,6 +53,12 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
        kbuf.dsize = sizeof(key);
 
        tdb_delete(tdb, kbuf);
+
+#ifdef WITH_UTMP
+       if(conn)
+               utmp_yield(key.pid, conn);
+#endif
+
        return(True);
 }
 
@@ -101,5 +112,259 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
 
        if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
 
+#ifdef WITH_UTMP
+       if (conn)
+           utmp_claim(&crec, conn);
+#endif
+
        return True;
 }
+
+#ifdef WITH_UTMP
+
+/****************************************************************************
+Reflect connection status in utmp/wtmp files.
+       T.D.Lee@durham.ac.uk  September 1999
+
+Hints for porting:
+       o Always attempt to use programmatic interface (pututline() etc.)
+       o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
+
+OS status:
+       Solaris 2.x:  Tested on 2.6 and 2.7; should be OK on other flavours.
+               T.D.Lee@durham.ac.uk
+       HPUX 9.x:  Not tested.  Appears not to have "x".
+       IRIX 6.5:  Not tested.  Appears to have "x".
+
+Notes:
+       The 4 byte 'ut_id' component is vital to distinguish connections,
+       of which there could be several hundered or even thousand.
+       Entries seem to be printable characters, with optional NULL pads.
+
+       We need to be distinct from other entries in utmp/wtmp.
+
+       Observed things: therefore avoid them.  Add to this list please.
+       From Solaris 2.x (because that's what I have):
+               'sN'    : run-levels; N: [0-9]
+               'co'    : console
+               'CC'    : arbitrary things;  C: [a-z]
+               'rXNN'  : rlogin;  N: [0-9]; X: [0-9a-z]
+               'tXNN'  : rlogin;  N: [0-9]; X: [0-9a-z]
+               '/NNN'  : Solaris CDE
+               'ftpZ'  : ftp (Z is the number 255, aka 0377, aka 0xff)
+       Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp",
+       but differences have been seen.
+
+       Arbitrarily I have chosen to use a distinctive 'SM' for the
+       first two bytes.
+
+       The remaining two encode the connection number used in samba locking
+       functions "claim_connection() and "yield_connection()".  This seems
+       to be a "nicely behaved" number: starting from 0 then working up
+       looking for an available slot.
+
+****************************************************************************/
+
+#include <utmp.h>
+
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+
+static const char *ut_id_encstr =
+       "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+static
+int
+ut_id_encode(int i, char *fourbyte)
+{
+       int nbase;
+
+       fourbyte[0] = 'S';
+       fourbyte[1] = 'M';
+
+/*
+ * Encode remaining 2 bytes from 'i'.
+ * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
+ * Example: digits would produce the base-10 numbers from '001'.
+ */
+       nbase = strlen(ut_id_encstr);
+
+       fourbyte[3] = ut_id_encstr[i % nbase];
+       i /= nbase;
+       fourbyte[2] = ut_id_encstr[i % nbase];
+       i /= nbase;
+
+       return(i);      /* 0: good; else overflow */
+}
+
+static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid, int i)
+{
+       struct timeval timeval;
+       int rc;
+
+       pstrcpy(u->ut_user, conn->user);
+       rc = ut_id_encode(i, u->ut_id);
+       slprintf(u->ut_line, 12, "smb/%d", i);
+
+       u->ut_pid = pid;
+
+       gettimeofday(&timeval, NULL);
+       u->ut_time = timeval.tv_sec;
+
+       return(rc);
+}
+
+/* Default path (if possible) */
+#ifdef HAVE_UTMPX_H
+
+# ifdef UTMPX_FILE
+static char *ut_pathname = UTMPX_FILE;
+# else
+static char *ut_pathname = "";
+# endif
+# ifdef WTMPX_FILE
+static char *wt_pathname = WTMPX_FILE;
+# else
+static char *wt_pathname = "";
+# endif
+
+#else  /* HAVE_UTMPX_H */
+
+# ifdef UTMP_FILE
+static char *ut_pathname = UTMP_FILE;
+# else
+static char *ut_pathname = "";
+# endif
+# ifdef WTMP_FILE
+static char *wt_pathname = WTMP_FILE;
+# else
+static char *wt_pathname = "";
+# endif
+
+#endif /* HAVE_UTMPX_H */
+
+static void uw_pathname(pstring fname, const char *uw_name)
+{
+       pstring dirname;
+
+       pstrcpy(dirname,lp_utmpdir());
+       trim_string(dirname,"","/");
+
+       /* Given directory: use it */
+       if (dirname != 0 && strlen(dirname) != 0) {
+               pstrcpy(fname, dirname);
+               pstrcat(fname, "/");
+               pstrcat(fname, uw_name);
+               return;
+       }
+
+       /* No given directory: attempt to use default paths */
+       if (uw_name[0] == 'u') {
+               pstrcpy(fname, ut_pathname);
+               return;
+       }
+
+       if (uw_name[0] == 'w') {
+               pstrcpy(fname, wt_pathname);
+               return;
+       }
+
+       pstrcpy(fname, "");
+}
+
+static void utmp_update(const struct utmp *u, const char *host)
+{
+       pstring fname;
+
+#ifdef HAVE_UTMPX_H
+       struct utmpx ux, *uxrc;
+
+       getutmpx(u, &ux);
+       if (host) {
+#if defined(HAVE_UX_UT_SYSLEN)
+               ux.ut_syslen = strlen(host);
+#endif /* defined(HAVE_UX_UT_SYSLEN) */
+               pstrcpy(ux.ut_host, host);
+       }
+
+       uw_pathname(fname, "utmpx");
+       DEBUG(2,("utmp_update: fname:%s\n", fname));
+       if (strlen(fname) != 0) {
+               utmpxname(fname);
+       }
+       uxrc = pututxline(&ux);
+       if (uxrc == NULL) {
+               DEBUG(2,("utmp_update: pututxline() failed\n"));
+               return;
+       }
+
+       uw_pathname(fname, "wtmpx");
+       DEBUG(2,("utmp_update: fname:%s\n", fname));
+       if (strlen(fname) != 0) {
+               updwtmpx(fname, &ux);
+       }
+#else
+       uw_pathname(fname, "utmp");
+       DEBUG(2,("utmp_update: fname:%s\n", fname));
+       if (strlen(fname) != 0) {
+               utmpname(fname);
+       }
+       pututline(u);
+
+       uw_pathname(fname, "wtmp");
+
+       /* *** Hmmm.  Appending wtmp (as distinct from overwriting utmp) has
+       me baffled.  How is it to be done? *** */
+#endif
+}
+
+static void utmp_yield(pid_t pid, const connection_struct *conn)
+{
+       struct utmp u;
+
+       if (! lp_utmp(SNUM(conn))) {
+               DEBUG(2,("utmp_yield: lp_utmp() NULL\n"));
+               return;
+       }
+
+       DEBUG(2,("utmp_yield: conn: user:%s cnum:%d i:%d\n",
+         conn->user, conn->cnum, i));
+
+       memset((char *)&u, '\0', sizeof(struct utmp));
+       u.ut_type = DEAD_PROCESS;
+       u.ut_exit.e_termination = 0;
+       u.ut_exit.e_exit = 0;
+       if (utmp_fill(&u, conn, pid, conn->cnum) == 0) {
+               utmp_update(&u, NULL);
+       }
+}
+
+static void utmp_claim(const struct connect_record *crec, const connection_struct *conn)
+{
+       struct utmp u;
+
+       if (conn == NULL) {
+               DEBUG(2,("utmp_claim: conn NULL\n"));
+               return;
+       }
+
+       if (! lp_utmp(SNUM(conn))) {
+               DEBUG(2,("utmp_claim: lp_utmp() NULL\n"));
+               return;
+       }
+
+       DEBUG(2,("utmp_claim: conn: user:%s cnum:%d i:%d\n",
+         conn->user, conn->cnum, i));
+       DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s\n",
+         crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_connection_name()));
+
+
+       memset((char *)&u, '\0', sizeof(struct utmp));
+       u.ut_type = USER_PROCESS;
+       if (utmp_fill(&u, conn, crec->pid, conn->cnum) == 0) {
+               utmp_update(&u, crec->machine);
+       }
+}
+
+#endif
index 8cba8d0644a81b7a76028a24c567ceb81200345c..0a892bad05e34118759b2c2a5eab6d4fc49fefc4 100644 (file)
@@ -27,7 +27,7 @@ extern int DEBUGLEVEL;
 /****************************************************************************
 normalise for DOS usage 
 ****************************************************************************/
-static void disk_norm(SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
 {
        /* check if the disk is beyond the max disk size */
        SMB_BIG_UINT maxdisksize = lp_maxdisksize();
@@ -39,18 +39,23 @@ static void disk_norm(SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsiz
                /* the -1 should stop applications getting div by 0
                   errors */
        }  
-       
+
        while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) {
                *dfree /= 2;
                *dsize /= 2;
                *bsize *= 2;
-               if (*bsize > WORDMAX) {
-                       *bsize = WORDMAX;
-                       if (*dsize > WORDMAX)
-                               *dsize = WORDMAX;
-                       if (*dfree >  WORDMAX)
-                               *dfree = WORDMAX;
-                       break;
+               if(small_query) {       
+                       /*
+                        * Force max to fit in 16 bit fields.
+                        */
+                       if (*bsize > (WORDMAX*512)) {
+                               *bsize = (WORDMAX*512);
+                               if (*dsize > WORDMAX)
+                                       *dsize = WORDMAX;
+                               if (*dfree >  WORDMAX)
+                                       *dfree = WORDMAX;
+                               break;
+                       }
                }
        }
 }
@@ -152,7 +157,7 @@ static int fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 
 #endif /* STAT_STATFS4 */
 
-#ifdef STAT_STATVFS            /* SVR4 */
+#if defined(STAT_STATVFS) || defined(STAT_STATVFS64)           /* SVR4 */
 # define CONVERT_BLOCKS(B) \
        adjust_blocks ((SMB_BIG_UINT)(B), fsd.f_frsize ? (SMB_BIG_UINT)fsd.f_frsize : (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
 
@@ -185,17 +190,68 @@ static int fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 /****************************************************************************
   return number of 1K blocks available on a path and total number 
 ****************************************************************************/
-static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+
+static SMB_BIG_UINT disk_free(char *path, BOOL small_query, 
+                              SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
 {
        int dfree_retval;
        SMB_BIG_UINT dfree_q = 0;
        SMB_BIG_UINT bsize_q = 0;
        SMB_BIG_UINT dsize_q = 0;
+       char *dfree_command;
 
        (*dfree) = (*dsize) = 0;
        (*bsize) = 512;
 
-       fsusage(path, dfree, dsize);
+
+       /*
+        * If external disk calculation specified, use it.
+        */
+
+       dfree_command = lp_dfree_command();
+       if (dfree_command && *dfree_command) {
+               pstring line;
+               char *p;
+               FILE *pp;
+
+               slprintf (line, sizeof(pstring) - 1, "%s %s", dfree_command, path);
+               DEBUG (3, ("disk_free: Running command %s\n", line));
+
+               pp = sys_popen(line, "r", False);
+               if (pp) {
+                       fgets(line, sizeof(pstring), pp);
+                       line[sizeof(pstring)-1] = '\0';
+                       if (strlen(line) > 0)
+                               line[strlen(line)-1] = '\0';
+
+                       DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
+
+                       *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10);
+                       while (p && *p & isspace(*p))
+                               p++;
+                       if (p && *p)
+                               *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10);
+                       while (p && *p & isspace(*p))
+                               p++;
+                       if (p && *p)
+                               *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10);
+                       else
+                               *bsize = 1024;
+                       sys_pclose (pp);
+                       DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n",
+                               (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize));
+
+                       if (!*dsize)
+                               *dsize = 2048;
+                       if (!*dfree)
+                               *dfree = 1024;
+               } else {
+                       DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n",
+                               line, strerror(errno) ));
+                       fsusage(path, dfree, dsize);
+               }
+       } else
+               fsusage(path, dfree, dsize);
 
        if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) {
                (*bsize) = bsize_q;
@@ -219,7 +275,7 @@ static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree
                *dfree = MAX(1,*dfree);
        }
 
-       disk_norm(bsize,dfree,dsize);
+       disk_norm(small_query,bsize,dfree,dsize);
 
        if ((*bsize) < 1024) {
                dfree_retval = (*dfree)/(1024/(*bsize));
@@ -234,7 +290,8 @@ static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree
 /****************************************************************************
 wrap it to get filenames right
 ****************************************************************************/
-SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query, 
+                           SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
 {
-       return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
+       return(disk_free(dos_to_unix(path,False),small_query, bsize,dfree,dsize));
 }
index b7c3177ce2cfd5214970ee4e5cc1807f6991a5c6..55d5bf132cf954b84f2ed3d00bbe70a334cc5362 100644 (file)
@@ -27,257 +27,378 @@ extern int DEBUGLEVEL;
    This module implements directory related functions for Samba.
 */
 
-
-
-static uint32 dircounter = 0;
-
-
-#define NUMDIRPTRS 256
-
-
-static struct dptr_struct {
-       int pid;
+typedef struct _dptr_struct {
+       struct _dptr_struct *next, *prev;
+       int dnum;
+       uint16 spid;
        connection_struct *conn;
-       uint32 lastused;
        void *ptr;
-       BOOL valid;
-       BOOL finished;
        BOOL expect_close;
        char *wcard; /* Field only used for trans2_ searches */
        uint16 attr; /* Field only used for trans2_ searches */
        char *path;
-}
-dirptrs[NUMDIRPTRS];
+} dptr_struct;
 
+static struct bitmap *dptr_bmap;
+static dptr_struct *dirptrs;
 
 static int dptrs_open = 0;
 
+#define INVALID_DPTR_KEY (-3)
+
 /****************************************************************************
-initialise the dir array
+ Initialise the dir bitmap.
 ****************************************************************************/
+
 void init_dptrs(void)
 {
   static BOOL dptrs_init=False;
-  int i;
 
-  if (dptrs_init) return;
-  for (i=0;i<NUMDIRPTRS;i++)    
-    {
-      dirptrs[i].valid = False;
-      dirptrs[i].wcard = NULL;
-      dirptrs[i].ptr = NULL;
-      string_init(&dirptrs[i].path,"");
-    }
+  if (dptrs_init)
+    return;
+
+  dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
+
+  if (!dptr_bmap)
+    exit_server("out of memory in init_dptrs\n");
+
   dptrs_init = True;
 }
 
 /****************************************************************************
-idle a dptr - the directory is closed but the control info is kept
+ Idle a dptr - the directory is closed but the control info is kept.
 ****************************************************************************/
-static void dptr_idle(int key)
+
+static void dptr_idle(dptr_struct *dptr)
 {
-  if (dirptrs[key].valid && dirptrs[key].ptr) {
-    DEBUG(4,("Idling dptr key %d\n",key));
+  if (dptr->ptr) {
+    DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
     dptrs_open--;
-    CloseDir(dirptrs[key].ptr);
-    dirptrs[key].ptr = NULL;
-  }    
+    CloseDir(dptr->ptr);
+    dptr->ptr = NULL;
+  }
 }
 
 /****************************************************************************
-idle the oldest dptr
+ Idle the oldest dptr.
 ****************************************************************************/
+
 static void dptr_idleoldest(void)
 {
-  int i;
-  uint32 old=dircounter+1;
-  int oldi= -1;
-  for (i=0;i<NUMDIRPTRS;i++)
-    if (dirptrs[i].valid && dirptrs[i].ptr && dirptrs[i].lastused < old) {
-      old = dirptrs[i].lastused;
-      oldi = i;
+  dptr_struct *dptr;
+
+  /*
+   * Go to the end of the list.
+   */
+  for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+    ;
+
+  if(!dptr) {
+    DEBUG(0,("No dptrs available to idle ?\n"));
+    return;
+  }
+
+  /*
+   * Idle the oldest pointer.
+   */
+
+  for(; dptr; dptr = dptr->prev) {
+    if (dptr->ptr) {
+      dptr_idle(dptr);
+      return;
     }
-  if (oldi != -1)
-    dptr_idle(oldi);
-  else
-    DEBUG(0,("No dptrs available to idle??\n"));
+  }
 }
 
 /****************************************************************************
-get the dir ptr for a dir index
+ Get the dptr_struct for a dir index.
 ****************************************************************************/
-static void *dptr_get(int key,uint32 lastused)
-{
-       struct dptr_struct *dp = &dirptrs[key];
-
-       if (dp->valid) {
-               if (lastused) dp->lastused = lastused;
-               if (!dp->ptr) {
-                       if (dptrs_open >= MAX_OPEN_DIRECTORIES)
-                               dptr_idleoldest();
-                       DEBUG(4,("Reopening dptr key %d\n",key));
-                       if ((dp->ptr = OpenDir(dp->conn, dp->path, True)))
-                               dptrs_open++;
-               }
-               return(dp->ptr);
-       }
-       return(NULL);
+
+static dptr_struct *dptr_get(int key, BOOL forclose)
+{
+  dptr_struct *dptr;
+
+  for(dptr = dirptrs; dptr; dptr = dptr->next) {
+    if(dptr->dnum == key) {
+      if (!forclose && !dptr->ptr) {
+        if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+          dptr_idleoldest();
+        DEBUG(4,("Reopening dptr key %d\n",key));
+        if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
+          dptrs_open++;
+      }
+      DLIST_PROMOTE(dirptrs,dptr);
+      return dptr;
+    }
+  }
+  return(NULL);
+}
+
+/****************************************************************************
+ Get the dptr ptr for a dir index.
+****************************************************************************/
+
+static void *dptr_ptr(int key)
+{
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr)
+    return(dptr->ptr);
+  return(NULL);
 }
 
 /****************************************************************************
-get the dir path for a dir index
+ Get the dir path for a dir index.
 ****************************************************************************/
+
 char *dptr_path(int key)
 {
-  if (dirptrs[key].valid)
-    return(dirptrs[key].path);
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr)
+    return(dptr->path);
   return(NULL);
 }
 
 /****************************************************************************
-get the dir wcard for a dir index (lanman2 specific)
+ Get the dir wcard for a dir index (lanman2 specific).
 ****************************************************************************/
+
 char *dptr_wcard(int key)
 {
-  if (dirptrs[key].valid)
-    return(dirptrs[key].wcard);
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr)
+    return(dptr->wcard);
   return(NULL);
 }
 
 /****************************************************************************
-set the dir wcard for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
+ Set the dir wcard for a dir index (lanman2 specific).
+ Returns 0 on ok, 1 on fail.
 ****************************************************************************/
+
 BOOL dptr_set_wcard(int key, char *wcard)
 {
-  if (dirptrs[key].valid) {
-    dirptrs[key].wcard = wcard;
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr) {
+    dptr->wcard = wcard;
     return True;
   }
   return False;
 }
 
 /****************************************************************************
-set the dir attrib for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
+ Set the dir attrib for a dir index (lanman2 specific).
+ Returns 0 on ok, 1 on fail.
 ****************************************************************************/
+
 BOOL dptr_set_attr(int key, uint16 attr)
 {
-  if (dirptrs[key].valid) {
-    dirptrs[key].attr = attr;
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr) {
+    dptr->attr = attr;
     return True;
   }
   return False;
 }
 
 /****************************************************************************
-get the dir attrib for a dir index (lanman2 specific)
+ Get the dir attrib for a dir index (lanman2 specific)
 ****************************************************************************/
+
 uint16 dptr_attr(int key)
 {
-  if (dirptrs[key].valid)
-    return(dirptrs[key].attr);
+  dptr_struct *dptr = dptr_get(key, False);
+
+  if (dptr)
+    return(dptr->attr);
   return(0);
 }
 
 /****************************************************************************
-close a dptr
+ Close a dptr (internal func).
+****************************************************************************/
+
+static void dptr_close_internal(dptr_struct *dptr)
+{
+  DEBUG(4,("closing dptr key %d\n",dptr->dnum));
+
+  DLIST_REMOVE(dirptrs, dptr);
+
+  /* 
+   * Free the dnum in the bitmap. Remember the dnum value is always 
+   * biased by one with respect to the bitmap.
+   */
+
+  if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
+    DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
+                       dptr->dnum ));
+  }
+
+  bitmap_clear(dptr_bmap, dptr->dnum - 1);
+
+  if (dptr->ptr) {
+    CloseDir(dptr->ptr);
+    dptrs_open--;
+  }
+
+  /* Lanman 2 specific code */
+  if (dptr->wcard)
+    free(dptr->wcard);
+  string_set(&dptr->path,"");
+  free((char *)dptr);
+}
+
+/****************************************************************************
+ Close a dptr given a key.
 ****************************************************************************/
-void dptr_close(int key)
+
+void dptr_close(int *key)
 {
+  dptr_struct *dptr;
+
+  if(*key == INVALID_DPTR_KEY)
+    return;
+
   /* OS/2 seems to use -1 to indicate "close all directories" */
-  if (key == -1) {
-    int i;
-    for (i=0;i<NUMDIRPTRS;i++) 
-      dptr_close(i);
+  if (*key == -1) {
+    dptr_struct *next;
+    for(dptr = dirptrs; dptr; dptr = next) {
+      next = dptr->next;
+      dptr_close_internal(dptr);
+    }
+    *key = INVALID_DPTR_KEY;
     return;
   }
 
-  if (key < 0 || key >= NUMDIRPTRS) {
-    DEBUG(3,("Invalid key %d given to dptr_close\n",key));
+  dptr = dptr_get(*key, True);
+
+  if (!dptr) {
+    DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
     return;
   }
 
-  if (dirptrs[key].valid) {
-    DEBUG(4,("closing dptr key %d\n",key));
-    if (dirptrs[key].ptr) {
-      CloseDir(dirptrs[key].ptr);
-      dptrs_open--;
-    }
-    /* Lanman 2 specific code */
-    if (dirptrs[key].wcard)
-      free(dirptrs[key].wcard);
-    dirptrs[key].valid = False;
-    string_set(&dirptrs[key].path,"");
-  }
+  dptr_close_internal(dptr);
+
+  *key = INVALID_DPTR_KEY;
 }
 
 /****************************************************************************
-close all dptrs for a cnum
+ Close all dptrs for a cnum.
 ****************************************************************************/
+
 void dptr_closecnum(connection_struct *conn)
 {
-  int i;
-  for (i=0;i<NUMDIRPTRS;i++)
-    if (dirptrs[i].valid && dirptrs[i].conn == conn)
-      dptr_close(i);
+  dptr_struct *dptr, *next;
+  for(dptr = dirptrs; dptr; dptr = next) {
+    next = dptr->next;
+    if (dptr->conn == conn)
+      dptr_close_internal(dptr);
+  }
 }
 
 /****************************************************************************
-idle all dptrs for a cnum
+ Idle all dptrs for a cnum.
 ****************************************************************************/
+
 void dptr_idlecnum(connection_struct *conn)
 {
-  int i;
-  for (i=0;i<NUMDIRPTRS;i++)
-    if (dirptrs[i].valid && dirptrs[i].conn == conn && dirptrs[i].ptr)
-      dptr_idle(i);
+  dptr_struct *dptr;
+  for(dptr = dirptrs; dptr; dptr = dptr->next) {
+    if (dptr->conn == conn && dptr->ptr)
+      dptr_idle(dptr);
+  }
 }
 
 /****************************************************************************
-close a dptr that matches a given path, only if it matches the pid also
+ Close a dptr that matches a given path, only if it matches the spid also.
 ****************************************************************************/
-void dptr_closepath(char *path,int pid)
+
+void dptr_closepath(char *path,uint16 spid)
 {
-  int i;
-  for (i=0;i<NUMDIRPTRS;i++)
-    if (dirptrs[i].valid && pid == dirptrs[i].pid &&
-       strequal(dirptrs[i].path,path))
-      dptr_close(i);
+  dptr_struct *dptr, *next;
+  for(dptr = dirptrs; dptr; dptr = next) {
+    next = dptr->next;
+    if (spid == dptr->spid && strequal(dptr->path,path))
+      dptr_close_internal(dptr);
+  }
 }
 
 /****************************************************************************
-  start a directory listing
+ Start a directory listing.
 ****************************************************************************/
+
 static BOOL start_dir(connection_struct *conn,char *directory)
 {
-       DEBUG(5,("start_dir dir=%s\n",directory));
+  DEBUG(5,("start_dir dir=%s\n",directory));
 
-       if (!check_name(directory,conn))
-               return(False);
+  if (!check_name(directory,conn))
+    return(False);
   
-       if (! *directory)
-               directory = ".";
-
-       conn->dirptr = OpenDir(conn, directory, True);
-       if (conn->dirptr) {    
-               dptrs_open++;
-               string_set(&conn->dirpath,directory);
-               return(True);
-       }
+  if (! *directory)
+    directory = ".";
+
+  conn->dirptr = OpenDir(conn, directory, True);
+  if (conn->dirptr) {    
+    dptrs_open++;
+    string_set(&conn->dirpath,directory);
+    return(True);
+  }
   
-       return(False);
+  return(False);
 }
 
+/****************************************************************************
+ Try and close the oldest handle not marked for
+ expect close in the hope that the client has
+ finished with that one.
+****************************************************************************/
+
+static void dptr_close_oldest(BOOL old)
+{
+  dptr_struct *dptr;
+
+  /*
+   * Go to the end of the list.
+   */
+  for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+    ;
+
+  if(!dptr) {
+    DEBUG(0,("No old dptrs available to close oldest ?\n"));
+    return;
+  }
+
+  /*
+   * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
+   * does not have expect_close set. If 'old' is false, close
+   * one of the new dnum handles.
+   */
+
+  for(; dptr; dptr = dptr->prev) {
+    if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
+        (!old && (dptr->dnum > 255))) {
+      dptr_close_internal(dptr);
+      return;
+    }
+  }
+}
 
 /****************************************************************************
-create a new dir ptr
+ Create a new dir ptr. If the flag old_handle is true then we must allocate
+ from the bitmap range 0 - 255 as old SMBsearch directory handles are only
+ one byte long. If old_handle is false we allocate from the range
+ 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
+ a directory handle is never zero. All the above is folklore taught to
+ me at Andrew's knee.... :-) :-). JRA.
 ****************************************************************************/
-int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid)
+
+int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid)
 {
-  int i;
-  uint32 old;
-  int oldi;
+  dptr_struct *dptr;
 
   if (!start_dir(conn,path))
     return(-2); /* Code to say use a unix error return code. */
@@ -285,70 +406,101 @@ int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid)
   if (dptrs_open >= MAX_OPEN_DIRECTORIES)
     dptr_idleoldest();
 
-  for (i=0;i<NUMDIRPTRS;i++)
-    if (!dirptrs[i].valid)
-      break;
-  if (i == NUMDIRPTRS) i = -1;
+  dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
+  if(!dptr) {
+    DEBUG(0,("malloc fail in dptr_create.\n"));
+    return -1;
+  }
+
+  ZERO_STRUCTP(dptr);
+
+  if(old_handle) {
+
+    /*
+     * This is an old-style SMBsearch request. Ensure the
+     * value we return will fit in the range 1-255.
+     */
 
+    dptr->dnum = bitmap_find(dptr_bmap, 0);
 
-  /* as a 2nd option, grab the oldest not marked for expect_close */
-  if (i == -1) {
-    old=dircounter+1;
-    oldi= -1;
-    for (i=0;i<NUMDIRPTRS;i++)
-      if (!dirptrs[i].expect_close && dirptrs[i].lastused < old) {
-       old = dirptrs[i].lastused;
-       oldi = i;
+    if(dptr->dnum == -1 || dptr->dnum > 254) {
+
+      /*
+       * Try and close the oldest handle not marked for
+       * expect close in the hope that the client has
+       * finished with that one.
+       */
+
+      dptr_close_oldest(True);
+
+      /* Now try again... */
+      dptr->dnum = bitmap_find(dptr_bmap, 0);
+
+      if(dptr->dnum == -1 || dptr->dnum > 254) {
+        DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
+        free((char *)dptr);
+        return -1;
       }
-    i = oldi;
-  }
+    }
+  } else {
+
+    /*
+     * This is a new-style trans2 request. Allocate from
+     * a range that will return 256 - MAX_DIRECTORY_HANDLES.
+     */
+
+    dptr->dnum = bitmap_find(dptr_bmap, 255);
+
+    if(dptr->dnum == -1 || dptr->dnum < 255) {
+
+      /*
+       * Try and close the oldest handle close in the hope that
+       * the client has finished with that one. This will only
+       * happen in the case of the Win98 client bug where it leaks
+       * directory handles.
+       */
+
+      dptr_close_oldest(False);
 
-  /* a 3rd option - grab the oldest one */
-  if (i == -1) {
-    old=dircounter+1;
-    oldi= -1;
-    for (i=0;i<NUMDIRPTRS;i++)
-      if (dirptrs[i].lastused < old) {
-       old = dirptrs[i].lastused;
-       oldi = i;
+      /* Now try again... */
+      dptr->dnum = bitmap_find(dptr_bmap, 255);
+
+      if(dptr->dnum == -1 || dptr->dnum < 255) {
+        DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
+        free((char *)dptr);
+        return -1;
       }
-    i = oldi;
+    }
   }
 
-  if (i == -1) {
-    DEBUG(0,("Error - all dirptrs in use??\n"));
-    return(-1);
-  }
+  bitmap_set(dptr_bmap, dptr->dnum);
 
-  if (dirptrs[i].valid)
-    dptr_close(i);
+  dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
 
-  dirptrs[i].ptr = conn->dirptr;
-  string_set(&dirptrs[i].path,path);
-  dirptrs[i].lastused = dircounter++;
-  dirptrs[i].finished = False;
-  dirptrs[i].conn = conn;
-  dirptrs[i].pid = pid;
-  dirptrs[i].expect_close = expect_close;
-  dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */
-  dirptrs[i].attr = 0; /* Only used in lanman2 searches */
-  dirptrs[i].valid = True;
+  dptr->ptr = conn->dirptr;
+  string_set(&dptr->path,path);
+  dptr->conn = conn;
+  dptr->spid = spid;
+  dptr->expect_close = expect_close;
+  dptr->wcard = NULL; /* Only used in lanman2 searches */
+  dptr->attr = 0; /* Only used in lanman2 searches */
+
+  DLIST_ADD(dirptrs, dptr);
 
   DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
-          i,path,expect_close));  
+          dptr->dnum,path,expect_close));  
 
-  return(i);
+  return(dptr->dnum);
 }
 
-#define DPTR_MASK ((uint32)(((uint32)1)<<31))
-
 /****************************************************************************
-fill the 5 byte server reserved dptr field
+ Fill the 5 byte server reserved dptr field.
 ****************************************************************************/
+
 BOOL dptr_fill(char *buf1,unsigned int key)
 {
   unsigned char *buf = (unsigned char *)buf1;
-  void *p = dptr_get(key,0);
+  void *p = dptr_ptr(key);
   uint32 offset;
   if (!p) {
     DEBUG(1,("filling null dirptr %d\n",key));
@@ -362,22 +514,14 @@ BOOL dptr_fill(char *buf1,unsigned int key)
   return(True);
 }
 
-
 /****************************************************************************
-return True is the offset is at zero
+ Fetch the dir ptr and seek it given the 5 byte server field.
 ****************************************************************************/
-BOOL dptr_zero(char *buf)
-{
-  return((IVAL(buf,1)&~DPTR_MASK) == 0);
-}
 
-/****************************************************************************
-fetch the dir ptr and seek it given the 5 byte server field
-****************************************************************************/
 void *dptr_fetch(char *buf,int *num)
 {
   unsigned int key = *(unsigned char *)buf;
-  void *p = dptr_get(key,dircounter++);
+  void *p = dptr_ptr(key);
   uint32 offset;
   if (!p) {
     DEBUG(3,("fetched null dirptr %d\n",key));
@@ -392,11 +536,12 @@ void *dptr_fetch(char *buf,int *num)
 }
 
 /****************************************************************************
-fetch the dir ptr.
+ Fetch the dir ptr.
 ****************************************************************************/
+
 void *dptr_fetch_lanman2(int dptr_num)
 {
-  void *p = dptr_get(dptr_num,dircounter++);
+  void *p = dptr_ptr(dptr_num);
 
   if (!p) {
     DEBUG(3,("fetched null dirptr %d\n",dptr_num));
@@ -407,8 +552,9 @@ void *dptr_fetch_lanman2(int dptr_num)
 }
 
 /****************************************************************************
-check a filetype for being valid
+ Check a filetype for being valid.
 ****************************************************************************/
+
 BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
 {
   if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
@@ -417,8 +563,9 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
 }
 
 /****************************************************************************
-  get a directory entry
+ Get an 8.3 directory entry.
 ****************************************************************************/
+
 BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
                    SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
 {
@@ -437,64 +584,68 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
               strequal(conn->dirpath,".") ||
               strequal(conn->dirpath,"/"));
   
-  needslash = 
-        ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+  needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
 
   if (!conn->dirptr)
     return(False);
   
   while (!found)
-    {
-      dname = ReadDirName(conn->dirptr);
+  {
+    BOOL filename_is_mask = False;
+    dname = ReadDirName(conn->dirptr);
 
-      DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
-              (long)conn->dirptr,TellDir(conn->dirptr)));
+    DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+          (long)conn->dirptr,TellDir(conn->dirptr)));
       
-      if (dname == NULL) 
-       return(False);
+    if (dname == NULL) 
+      return(False);
       
-      pstrcpy(filename,dname);      
-
-      if ((strcmp(filename,mask) == 0) ||
-         (name_map_mangle(filename,True,SNUM(conn)) &&
-          mask_match(filename,mask,False,False)))
-       {
-         if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
-           continue;
-
-         pstrcpy(fname,filename);
-         *path = 0;
-         pstrcpy(path,conn->dirpath);
-          if(needslash)
-           pstrcat(path,"/");
-         pstrcpy(pathreal,path);
-         pstrcat(path,fname);
-         pstrcat(pathreal,dname);
-         if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0) 
-           {
-             DEBUG(5,("Couldn't stat 1 [%s]\n",path));
-             continue;
-           }
-
-         if (check_descend &&
-             !strequal(fname,".") && !strequal(fname,".."))
-           continue;
+    pstrcpy(filename,dname);      
+
+    if ((filename_is_mask = (strcmp(filename,mask) == 0)) ||
+        (name_map_mangle(filename,True,False,SNUM(conn)) &&
+         mask_match(filename,mask,False,False)))
+    {
+      if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+        continue;
+
+      pstrcpy(fname,filename);
+      *path = 0;
+      pstrcpy(path,conn->dirpath);
+      if(needslash)
+        pstrcat(path,"/");
+      pstrcpy(pathreal,path);
+      pstrcat(path,fname);
+      pstrcat(pathreal,dname);
+      if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
+      {
+        DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+        continue;
+      }
          
-         *mode = dos_mode(conn,pathreal,&sbuf);
+      *mode = dos_mode(conn,pathreal,&sbuf);
 
-         if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
-           DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
-           continue;
-         }
+      if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) 
+      {
+        DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+        continue;
+      }
 
-         *size = sbuf.st_size;
-         *date = sbuf.st_mtime;
+      if (!filename_is_mask)
+      {
+        /* Now we can allow the mangled cache to be updated */
+        pstrcpy(filename,dname);
+        name_map_mangle(filename,True,True,SNUM(conn));
+      }
 
-         DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
+      *size = sbuf.st_size;
+      *date = sbuf.st_mtime;
+
+      DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
          
-         found = True;
-       }
+      found = True;
     }
+  }
 
   return(found);
 }
@@ -512,8 +663,9 @@ typedef struct
 
 
 /*******************************************************************
-open a directory
+ Open a directory.
 ********************************************************************/
+
 void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
 {
   Dir *dirp;
@@ -532,13 +684,15 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
 
   while ((n = vfs_readdirname(conn, p)))
   {
-    int l = strlen(n)+1;
-    pstring zn;
+    int l;
+
+    l = strlen(n)+1;
 
-    pstrcpy(zn, unix_to_dos(n, True));
+    /* Return value of vfs_readdirname has already gone through 
+       unix_to_dos() */
 
     /* If it's a vetoed file, pretend it doesn't even exist */
-    if (use_veto && conn && IS_VETO_PATH(conn, zn)) continue;
+    if (use_veto && conn && IS_VETO_PATH(conn, n)) continue;
 
     if (used + l > dirp->mallocsize) {
       int s = MAX(used+l,used+2000);
@@ -552,7 +706,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
       dirp->mallocsize = s;
       dirp->current = dirp->data;
     }
-    pstrcpy(dirp->data+used,zn);
+    pstrcpy(dirp->data+used,n);
     used += l;
     dirp->numentries++;
   }
@@ -563,8 +717,9 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
 
 
 /*******************************************************************
-close a directory
+ Close a directory.
 ********************************************************************/
+
 void CloseDir(void *p)
 {
   Dir *dirp = (Dir *)p;
@@ -574,8 +729,9 @@ void CloseDir(void *p)
 }
 
 /*******************************************************************
-read from a directory
+ Read from a directory.
 ********************************************************************/
+
 char *ReadDirName(void *p)
 {
   char *ret;
@@ -592,8 +748,9 @@ char *ReadDirName(void *p)
 
 
 /*******************************************************************
-seek a dir
+ Seek a dir.
 ********************************************************************/
+
 BOOL SeekDir(void *p,int pos)
 {
   Dir *dirp = (Dir *)p;
@@ -611,8 +768,9 @@ BOOL SeekDir(void *p,int pos)
 }
 
 /*******************************************************************
-tell a dir position
+ Tell a dir position.
 ********************************************************************/
+
 int TellDir(void *p)
 {
   Dir *dirp = (Dir *)p;
@@ -622,38 +780,32 @@ int TellDir(void *p)
   return(dirp->pos);
 }
 
+/*******************************************************************************
+ This section manages a global directory cache.
+ (It should probably be split into a separate module.  crh)
+********************************************************************************/
 
-/* -------------------------------------------------------------------------- **
- * This section manages a global directory cache.
- * (It should probably be split into a separate module.  crh)
- * -------------------------------------------------------------------------- **
- */
-
-typedef struct
-  {
+typedef struct {
   ubi_dlNode  node;
   char       *path;
   char       *name;
   char       *dname;
   int         snum;
-  } dir_cache_entry;
+} dir_cache_entry;
 
 static ubi_dlNewList( dir_cache );
 
+/*****************************************************************************
+ Add an entry to the directory cache.
+ Input:  path  -
+         name  -
+         dname -
+         snum  -
+ Output: None.
+*****************************************************************************/
+
 void DirCacheAdd( char *path, char *name, char *dname, int snum )
-  /* ------------------------------------------------------------------------ **
-   * Add an entry to the directory cache.
-   *
-   *  Input:  path  -
-   *          name  -
-   *          dname -
-   *          snum  -
-   *
-   *  Output: None.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
+{
   int               pathlen;
   int               namelen;
   dir_cache_entry  *entry;
@@ -684,27 +836,23 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum )
   while( DIRCACHESIZE < dir_cache->count )
     free( ubi_dlRemTail( dir_cache ) );
 
-  } /* DirCacheAdd */
+}
+
+/*****************************************************************************
+ Search for an entry to the directory cache.
+ Input:  path  -
+         name  -
+         snum  -
+ Output: The dname string of the located entry, or NULL if the entry was
+         not found.
 
+ Notes:  This uses a linear search, which is is okay because of
+         the small size of the cache.  Use a splay tree or hash
+         for large caches.
+*****************************************************************************/
 
 char *DirCacheCheck( char *path, char *name, int snum )
-  /* ------------------------------------------------------------------------ **
-   * Search for an entry to the directory cache.
-   *
-   *  Input:  path  -
-   *          name  -
-   *          snum  -
-   *
-   *  Output: The dname string of the located entry, or NULL if the entry was
-   *          not found.
-   *
-   *  Notes:  This uses a linear search, which is is okay because of
-   *          the small size of the cache.  Use a splay tree or hash
-   *          for large caches.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
+{
   dir_cache_entry *entry;
 
   for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
@@ -721,18 +869,15 @@ char *DirCacheCheck( char *path, char *name, int snum )
     }
 
   return(NULL);
-  } /* DirCacheCheck */
+}
+
+/*****************************************************************************
+ Remove all cache entries which have an snum that matches the input.
+ Input:  snum  -
+ Output: None.
+*****************************************************************************/
 
 void DirCacheFlush(int snum)
-  /* ------------------------------------------------------------------------ **
-   * Remove all cache entries which have an snum that matches the input.
-   *
-   *  Input:  snum  -
-   *
-   *  Output: None.
-   *
-   * ------------------------------------------------------------------------ **
-   */
 {
        dir_cache_entry *entry;
        ubi_dlNodePtr    next;
@@ -744,11 +889,4 @@ void DirCacheFlush(int snum)
                        free( ubi_dlRemThis( dir_cache, entry ) );
                entry = (dir_cache_entry *)next;
        }
-} /* DirCacheFlush */
-
-/* -------------------------------------------------------------------------- **
- * End of the section that manages the global directory cache.
- * -------------------------------------------------------------------------- **
- */
-
-
+}
index 2923959b0382720d5b14a9cbe03d81e8f2c43a33..278a4ab5e3dcbaeadc0a9b50a0d58ce9093b05eb 100644 (file)
@@ -26,33 +26,68 @@ extern int DEBUGLEVEL;
 /****************************************************************************
   change a dos mode to a unix mode
     base permission for files:
-         everybody gets read bit set
+         if inheriting
+           apply read/write bits from parent directory.
+         else   
+           everybody gets read bit set
          dos readonly is represented in unix by removing everyone's write bit
          dos archive is represented in unix by the user's execute bit
          dos system is represented in unix by the group's execute bit
          dos hidden is represented in unix by the other's execute bit
-         Then apply create mask,
-         then add force bits.
+         if !inheriting {
+           Then apply create mask,
+           then add force bits.
+         }
     base permission for directories:
          dos directory is represented in unix by unix's dir bit and the exec bit
-         Then apply create mask,
-         then add force bits.
+         if !inheriting {
+           Then apply create mask,
+           then add force bits.
+         }
 ****************************************************************************/
-mode_t unix_mode(connection_struct *conn,int dosmode)
+mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
 {
   mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
+  mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
 
   if ( !IS_DOS_READONLY(dosmode) )
     result |= (S_IWUSR | S_IWGRP | S_IWOTH);
+
+  if (fname && lp_inherit_perms(SNUM(conn))) {
+    char *dname;
+    SMB_STRUCT_STAT sbuf;
+
+    dname = parent_dirname(fname);
+    DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
+    if (dos_stat(dname,&sbuf) != 0) {
+      DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
+      return(0);      /* *** shouldn't happen! *** */
+    }
+
+    /* Save for later - but explicitly remove setuid bit for safety. */
+    dir_mode = sbuf.st_mode & ~S_ISUID;
+    DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
+    /* Clear "result" */
+    result = 0;
+  } 
+
   if (IS_DOS_DIR(dosmode)) {
     /* We never make directories read only for the owner as under DOS a user
        can always create a file in a read-only directory. */
-    result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
-    /* Apply directory mask */
-    result &= lp_dir_mode(SNUM(conn));
-    /* Add in force bits */
-    result |= lp_force_dir_mode(SNUM(conn));
+    result |= (S_IFDIR | S_IWUSR);
+
+    if (dir_mode) {
+      /* Inherit mode of parent directory. */
+      result |= dir_mode;
+    } else {
+      /* Provisionally add all 'x' bits */
+      result |= (S_IXUSR | S_IXGRP | S_IXOTH);                 
+
+      /* Apply directory mask */
+      result &= lp_dir_mask(SNUM(conn));
+      /* Add in force bits */
+      result |= lp_force_dir_mode(SNUM(conn));
+    }
   } else { 
     if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
       result |= S_IXUSR;
@@ -62,11 +97,17 @@ mode_t unix_mode(connection_struct *conn,int dosmode)
  
     if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
       result |= S_IXOTH;  
-    /* Apply mode mask */
-    result &= lp_create_mode(SNUM(conn));
-    /* Add in force bits */
-    result |= lp_force_create_mode(SNUM(conn));
+
+    if (dir_mode) {
+      /* Inherit 666 component of parent directory mode */
+      result |= dir_mode
+        &  (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
+    } else {
+      /* Apply mode mask */
+      result &= lp_create_mask(SNUM(conn));
+      /* Add in force bits */
+      result |= lp_force_create_mode(SNUM(conn));
+    }
   }
   return(result);
 }
@@ -155,7 +196,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
 
   if (dos_mode(conn,fname,st) == dosmode) return(0);
 
-  unixmode = unix_mode(conn,dosmode);
+  unixmode = unix_mode(conn,dosmode,fname);
 
   /* preserve the s bits */
   mask |= (S_ISUID | S_ISGID);
@@ -179,11 +220,9 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
   }
 
   /* if we previously had any w bits set then leave them alone 
-   if the new mode is not rdonly */
-  if (!IS_DOS_READONLY(dosmode) &&
-      (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
-    unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
-    unixmode |= tmp;
+   whilst adding in the new w bits, if the new mode is not rdonly */
+  if (!IS_DOS_READONLY(dosmode)) {
+    unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
   }
 
   return(conn->vfs_ops.chmod(dos_to_unix(fname,False),unixmode));
@@ -251,9 +290,8 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
 
   if (file_utime(conn, fname, &times)) {
     DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
+    return False;
   }
   
   return(True);
 } 
-
-
index 1e166275152869a4e2f27d93989c1c153cb1a4b4..7a96e6e598cd02beecea3438b2c02b4e20da9c91 100644 (file)
@@ -23,6 +23,7 @@
 
 extern int DEBUGLEVEL;
 
+static BOOL setup_write_cache(files_struct *, SMB_OFF_T);
 
 /****************************************************************************
 seek a file. Try to avoid the seek if possible
@@ -38,6 +39,18 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
 
   seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET);
 
+  /*
+   * We want to maintain the fiction that we can seek
+   * on a fifo for file system purposes. This allows 
+   * people to set up UNIX fifo's that feed data to Windows
+   * applications. JRA.
+   */
+
+  if((seek_ret == -1) && (errno == ESPIPE)) {
+    seek_ret = pos+offset;
+    errno = 0;
+  }
+
   if((seek_ret == -1) || (seek_ret != pos+offset)) {
     DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) ));
     fsp->pos = -1;
@@ -52,6 +65,29 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
   return(fsp->pos);
 }
 
+/****************************************************************************
+ Read from write cache if we can.
+****************************************************************************/
+
+static unsigned int cache_read_hits;
+
+BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
+{
+  write_cache *wcp = fsp->wcp;
+
+  if(!wcp)
+    return False;
+
+  if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size)
+    return False;
+
+  memcpy(data, wcp->data + (pos - wcp->offset), n);
+
+  cache_read_hits++;
+
+  return True;
+}
+
 /****************************************************************************
 read from a file
 ****************************************************************************/
@@ -62,7 +98,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
 
 #if USE_READ_PREDICTION
   if (!fsp->can_write) {
-    ret = read_predict(fsp, fsp->fd_ptr->fd,pos,data,NULL,n);
+    ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
 
     data += ret;
     n -= ret;
@@ -70,25 +106,19 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
   }
 #endif
 
-#if WITH_MMAP
-  if (fsp->mmap_ptr) {
-         SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : 0;
-         num = MIN(n,num);
-         if (num > 0) {
-                 memcpy(data,fsp->mmap_ptr+pos,num);
-                 data += num;
-                 pos += num;
-                 n -= num;
-                 ret += num;
-         }
-  }
-#endif
+  /*
+   * Serve from write cache if we can.
+   */
+  if(read_from_write_cache(fsp, data, pos, n))
+    return n;
+
+  flush_write_cache(fsp, READ_FLUSH);
 
   if (seek_file(fsp,pos) == -1) {
     DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
     return(ret);
   }
-
+  
   if (n > 0) {
     readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n);
     if (readret > 0) ret += readret;
@@ -97,13 +127,43 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
   return(ret);
 }
 
+/* Write cache static counters. */
+
+static unsigned int abutted_writes;
+static unsigned int total_writes;
+static unsigned int non_oplock_writes;
+static unsigned int direct_writes;
+static unsigned int init_writes;
+static unsigned int flushed_writes;
+static unsigned int num_perfect_writes;
+static unsigned int flush_reasons[NUM_FLUSH_REASONS];
+
+/* how many write cache buffers have been allocated */
+static unsigned int allocated_write_caches;
+static unsigned int num_write_caches;
+
+/****************************************************************************
+ *Really* write to a file
+****************************************************************************/
+
+static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n)
+{
+  if ((pos != -1) && (seek_file(fsp,pos) == -1))
+    return -1;
+
+  return write_data(fsp->fd_ptr->fd,data,n);
+}
 
 /****************************************************************************
 write to a file
 ****************************************************************************/
 
-ssize_t write_file(files_struct *fsp,char *data,size_t n)
+ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
 {
+  write_cache *wcp = fsp->wcp;
+  ssize_t total_written = 0;
+  int write_path = -1; 
+
   if (!fsp->can_write) {
     errno = EPERM;
     return(0);
@@ -112,25 +172,489 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n)
   if (!fsp->modified) {
     SMB_STRUCT_STAT st;
     fsp->modified = True;
+
     if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) {
       int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
       if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {        
         file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
       }
+
+      /*
+       * If this is the first write and we have an exclusive oplock then setup
+       * the write cache.
+       */
+
+      if ((fsp->oplock_type == EXCLUSIVE_OPLOCK) && !wcp) {
+        setup_write_cache(fsp, st.st_size);
+        wcp = fsp->wcp;
+      } 
     }  
   }
 
-  return(vfs_write_data(fsp,data,n));
+  total_writes++;
+  if (!fsp->oplock_type) {
+    non_oplock_writes++;
+  }
+
+  /*
+   * If this file is level II oplocked then we need
+   * to grab the shared memory lock and inform all
+   * other files with a level II lock that they need
+   * to flush their read caches. We keep the lock over
+   * the shared memory area whilst doing this.
+   */
+
+  if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+    SMB_DEV_T dev = fsp->fd_ptr->dev;
+    SMB_INO_T inode = fsp->fd_ptr->inode;
+    share_mode_entry *share_list = NULL;
+    pid_t pid = getpid();
+    int token = -1;
+    int num_share_modes = 0;
+    int i;
+
+    if (lock_share_entry(fsp->conn, dev, inode) == False) {
+      DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
+    }
+
+    num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list);
+
+    for(i = 0; i < num_share_modes; i++) {
+      share_mode_entry *share_entry = &share_list[i];
+
+      /*
+       * As there could have been multiple writes waiting at the lock_share_entry
+       * gate we may not be the first to enter. Hence the state of the op_types
+       * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II
+       * oplock. It will do no harm to re-send break messages to those smbd's
+       * that are still waiting their turn to remove their LEVEL_II state, and
+       * also no harm to ignore existing NO_OPLOCK states. JRA.
+       */
+
+      if (share_entry->op_type == NO_OPLOCK)
+        continue;
+
+      /* Paranoia .... */
+      if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
+        DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i ));
+        abort();
+      }
+
+      /*
+       * Check if this is a file we have open (including the
+       * file we've been called to do write_file on. If so
+       * then break it directly without releasing the lock.
+       */
+
+      if (pid == share_entry->pid) {
+        files_struct *new_fsp = file_find_dit(dev, inode, &share_entry->time);
+
+        /* Paranoia check... */
+        if(new_fsp == NULL) {
+          DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i ));
+          abort();
+        }
+        oplock_break_level2(new_fsp, True, token);
+
+      } else {
+
+        /*
+         * This is a remote file and so we send an asynchronous
+         * message.
+         */
+
+        request_oplock_break(share_entry, dev, inode);
+      }
+    }
+    free((char *)share_list);
+    unlock_share_entry(fsp->conn, dev, inode);
+  }
+
+  /* Paranoia check... */
+  if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+    DEBUG(0,("write_file: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
+    abort();
+  }
+
+  if (total_writes % 500 == 0) {
+    DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u flushes=%u total=%u \
+nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
+         init_writes, abutted_writes, flushed_writes, total_writes, non_oplock_writes,
+         allocated_write_caches,
+         num_write_caches, direct_writes, num_perfect_writes, cache_read_hits ));
+
+    DEBUG(3,("WRITECACHE: SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n",
+    flush_reasons[SEEK_FLUSH],
+    flush_reasons[READ_FLUSH],
+    flush_reasons[WRITE_FLUSH],
+    flush_reasons[READRAW_FLUSH],
+    flush_reasons[OPLOCK_RELEASE_FLUSH],
+    flush_reasons[CLOSE_FLUSH],
+    flush_reasons[SYNC_FLUSH] ));
+  }
+
+  if(!wcp) {
+    direct_writes++;
+    return real_write_file(fsp, data, pos, n);
+  }
+
+  DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n",
+       fsp->fd_ptr->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size));
+
+  /* 
+   * If we have active cache and it isn't contiguous then we flush.
+   * NOTE: There is a small problem with running out of disk ....
+   */
+
+  if (wcp->data_size) {
+
+    BOOL cache_flush_needed = False;
+
+    if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) {
+      
+      /*
+       * Start of write overlaps or abutts the existing data.
+       */
+
+      size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n);
+
+      memcpy(wcp->data + (pos - wcp->offset), data, data_used);
+
+      /*
+       * Update the current buffer size with the new data.
+       */
+
+      if(pos + data_used > wcp->offset + wcp->data_size)
+        wcp->data_size = pos + data_used - wcp->offset;
+
+      /*
+       * If we used all the data then
+       * return here.
+       */
+
+      if(n == data_used)
+        return n;
+      else
+        cache_flush_needed = True;
+
+      /*
+       * Move the start of data forward by the amount used,
+       * cut down the amount left by the same amount.
+       */
+
+      data += data_used;
+      pos += data_used;
+      n -= data_used;
+
+      abutted_writes++;
+      total_written = data_used;
+
+      write_path = 1;
+
+    } else if ((pos < wcp->offset) && (pos + n > wcp->offset) && 
+               (pos + n <= wcp->offset + wcp->alloc_size)) {
+
+      /*
+       * End of write overlaps the existing data.
+       */
+
+      size_t data_used = pos + n - wcp->offset;
+
+      memcpy(wcp->data, data + n - data_used, data_used);
+
+      /*
+       * Update the current buffer size with the new data.
+       */
+
+      if(pos + n > wcp->offset + wcp->data_size)
+        wcp->data_size = pos + n - wcp->offset;
+
+      /*
+       * We don't need to move the start of data, but we
+       * cut down the amount left by the amount used.
+       */
+
+      n -= data_used;
+
+      /*
+       * We cannot have used all the data here.
+       */
+
+      cache_flush_needed = True;
+
+      abutted_writes++;
+      total_written = data_used;
+
+      write_path = 2;
+
+    } else if ( (pos >= wcp->file_size) && 
+                (pos > wcp->offset + wcp->data_size) && 
+                (pos < wcp->offset + wcp->alloc_size) ) {
+
+      /*
+       * Non-contiguous write part of which fits within
+       * the cache buffer and is extending the file.
+       */
+
+      size_t data_used;
+
+      if(pos + n <= wcp->offset + wcp->alloc_size)
+        data_used = n;
+      else
+        data_used = wcp->offset + wcp->alloc_size - pos;
+
+      /*
+       * Fill in the non-continuous area with zeros.
+       */
+
+      memset(wcp->data + wcp->data_size, '\0',
+             pos - (wcp->offset + wcp->data_size) );
+
+      memcpy(wcp->data + (pos - wcp->offset), data, data_used);
+
+      /*
+       * Update the current buffer size with the new data.
+       */
+
+      if(pos + data_used > wcp->offset + wcp->data_size)
+        wcp->data_size = pos + data_used - wcp->offset;
+
+      /*
+       * Update the known file length.
+       */
+
+      wcp->file_size = wcp->offset + wcp->data_size;
+
+#if 0
+      if (set_filelen(fsp->fd_ptr->fd, wcp->file_size) == -1) {
+        DEBUG(0,("write_file: error %s in setting file to length %.0f\n",
+          strerror(errno), (double)wcp->file_size ));
+        return -1;
+      }
+#endif
+
+      /*
+       * If we used all the data then
+       * return here.
+       */
+
+      if(n == data_used)
+        return n;
+      else
+        cache_flush_needed = True;
+
+      /*
+       * Move the start of data forward by the amount used,
+       * cut down the amount left by the same amount.
+       */
+
+      data += data_used;
+      pos += data_used;
+      n -= data_used;
+
+      abutted_writes++;
+      total_written = data_used;
+
+      write_path = 3;
+
+    } else {
+
+      /*
+       * Write is bigger than buffer, or there is no overlap on the
+       * low or high ends.
+       */
+
+      DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \
+len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size ));
+
+      /*
+       * Update the file size if needed.
+       */
+
+      if(pos + n > wcp->file_size)
+        wcp->file_size = pos + n;
+
+      /*
+       * If write would fit in the cache, and is larger than
+       * the data already in the cache, flush the cache and
+       * preferentially copy the data new data into it. Otherwise
+       * just write the data directly.
+       */
+
+      if ( n <= wcp->alloc_size && n > wcp->data_size) {
+        cache_flush_needed = True;
+      } else {
+        direct_writes++;
+        return real_write_file(fsp, data, pos, n);
+      }
+
+      write_path = 4;
+
+    }
+
+    if(wcp->data_size > wcp->file_size)
+      wcp->file_size = wcp->data_size;
+
+    if (cache_flush_needed) {
+      flushed_writes++;
+
+      DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
+n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
+             write_path, fsp->fd_ptr->fd, (double)wcp->file_size, (double)pos, (unsigned int)n,
+             (double)wcp->offset, (unsigned int)wcp->data_size ));
+
+      flush_write_cache(fsp, WRITE_FLUSH);
+    }
+  }
+
+  /*
+   * If the write request is bigger than the cache
+   * size, write it all out.
+   */
+
+  if (n > wcp->alloc_size ) {
+    if(real_write_file(fsp, data, pos, n) == -1)
+      return -1;
+    direct_writes++;
+    return total_written + n;
+  }
+
+  /*
+   * If there's any data left, cache it.
+   */
+
+  if (n) {
+    if (wcp->data_size) {
+      abutted_writes++;
+      DEBUG(9,("abutted write (%u)\n", abutted_writes));
+    } else {
+      init_writes++;
+    }
+    memcpy(wcp->data+wcp->data_size, data, n);
+    if (wcp->data_size == 0) {
+      wcp->offset = pos;
+      num_write_caches++;
+    }
+    wcp->data_size += n;
+    DEBUG(9,("cache return %u\n", (unsigned int)n));
+    total_written += n;
+    return total_written; /* .... that's a write :) */
+  }
+  
+  return total_written;
 }
 
+/****************************************************************************
+ Delete the write cache structure.
+****************************************************************************/
+
+void delete_write_cache(files_struct *fsp)
+{
+  write_cache *wcp;
+
+  if(!fsp)
+    return;
+
+  if(!(wcp = fsp->wcp))
+    return;
+
+  allocated_write_caches--;
+
+  SMB_ASSERT(wcp->data_size == 0);
+
+  free(wcp->data);
+  free(wcp);
+
+  fsp->wcp = NULL;
+}
+
+/****************************************************************************
+ Setup the write cache structure.
+****************************************************************************/
+
+static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T filesize)
+{
+  ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn));
+  write_cache *wcp;
+
+  if (allocated_write_caches >= MAX_WRITE_CACHES) return False;
+
+  if(alloc_size == 0 || fsp->wcp)
+    return False;
+
+  if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) {
+    DEBUG(0,("setup_write_cache: malloc fail.\n"));
+    return False;
+  }
+
+  wcp->file_size = filesize;
+  wcp->offset = 0;
+  wcp->alloc_size = alloc_size;
+  wcp->data_size = 0;
+  if((wcp->data = malloc(wcp->alloc_size)) == NULL) {
+    DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n",
+          (unsigned int)wcp->alloc_size ));
+    free(wcp);
+    return False;
+  }
+
+  fsp->wcp = wcp;
+  allocated_write_caches++;
+
+  return True;
+}
+
+/****************************************************************************
+ Cope with a size change.
+****************************************************************************/
+
+void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T filesize)
+{
+  if(fsp->wcp) {
+    flush_write_cache(fsp, SIZECHANGE_FLUSH);
+    fsp->wcp->file_size = filesize;
+  }
+}
+
+/*******************************************************************
+ Flush a write cache struct to disk.
+********************************************************************/
+
+ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
+{
+  write_cache *wcp = fsp->wcp;
+  size_t data_size;
+
+  if(!wcp || !wcp->data_size)
+    return 0;
+
+  data_size = wcp->data_size;
+  wcp->data_size = 0;
+
+  num_write_caches--;
+
+  flush_reasons[(int)reason]++;
+
+  DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
+       fsp->fd_ptr->fd, (double)wcp->offset, (unsigned int)data_size));
+
+  if(data_size == wcp->alloc_size)
+    num_perfect_writes++;
+
+  return real_write_file(fsp, wcp->data, wcp->offset, data_size);
+}
 
 /*******************************************************************
 sync a file
 ********************************************************************/
 
-void sys_sync_file(int fd)
+void sys_fsync_file(connection_struct *conn, files_struct *fsp)
 {
 #ifdef HAVE_FSYNC
-    fsync(fd);
+    if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) {
+      flush_write_cache(fsp, SYNC_FLUSH);
+      conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+    }
 #endif
 }
index 504c35aeec4e412c6f743ecb09237b31d0cbb2ae..729ef8c809949e947e2af6a6345350a546e99c17 100644 (file)
@@ -3,6 +3,8 @@
    Version 1.9.
    filename handling routines
    Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Jeremy Allison 1999-200
+   Copyright (C) Ying Chen 2000
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+/*
+ * New hash table stat cache code added by Ying Chen.
+ */
+
 #include "includes.h"
 
 extern int DEBUGLEVEL;
@@ -26,7 +32,6 @@ extern BOOL case_sensitive;
 extern BOOL case_preserve;
 extern BOOL short_case_preserve;
 extern fstring remote_machine;
-extern pstring global_myname;
 extern BOOL use_mangled_map;
 
 static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache);
@@ -97,7 +102,12 @@ static int global_stat_cache_hits;
 
 void print_stat_cache_statistics(void)
 {
-  double eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
+  double eff;
+
+  if(global_stat_cache_lookups == 0)
+    return;
+
+  eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
 
   DEBUG(0,("stat cache stats: lookups = %d, hits = %d, misses = %d, \
 stat cache was %f%% effective.\n", global_stat_cache_lookups,
@@ -105,15 +115,12 @@ stat cache was %f%% effective.\n", global_stat_cache_lookups,
 }
 
 typedef struct {
-  ubi_dlNode link;
   int name_len;
-  pstring orig_name;
-  pstring translated_name;
+  char names[2]; /* This is extended via malloc... */
 } stat_cache_entry;
 
-#define MAX_STAT_CACHE_SIZE 50
-
-static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0};
+#define INIT_STAT_CACHE_SIZE 512
+static hash_table stat_cache;
 
 /****************************************************************************
  Compare a pathname to a name in the stat cache - of a given length.
@@ -124,6 +131,7 @@ static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0};
  case.
 *****************************************************************************/
 
+#if 0 /* This function unused?? */
 static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
 {
   BOOL matched = (memcmp( stat_name, orig_name, len) == 0);
@@ -132,6 +140,7 @@ static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
 
   return matched;
 }
+#endif
 
 /****************************************************************************
  Add an entry into the stat cache.
@@ -140,9 +149,11 @@ static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
 static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
 {
   stat_cache_entry *scp;
+  stat_cache_entry *found_scp;
   pstring orig_name;
   pstring translated_path;
   int namelen;
+  hash_element *hash_elem;
 
   if (!lp_stat_cache()) return;
 
@@ -190,39 +201,39 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
    * add it.
    */
 
-  for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp; 
-                        scp = (stat_cache_entry *)ubi_dlNext( scp )) {
-    if((strcmp( scp->orig_name, orig_name) == 0) &&
-       (strcmp( scp->translated_name, translated_path) == 0)) {
-      /*
-       * Name does exist - promote it.
-       */
-      if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != scp ) {
-        ubi_dlRemThis( &stat_cache, scp);
-        ubi_dlAddHead( &stat_cache, scp);
-      }
+  if ((hash_elem = hash_lookup(&stat_cache, orig_name))) {
+    found_scp = (stat_cache_entry *)(hash_elem->value);
+    if (strcmp((found_scp->names+found_scp->name_len+1), translated_path) == 0) {
       return;
+    } else {
+      hash_remove(&stat_cache, hash_elem);
+      if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+        DEBUG(0,("stat_cache_add: Out of memory !\n"));
+        return;
+      }
+      pstrcpy(scp->names, orig_name);
+      pstrcpy((scp->names+namelen+1), translated_path);
+      scp->name_len = namelen;
+      hash_insert(&stat_cache, (char *)scp, orig_name);
     }
-  }
-
-  if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry))) == NULL) {
-    DEBUG(0,("stat_cache_add: Out of memory !\n"));
     return;
-  }
-
-  pstrcpy(scp->orig_name, orig_name);
-  pstrcpy(scp->translated_name, translated_path);
-  scp->name_len = namelen;
+  } else {
 
-  ubi_dlAddHead( &stat_cache, scp);
-
-  DEBUG(10,("stat_cache_add: Added entry %s -> %s\n", scp->orig_name, scp->translated_name ));
+    /*
+     * New entry.
+     */
 
-  if(ubi_dlCount(&stat_cache) > lp_stat_cache_size()) {
-    scp = (stat_cache_entry *)ubi_dlRemTail( &stat_cache );
-    free((char *)scp);
-    return;
+    if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
+      DEBUG(0,("stat_cache_add: Out of memory !\n"));
+      return;
+    }
+    pstrcpy(scp->names, orig_name);
+    pstrcpy(scp->names+namelen+1, translated_path);
+    scp->name_len = namelen;
+    hash_insert(&stat_cache, (char *)scp, orig_name);
   }
+
+  DEBUG(5,("stat_cache_add: Added entry %s -> %s\n", scp->names, (scp->names+scp->name_len+1)));
 }
 
 /****************************************************************************
@@ -230,16 +241,18 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
  Return True if we translated (and did a scuccessful stat on) the entire name.
 *****************************************************************************/
 
-static BOOL stat_cache_lookup(struct connection_struct *conn, char *name, 
-                             char *dirpath, char **start, 
-                             SMB_STRUCT_STAT *pst)
+static BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath, 
+                              char **start, SMB_STRUCT_STAT *pst)
 {
   stat_cache_entry *scp;
-  stat_cache_entry *longest_hit = NULL;
+  char *trans_name;
   pstring chk_name;
   int namelen;
+  hash_element *hash_elem;
+  char *sp;
 
-  if (!lp_stat_cache()) return False;
+  if (!lp_stat_cache())
+    return False;
  
   namelen = strlen(name);
 
@@ -258,123 +271,46 @@ static BOOL stat_cache_lookup(struct connection_struct *conn, char *name,
   if(!case_sensitive)
     strupper( chk_name );
 
-  for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp; 
-                        scp = (stat_cache_entry *)ubi_dlNext( scp )) {
-    if(scp->name_len <= namelen) {
-      if(stat_name_equal_len(scp->orig_name, chk_name, scp->name_len)) {
-        if((longest_hit == NULL) || (longest_hit->name_len <= scp->name_len))
-          longest_hit = scp;
+  while (1) {
+    hash_elem = hash_lookup(&stat_cache, chk_name);
+    if(hash_elem == NULL) {
+      /*
+       * Didn't find it - remove last component for next try.
+       */
+      sp = strrchr(chk_name, '/');
+      if (sp) {
+        *sp = '\0';
+      } else {
+        /*
+         * We reached the end of the name - no match.
+         */
+        global_stat_cache_misses++;
+        return False;
+      }
+      if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
+                          || (strcmp(chk_name, "..") == 0)) {
+        global_stat_cache_misses++;
+        return False;
       }
+    } else {
+      scp = (stat_cache_entry *)(hash_elem->value);
+      global_stat_cache_hits++;
+      trans_name = scp->names+scp->name_len+1;
+      if(conn->vfs_ops.stat(dos_to_unix(trans_name,False), pst) != 0) {
+        /* Discard this entry - it doesn't exist in the filesystem.  */
+        hash_remove(&stat_cache, hash_elem);
+        return False;
+      }
+      memcpy(name, trans_name, scp->name_len);
+      *start = &name[scp->name_len];
+      if(**start == '/')
+        ++*start;
+      StrnCpy( dirpath, trans_name, name - (*start));
+      return (namelen == scp->name_len);
     }
   }
-
-  if(longest_hit == NULL) {
-    DEBUG(10,("stat_cache_lookup: cache miss on %s\n", name));
-    global_stat_cache_misses++;
-    return False;
-  }
-
-  global_stat_cache_hits++;
-
-  DEBUG(10,("stat_cache_lookup: cache hit for name %s. %s -> %s\n",
-        name, longest_hit->orig_name, longest_hit->translated_name ));
-
-  /*
-   * longest_hit is the longest match we got in the list.
-   * Check it exists - if so, overwrite the original name
-   * and then promote it to the top.
-   */
-
-  if(conn->vfs_ops.stat(dos_to_unix(longest_hit->translated_name,False), 
-                        pst) != 0) {
-    /*
-     * Discard this entry.
-     */
-    ubi_dlRemThis( &stat_cache, longest_hit);
-    free((char *)longest_hit);
-    return False;
-  }
-
-  memcpy(name, longest_hit->translated_name, longest_hit->name_len);
-  if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != longest_hit ) {
-    ubi_dlRemThis( &stat_cache, longest_hit);
-    ubi_dlAddHead( &stat_cache, longest_hit);
-  }
-
-  *start = &name[longest_hit->name_len];
-  if(**start == '/')
-    ++*start;
-
-  StrnCpy( dirpath, longest_hit->translated_name, name - (*start));
-
-  return (namelen == longest_hit->name_len);
 }
 
-/****************************************************************************
- this routine converts from the dos and dfs namespace to the unix namespace.
-****************************************************************************/
-BOOL unix_dfs_convert(char *name,connection_struct *conn,
-                               char *saved_last_component, 
-                               BOOL *bad_path, SMB_STRUCT_STAT *pst)
-{
-       pstring local_path;
-
-       DEBUG(10,("unix_dfs_convert: %s\n", name));
-
-       if (name != NULL &&
-           under_dfs(conn, name, local_path, sizeof(local_path)))
-       {
-               DEBUG(10,("%s is in dfs map.\n", name));
-
-               /* check for our own name */
-               if (StrCaseCmp(global_myname, name+1) > 0)
-               {
-                       return False;
-               }
-
-               pstrcpy(name, local_path);
-
-               DEBUG(10,("removed name: %s\n", name));
-       }
-       return unix_convert(name, conn, saved_last_component, bad_path, pst);
-}
-
-
-/*******************************************************************
-reduce a file name, removing .. elements. 
-********************************************************************/
-static void unix_clean_name(char *s)
-{
-  char *p=NULL;
-
-  DEBUG(3,("unix_clean_name [%s]\n",s));
-
-  /* remove any double slashes */
-  string_sub(s, "//","/");
-
-  /* Remove leading ./ characters */
-  if(strncmp(s, "./", 2) == 0) {
-    trim_string(s, "./", NULL);
-    if(*s == 0)
-      pstrcpy(s,"./");
-  }
-
-  while ((p = strstr(s,"/../")) != NULL)
-    {
-      pstring s1;
-
-      *p = 0;
-      pstrcpy(s1,p+3);
-
-      if ((p=strrchr(s,'/')) != NULL)
-       *p = 0;
-      else
-       *s = 0;
-      pstrcat(s,s1);
-    }  
-
-  trim_string(s,NULL,"/..");
-}
 /****************************************************************************
 This routine is called to convert names from the dos namespace to unix
 namespace. It needs to handle any case conversions, mangling, format
@@ -396,15 +332,14 @@ used to pick the correct error code to return between ENOENT and ENOTDIR
 as Windows applications depend on ERRbadpath being returned if a component
 of a pathname does not exist.
 ****************************************************************************/
-BOOL unix_convert(char *name,connection_struct *conn,
-                               char *saved_last_component, 
-                               BOOL *bad_path, SMB_STRUCT_STAT *pst)
+
+BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, 
+                  BOOL *bad_path, SMB_STRUCT_STAT *pst)
 {
   SMB_STRUCT_STAT st;
   char *start, *end;
   pstring dirpath;
   pstring orig_path;
-  int saved_errno;
   BOOL component_was_mangled = False;
   BOOL name_has_wildcard = False;
 #if 0
@@ -417,7 +352,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
   *dirpath = 0;
   *bad_path = False;
   if(pst) {
-         ZERO_STRUCTP(pst);
+    ZERO_STRUCTP(pst);
   }
 
   if(saved_last_component)
@@ -480,7 +415,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
 
       for (s=name2 ; *s ; s++)
         if (!issafe(*s)) *s = '_';
-      pstrcpy(name,(char *)mktemp(name2));       
+      pstrcpy(name,(char *)smbd_mktemp(name2));          
     }      
     return(True);
   }
@@ -518,8 +453,6 @@ BOOL unix_convert(char *name,connection_struct *conn,
     return(True);
   }
 
-  saved_errno = errno;
-
   DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
         name, dirpath, start));
 
@@ -529,7 +462,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
    */
 
   if (case_sensitive && !is_mangled(name) && 
-      !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
+      !lp_strip_dot() && !use_mangled_map)
     return(False);
 
   if(strchr(start,'?') || strchr(start,'*'))
@@ -702,136 +635,6 @@ BOOL unix_convert(char *name,connection_struct *conn,
   return(True);
 }
 
-/*******************************************************************
-reduce a file name, removing .. elements and checking that 
-it is below dir in the hierarchy. This uses GetWd() and so must be run
-on the system that has the referenced file system.
-
-widelinks are allowed if widelinks is true
-********************************************************************/
-
-static BOOL reduce_name(char *s,char *dir,BOOL widelinks)
-{
-#ifndef REDUCE_PATHS
-  return True;
-#else
-  pstring dir2;
-  pstring wd;
-  pstring base_name;
-  pstring newname;
-  char *p=NULL;
-  BOOL relative = (*s != '/');
-
-  *dir2 = *wd = *base_name = *newname = 0;
-
-  if (widelinks)
-    {
-      unix_clean_name(s);
-      /* can't have a leading .. */
-      if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
-       {
-         DEBUG(3,("Illegal file name? (%s)\n",s));
-         return(False);
-       }
-
-      if (strlen(s) == 0)
-        pstrcpy(s,"./");
-
-      return(True);
-    }
-  
-  DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
-
-  /* remove any double slashes */
-  string_sub(s,"//","/");
-
-  pstrcpy(base_name,s);
-  p = strrchr(base_name,'/');
-
-  if (!p)
-    return(True);
-
-  if (!dos_GetWd(wd))
-    {
-      DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
-      return(False);
-    }
-
-  if (dos_ChDir(dir) != 0)
-    {
-      DEBUG(0,("couldn't chdir to %s\n",dir));
-      return(False);
-    }
-
-  if (!dos_GetWd(dir2))
-    {
-      DEBUG(0,("couldn't getwd for %s\n",dir));
-      dos_ChDir(wd);
-      return(False);
-    }
-
-
-    if (p && (p != base_name))
-      {
-       *p = 0;
-       if (strcmp(p+1,".")==0)
-         p[1]=0;
-       if (strcmp(p+1,"..")==0)
-         *p = '/';
-      }
-
-  if (dos_ChDir(base_name) != 0)
-    {
-      dos_ChDir(wd);
-      DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
-      return(False);
-    }
-
-  if (!dos_GetWd(newname))
-    {
-      dos_ChDir(wd);
-      DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
-      return(False);
-    }
-
-  if (p && (p != base_name))
-    {
-      pstrcat(newname,"/");
-      pstrcat(newname,p+1);
-    }
-
-  {
-    size_t l = strlen(dir2);    
-    if (dir2[l-1] == '/')
-      l--;
-
-    if (strncmp(newname,dir2,l) != 0)
-      {
-       dos_ChDir(wd);
-       DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
-       return(False);
-      }
-
-    if (relative)
-      {
-       if (newname[l] == '/')
-         pstrcpy(s,newname + l + 1);
-       else
-         pstrcpy(s,newname+l);
-      }
-    else
-      pstrcpy(s,newname);
-  }
-
-  dos_ChDir(wd);
-
-  if (strlen(s) == 0)
-    pstrcpy(s,"./");
-
-  DEBUG(3,("reduced to %s\n",s));
-  return(True);
-#endif
-}
 
 /****************************************************************************
 check a filename - possibly caling reducename
@@ -925,7 +728,8 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
        continue;
 
       pstrcpy(name2,dname);
-      if (!name_map_mangle(name2,False,SNUM(conn))) continue;
+      if (!name_map_mangle(name2,False,True,SNUM(conn)))
+        continue;
 
       if ((mangled && mangled_equal(name,name2))
          || fname_equal(name, name2))
@@ -941,3 +745,16 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
   CloseDir(cur_dir);
   return(False);
 }
+
+/*************************************************************************** **
+ * Initializes or clears the stat cache.
+ *
+ *  Input:  none.
+ *  Output: none.
+ *
+ * ************************************************************************** **
+ */
+BOOL reset_stat_cache( void )
+{
+  return hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, (compare_function)(strcmp));
+} /* reset_stat_cache  */
index 7f4533e7ae78ef10044a4ea2269e8c4c122b3d4c..d62950c568ae5fb1fe2e669f6cffaff66133d704 100644 (file)
@@ -97,7 +97,7 @@ files_struct *file_new(void )
        files_used++;
 
        fsp->fnum = i + FILE_HANDLE_OFFSET;
-       string_init(&fsp->fsp_name,"");
+       string_set(&fsp->fsp_name,"");
        
        DLIST_ADD(Files, fsp);
 
@@ -186,10 +186,7 @@ void file_close_conn(connection_struct *conn)
        for (fsp=Files;fsp;fsp=next) {
                next = fsp->next;
                if (fsp->conn == conn && fsp->open) {
-                       if (fsp->is_directory)
-                               close_directory(fsp); 
-                       else                  
-                               close_file(fsp,False); 
+                       close_file(fsp,False); 
                }
        }
 }
@@ -226,7 +223,7 @@ open files, %d are available.\n", request_max_open_files, real_max_open_files));
        }
        
        /*
-        * Ensure that pipe_handle_offset is set correctly.
+        * Ensure that pipe_handle_oppset is set correctly.
         */
        set_pipe_handle_offset(real_max_open_files);
 }
@@ -242,10 +239,7 @@ void file_close_user(int vuid)
        for (fsp=Files;fsp;fsp=next) {
                next=fsp->next;
                if ((fsp->vuid == vuid) && fsp->open) {
-                       if(!fsp->is_directory)
-                               close_file(fsp,False);
-                       else
-                               close_directory(fsp);
+                       close_file(fsp,False);
                }
        }
 }
@@ -340,13 +334,13 @@ void file_sync_all(connection_struct *conn)
 
        for (fsp=Files;fsp;fsp=next) {
                next=fsp->next;
-               if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)
-                   && lp_strict_sync(SNUM(conn))){
-                   conn->vfs_ops.sync(fsp->fd_ptr->fd);
+               if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)) {
+                       conn->vfs_ops.fsync(fsp->fd_ptr->fd);
                }
        }
 }
 
+
 /****************************************************************************
 free up a fd_ptr
 ****************************************************************************/
index 278869d4946bdd94f330be8d8dceffd4334b7abd..578775e73a0937de9e2edc1d960604624a06824e 100644 (file)
@@ -51,55 +51,63 @@ extern uint32 global_client_caps;
 
  ******************************************************************/
 static void copy_trans_params_and_data(char *outbuf, int align,
-                               prs_struct *rparam, prs_struct *rdata,
-                               int param_offset, int data_offset,
-                               int param_len, int data_len)
+                                      prs_struct *rparam, prs_struct *rdata,
+                                      int param_offset, int data_offset,
+                                      int param_len, int data_len)
 {
-       char *copy_into = smb_buf(outbuf)+1;
+       char *copy_into = smb_buf(outbuf) + 1;
 
-       DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
-                       param_offset, param_offset + param_len,
-                       data_offset , data_offset  + data_len));
+       DEBUG(5, ("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
+                 param_offset, param_offset + param_len,
+                 data_offset, data_offset + data_len));
 
-       if (param_len) prs_buf_copy(copy_into, rparam, param_offset, param_len);
+       if (param_len)
+               prs_buf_copy(copy_into, rparam, param_offset, param_len);
        copy_into += param_len + align;
-       if (data_len ) prs_buf_copy(copy_into, rdata , data_offset , data_len);
+       if (data_len)
+               prs_buf_copy(copy_into, rdata, data_offset, data_len);
 }
 
 /****************************************************************************
   send a trans reply
   ****************************************************************************/
 void send_trans_reply(char *outbuf,
-                               prs_struct *rdata,
-                               prs_struct *rparam,
-                               uint16 *setup, int lsetup, int max_data_ret,
-                               BOOL pipe_data_outstanding)
+                     prs_struct *rdata,
+                     prs_struct *rparam,
+                     uint16 *setup, int lsetup, int max_data_ret,
+                     BOOL pipe_data_outstanding)
 {
        int i;
-       int this_ldata,this_lparam;
-       int tot_data=0,tot_param=0;
+       int this_ldata, this_lparam;
+       int tot_data = 0, tot_param = 0;
        int align;
 
-       int ldata  = rdata  ? prs_buf_len(rdata ) : 0;
+       int ldata = rdata ? prs_buf_len(rdata) : 0;
        int lparam = rparam ? prs_buf_len(rparam) : 0;
 
        BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
 
-       DEBUG(10,("send_trans_reply: max_data_ret: %d datalen: %d plen: %d\n",
-                               max_data_ret, ldata, lparam));
+       DEBUG(10,
+             ("send_trans_reply: max_data_ret: %d datalen: %d plen: %d\n",
+              max_data_ret, ldata, lparam));
 
        if (buffer_too_large)
        {
-               DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
+               DEBUG(5,
+                     ("send_trans_reply: buffer %d too large %d\n", ldata,
+                      max_data_ret));
                ldata = max_data_ret;
        }
 
-       this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
-       this_ldata  = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
+       this_lparam = MIN(lparam, max_send - (500 + lsetup * SIZEOFWORD));      /* hack */
+       this_ldata =
+               MIN(ldata,
+                   max_send - (500 + lsetup * SIZEOFWORD + this_lparam));
 
-       align = ((this_lparam)%4);
+       align = ((this_lparam) % 4);
 
-       set_message(outbuf,10+lsetup,1+align+this_ldata+this_lparam,True);
+       set_message(outbuf, 10 + lsetup, 1 + align + this_ldata + this_lparam,
+                   True);
 
        if (buffer_too_large || pipe_data_outstanding)
        {
@@ -107,65 +115,73 @@ void send_trans_reply(char *outbuf,
                {
                        /* issue a buffer size warning.  on a DCE/RPC pipe, expect an SMBreadX... */
                        SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-                       SIVAL(outbuf, smb_rcls, 0x80000005); /* STATUS_BUFFER_OVERFLOW */
-               } else {
+                       SIVAL(outbuf, smb_rcls, 0x80000005);    /* STATUS_BUFFER_OVERFLOW */
+               }
+               else
+               {
                        SCVAL(outbuf, smb_rcls, ERRDOS);
                        SSVAL(outbuf, smb_err, ERRmoredata);
                }
        }
 
        copy_trans_params_and_data(outbuf, align,
-                                  rparam     , rdata,
-                                  tot_param  , tot_data,
-                                  this_lparam, this_ldata);
-
-       SSVAL(outbuf,smb_vwv0,lparam);
-       SSVAL(outbuf,smb_vwv1,ldata);
-       SSVAL(outbuf,smb_vwv3,this_lparam);
-       SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
-       SSVAL(outbuf,smb_vwv5,0);
-       SSVAL(outbuf,smb_vwv6,this_ldata);
-       SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
-       SSVAL(outbuf,smb_vwv8,0);
-       SSVAL(outbuf,smb_vwv9,lsetup);
-
-       for (i=0;i<lsetup;i++)
+                                  rparam, rdata,
+                                  tot_param, tot_data,
+                                  this_lparam, this_ldata);
+
+       SSVAL(outbuf, smb_vwv0, lparam);
+       SSVAL(outbuf, smb_vwv1, ldata);
+       SSVAL(outbuf, smb_vwv3, this_lparam);
+       SSVAL(outbuf, smb_vwv4, smb_offset(smb_buf(outbuf) + 1, outbuf));
+       SSVAL(outbuf, smb_vwv5, 0);
+       SSVAL(outbuf, smb_vwv6, this_ldata);
+       SSVAL(outbuf, smb_vwv7,
+             smb_offset(smb_buf(outbuf) + 1 + this_lparam + align, outbuf));
+       SSVAL(outbuf, smb_vwv8, 0);
+       SSVAL(outbuf, smb_vwv9, lsetup);
+
+       for (i = 0; i < lsetup; i++)
        {
-               SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+               SSVAL(outbuf, smb_vwv10 + i * SIZEOFWORD, setup[i]);
        }
 
        show_msg(outbuf);
-       send_smb(Client,outbuf);
+       send_smb(Client, outbuf);
 
        tot_data = this_ldata;
        tot_param = this_lparam;
 
        while (tot_data < ldata || tot_param < lparam)
        {
-               this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
-               this_ldata  = MIN(ldata -tot_data , max_send - (500+this_lparam));
+               this_lparam = MIN(lparam - tot_param, max_send - 500);  /* hack */
+               this_ldata =
+                       MIN(ldata - tot_data, max_send - (500 + this_lparam));
 
-               align = (this_lparam%4);
+               align = (this_lparam % 4);
 
-               set_message(outbuf,10,1+this_ldata+this_lparam+align,False);
+               set_message(outbuf, 10, 1 + this_ldata + this_lparam + align,
+                           False);
 
                copy_trans_params_and_data(outbuf, align,
-                                          rparam     , rdata,
-                                          tot_param  , tot_data,
-                                          this_lparam, this_ldata);
-
-               SSVAL(outbuf,smb_vwv3,this_lparam);
-               SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
-               SSVAL(outbuf,smb_vwv5,tot_param);
-               SSVAL(outbuf,smb_vwv6,this_ldata);
-               SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
-               SSVAL(outbuf,smb_vwv8,tot_data);
-               SSVAL(outbuf,smb_vwv9,0);
+                                          rparam, rdata,
+                                          tot_param, tot_data,
+                                          this_lparam, this_ldata);
+
+               SSVAL(outbuf, smb_vwv3, this_lparam);
+               SSVAL(outbuf, smb_vwv4,
+                     smb_offset(smb_buf(outbuf) + 1, outbuf));
+               SSVAL(outbuf, smb_vwv5, tot_param);
+               SSVAL(outbuf, smb_vwv6, this_ldata);
+               SSVAL(outbuf, smb_vwv7,
+                     smb_offset(smb_buf(outbuf) + 1 + this_lparam + align,
+                                outbuf));
+               SSVAL(outbuf, smb_vwv8, tot_data);
+               SSVAL(outbuf, smb_vwv9, 0);
 
                show_msg(outbuf);
-               send_smb(Client,outbuf);
+               send_smb(Client, outbuf);
 
-               tot_data  += this_ldata;
+               tot_data += this_ldata;
                tot_param += this_lparam;
        }
 }
@@ -177,20 +193,21 @@ static void api_rpc_trans_reply(char *outbuf, char *rdata, int rlen,
        prs_create(&ps, rdata, rlen, 0, False);
        prs_debug_out(&ps, "api_rpc_trans_reply", 200);
        send_trans_reply(outbuf, &ps, NULL, NULL, 0, rlen,
-                        pipe_data_outstanding);
+                        pipe_data_outstanding);
 }
 
 /****************************************************************************
  WaitNamedPipeHandleState 
 ****************************************************************************/
-static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
+static BOOL api_WNPHS(char *outbuf, pipes_struct * p, char *param, int mdrcnt)
 {
        uint16 priority;
 
-       if (!param) return False;
+       if (!param)
+               return False;
 
        priority = param[0] + (param[1] << 8);
-       DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority));
+       DEBUG(4, ("WaitNamedPipeHandleState priority %x\n", priority));
 
        if (wait_rpc_pipe_hnd_state(p, priority))
        {
@@ -206,14 +223,15 @@ static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
 /****************************************************************************
  SetNamedPipeHandleState 
 ****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
+static BOOL api_SNPHS(char *outbuf, pipes_struct * p, char *param, int mdrcnt)
 {
        uint16 id;
 
-       if (!param) return False;
+       if (!param)
+               return False;
 
        id = param[0] + (param[1] << 8);
-       DEBUG(4,("SetNamedPipeHandleState to code %x\n", id));
+       DEBUG(4, ("SetNamedPipeHandleState to code %x\n", id));
 
        if (set_rpc_pipe_hnd_state(p, id))
        {
@@ -236,42 +254,44 @@ static BOOL api_no_reply(char *outbuf, int max_rdata_len)
        prs_init(&rparam, 4, 0, False);
 
        rparam.start = 0;
-       rparam.end   = 4;
+       rparam.end = 4;
 
        /* unsupported */
-       SSVAL(rparam.data,0,NERR_notsupported);
-       SSVAL(rparam.data,2,0); /* converter word */
+       SSVAL(rparam.data, 0, NERR_notsupported);
+       SSVAL(rparam.data, 2, 0);       /* converter word */
 
-       DEBUG(3,("Unsupported API fd command\n"));
+       DEBUG(3, ("Unsupported API fd command\n"));
 
        /* now send the reply */
-       send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len, False);
+       send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len,
+                        False);
 
        prs_free_data(&rparam);
 
-       return(-1);
+       return (-1);
 }
 
 /****************************************************************************
   handle remote api calls delivered to a named pipe already opened.
   ****************************************************************************/
-static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
-                       uint16 *setup,char *data,char *params,
-                       int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+static int api_fd_reply(connection_struct * conn, uint16 vuid, char *outbuf,
+                       uint16 *setup, char *data, char *params,
+                       int suwcnt, int tdscnt, int tpscnt, int mdrcnt,
+                       int mprcnt)
 {
-       BOOL reply    = False;
+       BOOL reply = False;
 
        uint16 pnum;
        uint16 subcommand;
        pipes_struct *p = NULL;
 
-       DEBUG(5,("api_fd_reply\n"));
+       DEBUG(5, ("api_fd_reply\n"));
 
        /* First find out the name of this file. */
        if (suwcnt != 2)
        {
-               DEBUG(0,("Unexpected named pipe transaction.\n"));
-               return(-1);
+               DEBUG(0, ("Unexpected named pipe transaction.\n"));
+               return (-1);
        }
 
        /* Get the file handle and hence the file name. */
@@ -281,11 +301,11 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
 
        if (p != NULL)
        {
-               DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
-                                 subcommand, p->name, pnum));
+               DEBUG(3, ("Got API command 0x%x on pipe \"%s\" (pnum %x)",
+                         subcommand, p->name, pnum));
 
                /* record maximum data length that can be transmitted in an SMBtrans */
-                DEBUG(10,("api_fd_reply: p:%p mdrcnt: %d\n", p, mdrcnt));
+               DEBUG(10, ("api_fd_reply: p:%p mdrcnt: %d\n", p, mdrcnt));
 
                switch (subcommand)
                {
@@ -295,12 +315,13 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
                                char *rdata = NULL;
                                int rlen = mdrcnt;
                                reply = readwrite_pipe(p, data, tdscnt,
-                                                      &rdata, &rlen,
-                                                      &pipe_outstanding);
+                                                      &rdata, &rlen,
+                                                      &pipe_outstanding);
                                if (reply)
                                {
-                                       api_rpc_trans_reply(outbuf, rdata, rlen,
-                                                           pipe_outstanding);
+                                       api_rpc_trans_reply(outbuf, rdata,
+                                                           rlen,
+                                                           pipe_outstanding);
                                }
                                break;
                        }
@@ -320,7 +341,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
        }
        else
        {
-               DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+               DEBUG(1, ("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
        }
 
        if (!reply)
@@ -333,36 +354,40 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
 /****************************************************************************
   handle named pipe commands
   ****************************************************************************/
-static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *name,
-                     uint16 *setup,char *data,char *params,
-                     int suwcnt,int tdscnt,int tpscnt,
-                     int msrcnt,int mdrcnt,int mprcnt)
+static int named_pipe(connection_struct * conn, uint16 vuid, char *outbuf,
+                     char *name, uint16 *setup, char *data, char *params,
+                     int suwcnt, int tdscnt, int tpscnt, int msrcnt,
+                     int mdrcnt, int mprcnt)
 {
-       DEBUG(3,("named pipe command on <%s> name\n", name));
+       DEBUG(3, ("named pipe command on <%s> name\n", name));
 
-       if (strequal(name,"LANMAN"))
+       if (strequal(name, "LANMAN"))
        {
-               return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
+               return api_reply(conn, vuid, outbuf, data, params, tdscnt,
+                                tpscnt, mdrcnt, mprcnt);
        }
 
-       if (strequal(name,"WKSSVC") ||
-           strequal(name,"SRVSVC") ||
-           strequal(name,"WINREG") ||
-           strequal(name,"SAMR") ||
-           strequal(name,"LSARPC"))
+       if (strequal(name, "WKSSVC") ||
+           strequal(name, "SRVSVC") ||
+           strequal(name, "WINREG") ||
+           strequal(name, "SAMR") || strequal(name, "LSARPC"))
        {
-               DEBUG(4,("named pipe command from Win95 (wow!)\n"));
-               return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
+               DEBUG(4, ("named pipe command from Win95 (wow!)\n"));
+               return api_fd_reply(conn, vuid, outbuf, setup, data, params,
+                                   suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt);
        }
 
        if (strlen(name) < 1)
        {
-               return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
+               return api_fd_reply(conn, vuid, outbuf, setup, data, params,
+                                   suwcnt, tdscnt, tpscnt, mdrcnt, mprcnt);
        }
 
        if (setup)
        {
-               DEBUG(3,("unknown named pipe: setup 0x%X setup1=%d\n", (int)setup[0],(int)setup[1]));
+               DEBUG(3,
+                     ("unknown named pipe: setup 0x%X setup1=%d\n",
+                      (int)setup[0], (int)setup[1]));
        }
 
        return 0;
@@ -372,153 +397,188 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na
 /****************************************************************************
   reply to a SMBtrans
   ****************************************************************************/
-int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize)
+int reply_trans(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int bufsize)
 {
        fstring name;
-        int name_offset = 0;
-       char *data=NULL,*params=NULL;
-       uint16 *setup=NULL;
+       int name_offset = 0;
+       char *data = NULL, *params = NULL;
+       uint16 *setup = NULL;
        int outsize = 0;
-       uint16 vuid = SVAL(inbuf,smb_uid);
-       int tpscnt = SVAL(inbuf,smb_vwv0);
-       int tdscnt = SVAL(inbuf,smb_vwv1);
-       int mprcnt = SVAL(inbuf,smb_vwv2);
-       int mdrcnt = SVAL(inbuf,smb_vwv3);
-       int msrcnt = CVAL(inbuf,smb_vwv4);
-       BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
-       BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
-       int pscnt = SVAL(inbuf,smb_vwv9);
-       int psoff = SVAL(inbuf,smb_vwv10);
-       int dscnt = SVAL(inbuf,smb_vwv11);
-       int dsoff = SVAL(inbuf,smb_vwv12);
-       int suwcnt = CVAL(inbuf,smb_vwv13);
+       uint16 vuid = SVAL(inbuf, smb_uid);
+       int tpscnt = SVAL(inbuf, smb_vwv0);
+       int tdscnt = SVAL(inbuf, smb_vwv1);
+       int mprcnt = SVAL(inbuf, smb_vwv2);
+       int mdrcnt = SVAL(inbuf, smb_vwv3);
+       int msrcnt = CVAL(inbuf, smb_vwv4);
+       BOOL close_on_completion = BITSETW(inbuf + smb_vwv5, 0);
+       BOOL one_way = BITSETW(inbuf + smb_vwv5, 1);
+       int pscnt = SVAL(inbuf, smb_vwv9);
+       int psoff = SVAL(inbuf, smb_vwv10);
+       int dscnt = SVAL(inbuf, smb_vwv11);
+       int dsoff = SVAL(inbuf, smb_vwv12);
+       int suwcnt = CVAL(inbuf, smb_vwv13);
 
        ZERO_STRUCT(name);
-       fstrcpy(name,smb_buf(inbuf));
+       fstrcpy(name, smb_buf(inbuf));
 
-       if (dscnt > tdscnt || pscnt > tpscnt) {
+       if (dscnt > tdscnt || pscnt > tpscnt)
+       {
                exit_server("invalid trans parameters\n");
        }
-  
-       if (tdscnt)  {
-               if((data = (char *)malloc(tdscnt)) == NULL) {
-                       DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
-                       return(ERROR(ERRDOS,ERRnomem));
-               } 
-               memcpy(data,smb_base(inbuf)+dsoff,dscnt);
+
+       if (tdscnt)
+       {
+               if ((data = (char *)malloc(tdscnt)) == NULL)
+               {
+                       DEBUG(0,
+                             ("reply_trans: data malloc fail for %d bytes !\n",
+                              tdscnt));
+                       return (ERROR(ERRDOS, ERRnomem));
+               }
+               memcpy(data, smb_base(inbuf) + dsoff, dscnt);
        }
 
-       if (tpscnt) {
-               if((params = (char *)malloc(tpscnt)) == NULL) {
-                       DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
-                       return(ERROR(ERRDOS,ERRnomem));
-               } 
-               memcpy(params,smb_base(inbuf)+psoff,pscnt);
+       if (tpscnt)
+       {
+               if ((params = (char *)malloc(tpscnt)) == NULL)
+               {
+                       DEBUG(0,
+                             ("reply_trans: param malloc fail for %d bytes !\n",
+                              tpscnt));
+                       return (ERROR(ERRDOS, ERRnomem));
+               }
+               memcpy(params, smb_base(inbuf) + psoff, pscnt);
        }
 
-       if (suwcnt) {
+       if (suwcnt)
+       {
                int i;
-               if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
-          DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", suwcnt * sizeof(uint16)));
-                 return(ERROR(ERRDOS,ERRnomem));
-        } 
-               for (i=0;i<suwcnt;i++)
-                       setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
+               if ((setup = (uint16 *)malloc(suwcnt * sizeof(uint16))) ==
+                   NULL)
+               {
+                       DEBUG(0,
+                             ("reply_trans: setup malloc fail for %d bytes !\n",
+                              suwcnt * sizeof(uint16)));
+                       return (ERROR(ERRDOS, ERRnomem));
+               }
+               for (i = 0; i < suwcnt; i++)
+                       setup[i] = SVAL(inbuf, smb_vwv14 + i * SIZEOFWORD);
        }
 
 
-       if (pscnt < tpscnt || dscnt < tdscnt) {
+       if (pscnt < tpscnt || dscnt < tdscnt)
+       {
                /* We need to send an interim response then receive the rest
                   of the parameter/data bytes */
-               outsize = set_message(outbuf,0,0,True);
+               outsize = set_message(outbuf, 0, 0, True);
                show_msg(outbuf);
-               send_smb(Client,outbuf);
+               send_smb(Client, outbuf);
        }
 
        /* receive the rest of the trans packet */
-       while (pscnt < tpscnt || dscnt < tdscnt) {
+       while (pscnt < tpscnt || dscnt < tdscnt)
+       {
                BOOL ret;
-               int pcnt,poff,dcnt,doff,pdisp,ddisp;
-      
-               ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+               int pcnt, poff, dcnt, doff, pdisp, ddisp;
+
+               ret = receive_next_smb(inbuf, bufsize, SMB_SECONDARY_WAIT);
 
                show_msg(inbuf);
-      
+
                if ((ret && (CVAL(inbuf, smb_com) != SMBtrans &&
-                             CVAL(inbuf, smb_com) != SMBtranss)) || !ret)
+                            CVAL(inbuf, smb_com) != SMBtranss)) || !ret)
                {
-                       if(ret) {
-                               DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
-                       } else {
-                               DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
-                                        (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+                       if (ret)
+                       {
+                               DEBUG(0,
+                                     ("reply_trans: Invalid secondary trans packet\n"));
                        }
-                       if (params) free(params);
-                       if (data) free(data);
-                       if (setup) free(setup);
-                       return(ERROR(ERRSRV,ERRerror));
+                       else
+                       {
+                               DEBUG(0,
+                                     ("reply_trans: %s in getting secondary trans response.\n",
+                                      (smb_read_error ==
+                                       READ_ERROR) ? "error" : "timeout"));
+                       }
+                       if (params)
+                               free(params);
+                       if (data)
+                               free(data);
+                       if (setup)
+                               free(setup);
+                       return (ERROR(ERRSRV, ERRerror));
                }
 
-               tpscnt = SVAL(inbuf,smb_vwv0);
-               tdscnt = SVAL(inbuf,smb_vwv1);
-
-               pcnt = SVAL(inbuf,smb_vwv2);
-               poff = SVAL(inbuf,smb_vwv3);
-               pdisp = SVAL(inbuf,smb_vwv4);
-               
-               dcnt = SVAL(inbuf,smb_vwv5);
-               doff = SVAL(inbuf,smb_vwv6);
-               ddisp = SVAL(inbuf,smb_vwv7);
-               
+               tpscnt = SVAL(inbuf, smb_vwv0);
+               tdscnt = SVAL(inbuf, smb_vwv1);
+
+               pcnt = SVAL(inbuf, smb_vwv2);
+               poff = SVAL(inbuf, smb_vwv3);
+               pdisp = SVAL(inbuf, smb_vwv4);
+
+               dcnt = SVAL(inbuf, smb_vwv5);
+               doff = SVAL(inbuf, smb_vwv6);
+               ddisp = SVAL(inbuf, smb_vwv7);
+
                pscnt += pcnt;
                dscnt += dcnt;
-               
-               if (dscnt > tdscnt || pscnt > tpscnt) {
+
+               if (dscnt > tdscnt || pscnt > tpscnt)
+               {
                        exit_server("invalid trans parameters\n");
                }
-               
+
                if (pcnt)
-                       memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
+                       memcpy(params + pdisp, smb_base(inbuf) + poff, pcnt);
                if (dcnt)
-                       memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);      
+                       memcpy(data + ddisp, smb_base(inbuf) + doff, dcnt);
+       }
+
+
+       DEBUG(3, ("trans <%s> data=%d params=%d setup=%d\n",
+                 name, tdscnt, tpscnt, suwcnt));
+
+       /*
+        * WinCE wierdness....
+        */
+
+       if (name[0] == '\\' && (StrnCaseCmp(&name[1], local_machine,
+                                           strlen(local_machine)) == 0))
+       {
+               name_offset = strlen(local_machine) + 1;
        }
-       
-       
-       DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
-                name,tdscnt,tpscnt,suwcnt));
-       
-        /*
-         * WinCE wierdness....
-         */
-
-        if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine,
-                                strlen(local_machine)) == 0)) {
-          name_offset = strlen(local_machine)+1;
-        }
-
-       if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) {
-               DEBUG(5,("calling named_pipe\n"));
-               outsize = named_pipe(conn,vuid,outbuf,
-                                    name+name_offset+strlen("\\PIPE\\"),setup,data,params,
-                                    suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
-       } else {
-               DEBUG(3,("invalid pipe name\n"));
+
+       if (strncmp(&name[name_offset], "\\PIPE\\", strlen("\\PIPE\\")) == 0)
+       {
+               DEBUG(5, ("calling named_pipe\n"));
+               outsize = named_pipe(conn, vuid, outbuf,
+                                    name + name_offset + strlen("\\PIPE\\"),
+                                    setup, data, params, suwcnt, tdscnt,
+                                    tpscnt, msrcnt, mdrcnt, mprcnt);
+       }
+       else
+       {
+               DEBUG(3, ("invalid pipe name\n"));
                outsize = 0;
        }
 
-       
-       if (data) free(data);
-       if (params) free(params);
-       if (setup) free(setup);
-       
+
+       if (data)
+               free(data);
+       if (params)
+               free(params);
+       if (setup)
+               free(setup);
+
        if (close_on_completion)
-               close_cnum(conn,vuid);
+               close_cnum(conn, vuid);
 
        if (one_way)
-               return(-1);
-       
+               return (-1);
+
        if (outsize == 0)
-               return(ERROR(ERRSRV,ERRnosupport));
-       
-       return(outsize);
+               return (ERROR(ERRSRV, ERRnosupport));
+
+       return (outsize);
 }
index 0096499237b8952dff1e8ef5b2a92eb1a99d7641..6ffcb2bb56678e72882148cb226d06e42ea60a8b 100644 (file)
@@ -1,27 +1,27 @@
   /* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
-   Inter-process communication and named pipe handling
-   Copyright (C) Andrew Tridgell 1992-2000
-
-   SMB Version handling
-   Copyright (C) John H Terpstra 1995-2000
-
-   Copyright (C) Luke Kenneth Casson Leighton 1996-2000
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 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.
+     Unix SMB/Netbios implementation.
+     Version 1.9.
+     Inter-process communication and named pipe handling
+     Copyright (C) Andrew Tridgell 1992-2000
+
+     SMB Version handling
+     Copyright (C) John H Terpstra 1995-2000
+
+     Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 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 file handles the named pipe and mailslot calls
@@ -37,6 +37,7 @@
 #define CHECK_TYPES 0
 
 extern int DEBUGLEVEL;
+extern int max_send;
 
 extern fstring local_machine;
 extern fstring global_myworkgroup;
@@ -63,280 +64,316 @@ extern fstring global_sam_name;
 
 extern int Client;
 extern int smb_read_error;
-extern uint32 global_client_caps;
 
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
-                           int mdrcnt,int mprcnt,
-                           char **rdata,char **rparam,
-                           int *rdata_len,int *rparam_len);
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
-                        int mdrcnt,int mprcnt,
-                        char **rdata,char **rparam,
-                        int *rdata_len,int *rparam_len);
+static BOOL api_Unsupported(connection_struct * conn, uint16 vuid,
+                           char *param, char *data, int mdrcnt, int mprcnt,
+                           char **rdata, char **rparam, int *rdata_len,
+                           int *rparam_len);
+static BOOL api_TooSmall(connection_struct * conn, uint16 vuid, char *param,
+                        char *data, int mdrcnt, int mprcnt, char **rdata,
+                        char **rparam, int *rdata_len, int *rparam_len);
 
 
-static int CopyExpanded(connection_struct *conn,  const vuser_key *key,
-                       int snum, char** dst, char* src, int* n)
+static int CopyExpanded(connection_struct * conn, const vuser_key * key,
+                       int snum, char **dst, char *src, int *n)
 {
        pstring buf;
        int l;
        user_struct *vuser;
 
-       if (!src || !dst || !n || !(*dst)) return(0);
+       if (!src || !dst || !n || !(*dst))
+               return (0);
 
-       StrnCpy(buf,src,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       StrnCpy(buf, src, sizeof(buf) / 2);
+       pstring_sub(buf, "%S", lp_servicename(snum));
        vuser = get_valid_user_struct(key);
-       standard_sub(conn,vuser, buf);
+       standard_sub(conn, vuser, buf);
        vuid_free_user_struct(vuser);
-       StrnCpy(*dst,buf,*n);
+       StrnCpy(*dst, buf, *n);
        l = strlen(*dst) + 1;
        (*dst) += l;
        (*n) -= l;
        return l;
 }
 
-static int CopyAndAdvance(char** dst, char* src, int* n)
+static int CopyAndAdvance(char **dst, char *src, int *n)
 {
-  int l;
-  if (!src || !dst || !n || !(*dst)) return(0);
-  StrnCpy(*dst,src,*n);
-  l = strlen(*dst) + 1;
-  (*dst) += l;
-  (*n) -= l;
-  return l;
+       int l;
+       if (!src || !dst || !n || !(*dst))
+               return (0);
+       StrnCpy(*dst, src, *n - 1);
+       l = strlen(*dst) + 1;
+       (*dst) += l;
+       (*n) -= l;
+       return l;
 }
 
-static int StrlenExpanded(connection_struct *conn,
-                               const vuser_key *key, int snum, char* s)
+static int StrlenExpanded(connection_struct * conn,
+                         const vuser_key * key, int snum, char *s)
 {
        user_struct *vuser;
        pstring buf;
-       if (!s) return(0);
-       StrnCpy(buf,s,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       if (!s)
+               return (0);
+       StrnCpy(buf, s, sizeof(buf) / 2);
+       pstring_sub(buf, "%S", lp_servicename(snum));
        vuser = get_valid_user_struct(key);
-       standard_sub(conn,vuser, buf);
+       standard_sub(conn, vuser, buf);
        vuid_free_user_struct(vuser);
        return strlen(buf) + 1;
 }
 
-static char* Expand(connection_struct *conn, const vuser_key *key, int snum, char* s)
+static char *Expand(connection_struct * conn, const vuser_key * key, int snum,
+                   char *s)
 {
        user_struct *vuser;
        static pstring buf;
-       if (!s) return(NULL);
-       StrnCpy(buf,s,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       if (!s)
+               return (NULL);
+       StrnCpy(buf, s, sizeof(buf) / 2);
+       pstring_sub(buf, "%S", lp_servicename(snum));
        vuser = get_valid_user_struct(key);
-       standard_sub(conn,vuser, buf);
+       standard_sub(conn, vuser, buf);
        return &buf[0];
 }
 
 /*******************************************************************
   check a API string for validity when we only need to check the prefix
   ******************************************************************/
-static BOOL prefix_ok(char *str,char *prefix)
+static BOOL prefix_ok(char *str, char *prefix)
 {
-  return(strncmp(str,prefix,strlen(prefix)) == 0);
+       return (strncmp(str, prefix, strlen(prefix)) == 0);
 }
 
-struct pack_desc {
-  char* format;            /* formatstring for structure */
-  char* subformat;  /* subformat for structure */
-  char* base;      /* baseaddress of buffer */
-  int buflen;     /* remaining size for fixed part; on init: length of base */
-  int subcount;            /* count of substructures */
-  char* structbuf;  /* pointer into buffer for remaining fixed part */
-  int stringlen;    /* remaining size for variable part */             
-  char* stringbuf;  /* pointer into buffer for remaining variable part */
-  int neededlen;    /* total needed size */
-  int usedlen;     /* total used size (usedlen <= neededlen and usedlen <= buflen) */
-  char* curpos;            /* current position; pointer into format or subformat */
-  int errcode;
+struct pack_desc
+{
+       char *format;           /* formatstring for structure */
+       char *subformat;        /* subformat for structure */
+       char *base;             /* baseaddress of buffer */
+       int buflen;             /* remaining size for fixed part; on init: length of base */
+       int subcount;           /* count of substructures */
+       char *structbuf;        /* pointer into buffer for remaining fixed part */
+       int stringlen;          /* remaining size for variable part */
+       char *stringbuf;        /* pointer into buffer for remaining variable part */
+       int neededlen;          /* total needed size */
+       int usedlen;            /* total used size (usedlen <= neededlen and usedlen <= buflen) */
+       char *curpos;           /* current position; pointer into format or subformat */
+       int errcode;
 };
 
-static int get_counter(char** p)
+static int get_counter(char **p)
 {
-  int i, n;
-  if (!p || !(*p)) return(1);
-  if (!isdigit((int)**p)) return 1;
-  for (n = 0;;) {
-    i = **p;
-    if (isdigit(i))
-      n = 10 * n + (i - '0');
-    else
-      return n;
-    (*p)++;
-  }
+       int i, n;
+       if (!p || !(*p))
+               return (1);
+       if (!isdigit((int)**p))
+               return 1;
+       for (n = 0;;)
+       {
+               i = **p;
+               if (isdigit(i))
+                       n = 10 * n + (i - '0');
+               else
+                       return n;
+               (*p)++;
+       }
 }
 
-static int getlen(charp)
+static int getlen(char *p)
 {
-  int n = 0;
-  if (!p) return(0);
-  while (*p) {
-    switch( *p++ ) {
-    case 'W':                  /* word (2 byte) */
-      n += 2;
-      break;
-    case 'N':                  /* count of substructures (word) at end */
-      n += 2;
-      break;
-    case 'D':                  /* double word (4 byte) */
-    case 'z':                  /* offset to zero terminated string (4 byte) */
-    case 'l':                  /* offset to user data (4 byte) */
-      n += 4;
-      break;
-    case 'b':                  /* offset to data (with counter) (4 byte) */
-      n += 4;
-      get_counter(&p);
-      break;
-    case 'B':                  /* byte (with optional counter) */
-      n += get_counter(&p);
-      break;
-    }
-  }
-  return n;
+       int n = 0;
+       if (!p)
+               return (0);
+       while (*p)
+       {
+               switch (*p++)
+               {
+                       case 'W':       /* word (2 byte) */
+                               n += 2;
+                               break;
+                       case 'N':       /* count of substructures (word) at end */
+                               n += 2;
+                               break;
+                       case 'D':       /* double word (4 byte) */
+                       case 'z':       /* offset to zero terminated string (4 byte) */
+                       case 'l':       /* offset to user data (4 byte) */
+                               n += 4;
+                               break;
+                       case 'b':       /* offset to data (with counter) (4 byte) */
+                               n += 4;
+                               get_counter(&p);
+                               break;
+                       case 'B':       /* byte (with optional counter) */
+                               n += get_counter(&p);
+                               break;
+               }
+       }
+       return n;
 }
 
-static BOOL init_package(struct pack_descp, int count, int subcount)
+static BOOL init_package(struct pack_desc *p, int count, int subcount)
 {
-  int n = p->buflen;
-  int i;
-
-  if (!p->format || !p->base) return(False);
-
-  i = count * getlen(p->format);
-  if (p->subformat) i += subcount * getlen(p->subformat);
-  p->structbuf = p->base;
-  p->neededlen = 0;
-  p->usedlen = 0;
-  p->subcount = 0;
-  p->curpos = p->format;
-  if (i > n) {
-    p->neededlen = i;
-    i = n = 0;
-    p->errcode = ERRmoredata;
-  }
-  else
-    p->errcode = NERR_Success;
-  p->buflen = i;
-  n -= i;
-  p->stringbuf = p->base + i;
-  p->stringlen = n;
-  return(p->errcode == NERR_Success);
+       int n = p->buflen;
+       int i;
+
+       if (!p->format || !p->base)
+               return (False);
+
+       i = count * getlen(p->format);
+       if (p->subformat)
+               i += subcount * getlen(p->subformat);
+       p->structbuf = p->base;
+       p->neededlen = 0;
+       p->usedlen = 0;
+       p->subcount = 0;
+       p->curpos = p->format;
+       if (i > n)
+       {
+               p->neededlen = i;
+               i = n = 0;
+               p->errcode = ERRmoredata;
+       }
+       else
+               p->errcode = NERR_Success;
+       p->buflen = i;
+       n -= i;
+       p->stringbuf = p->base + i;
+       p->stringlen = n;
+       return (p->errcode == NERR_Success);
 }
 
 #ifdef HAVE_STDARG_H
-static int package(struct pack_descp, ...)
+static int package(struct pack_desc *p, ...)
 {
 #else
 static int package(va_alist)
-va_dcl
+     va_dcl
 {
-  struct pack_desc* p;
+       struct pack_desc *p;
 #endif
-  va_list args;
-  int needed=0, stringneeded;
-  char* str=NULL;
-  int is_string=0, stringused;
-  int32 temp;
+       va_list args;
+       int needed = 0, stringneeded;
+       char *str = NULL;
+       int is_string = 0, stringused;
+       int32 temp;
 
 #ifdef HAVE_STDARG_H
-  va_start(args,p);
+       va_start(args, p);
 #else
-  va_start(args);
-  p = va_arg(args,struct pack_desc *);
+       va_start(args);
+       p = va_arg(args, struct pack_desc *);
 #endif
 
-  if (!*p->curpos) {
-    if (!p->subcount)
-      p->curpos = p->format;
-    else {
-      p->curpos = p->subformat;
-      p->subcount--;
-    }
-  }
+       if (!*p->curpos)
+       {
+               if (!p->subcount)
+                       p->curpos = p->format;
+               else
+               {
+                       p->curpos = p->subformat;
+                       p->subcount--;
+               }
+       }
 #if CHECK_TYPES
-  str = va_arg(args,char*);
-  SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
+       str = va_arg(args, char *);
+       SMB_ASSERT(strncmp(str, p->curpos, strlen(str)) == 0);
 #endif
-  stringneeded = -1;
-
-  if (!p->curpos) return(0);
-
-  switch( *p->curpos++ ) {
-  case 'W':                    /* word (2 byte) */
-    needed = 2;
-    temp = va_arg(args,int);
-    if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
-    break;
-  case 'N':                    /* count of substructures (word) at end */
-    needed = 2;
-    p->subcount = va_arg(args,int);
-    if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
-    break;
-  case 'D':                    /* double word (4 byte) */
-    needed = 4;
-    temp = va_arg(args,int);
-    if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
-    break;
-  case 'B':                    /* byte (with optional counter) */
-    needed = get_counter(&p->curpos);
-    {
-      char *s = va_arg(args,char*);
-      if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
-    }
-    break;
-  case 'z':                    /* offset to zero terminated string (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = (str ? strlen(str)+1 : 0);
-    is_string = 1;
-    break;
-  case 'l':                    /* offset to user data (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = va_arg(args,int);
-    is_string = 0;
-    break;
-  case 'b':                    /* offset to data (with counter) (4 byte) */
-    str = va_arg(args,char*);
-    stringneeded = get_counter(&p->curpos);
-    is_string = 0;
-    break;
-  }
-  va_end(args);
-  if (stringneeded >= 0) {
-    needed = 4;
-    if (p->buflen >= needed) {
-      stringused = stringneeded;
-      if (stringused > p->stringlen) {
-       stringused = (is_string ? p->stringlen : 0);
-       if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
-      }
-      if (!stringused)
-       SIVAL(p->structbuf,0,0);
-      else {
-       SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
-       memcpy(p->stringbuf,str?str:"",stringused);
-       if (is_string) p->stringbuf[stringused-1] = '\0';
-       p->stringbuf += stringused;
-       p->stringlen -= stringused;
-       p->usedlen += stringused;
-      }
-    }
-    p->neededlen += stringneeded;
-  }
-  p->neededlen += needed;
-  if (p->buflen >= needed) {
-    p->structbuf += needed;
-    p->buflen -= needed;
-    p->usedlen += needed;
-  }
-  else {
-    if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
-  }
-  return 1;
+       stringneeded = -1;
+
+       if (!p->curpos)
+       {
+               va_end(args);
+               return (0);
+       }
+
+       switch (*p->curpos++)
+       {
+               case 'W':       /* word (2 byte) */
+                       needed = 2;
+                       temp = va_arg(args, int);
+                       if (p->buflen >= needed)
+                               SSVAL(p->structbuf, 0, temp);
+                       break;
+               case 'N':       /* count of substructures (word) at end */
+                       needed = 2;
+                       p->subcount = va_arg(args, int);
+                       if (p->buflen >= needed)
+                               SSVAL(p->structbuf, 0, p->subcount);
+                       break;
+               case 'D':       /* double word (4 byte) */
+                       needed = 4;
+                       temp = va_arg(args, int);
+                       if (p->buflen >= needed)
+                               SIVAL(p->structbuf, 0, temp);
+                       break;
+               case 'B':       /* byte (with optional counter) */
+                       needed = get_counter(&p->curpos);
+                       {
+                               char *s = va_arg(args, char *);
+                               if (p->buflen >= needed)
+                                       StrnCpy(p->structbuf, s ? s : "",
+                                               needed - 1);
+                       }
+                       break;
+               case 'z':       /* offset to zero terminated string (4 byte) */
+                       str = va_arg(args, char *);
+                       stringneeded = (str ? strlen(str) + 1 : 0);
+                       is_string = 1;
+                       break;
+               case 'l':       /* offset to user data (4 byte) */
+                       str = va_arg(args, char *);
+                       stringneeded = va_arg(args, int);
+                       is_string = 0;
+                       break;
+               case 'b':       /* offset to data (with counter) (4 byte) */
+                       str = va_arg(args, char *);
+                       stringneeded = get_counter(&p->curpos);
+                       is_string = 0;
+                       break;
+       }
+       va_end(args);
+       if (stringneeded >= 0)
+       {
+               needed = 4;
+               if (p->buflen >= needed)
+               {
+                       stringused = stringneeded;
+                       if (stringused > p->stringlen)
+                       {
+                               stringused = (is_string ? p->stringlen : 0);
+                               if (p->errcode == NERR_Success)
+                                       p->errcode = ERRmoredata;
+                       }
+                       if (!stringused)
+                               SIVAL(p->structbuf, 0, 0);
+                       else
+                       {
+                               SIVAL(p->structbuf, 0,
+                                     PTR_DIFF(p->stringbuf, p->base));
+                               memcpy(p->stringbuf, str ? str : "",
+                                      stringused);
+                               if (is_string)
+                                       p->stringbuf[stringused - 1] = '\0';
+                               p->stringbuf += stringused;
+                               p->stringlen -= stringused;
+                               p->usedlen += stringused;
+                       }
+               }
+               p->neededlen += stringneeded;
+       }
+       p->neededlen += needed;
+       if (p->buflen >= needed)
+       {
+               p->structbuf += needed;
+               p->buflen -= needed;
+               p->usedlen += needed;
+       }
+       else
+       {
+               if (p->errcode == NERR_Success)
+                       p->errcode = ERRmoredata;
+       }
+       return 1;
 }
 
 #if CHECK_TYPES
@@ -347,14 +384,14 @@ va_dcl
 #define PACKl(desc,t,v,l) package(desc,v,l)
 #endif
 
-static void PACKI(struct pack_desc* desc,char *t,int v)
+static void PACKI(struct pack_desc *desc, char *t, int v)
 {
-  PACK(desc,t,v);
+       PACK(desc, t, v);
 }
 
-static void PACKS(struct pack_desc* desc,char *t,char *v)
+static void PACKS(struct pack_desc *desc, char *t, char *v)
 {
-  PACK(desc,t,v);
+       PACK(desc, t, v);
 }
 
 
@@ -362,538 +399,670 @@ static void PACKS(struct pack_desc* desc,char *t,char *v)
   get a print queue
   ****************************************************************************/
 
-static void PackDriverData(struct pack_descdesc)
+static void PackDriverData(struct pack_desc *desc)
 {
-  char drivdata[4+4+32];
-  SIVAL(drivdata,0,sizeof drivdata); /* cb */
-  SIVAL(drivdata,4,1000);      /* lVersion */
-  memset(drivdata+8,0,32);     /* szDeviceName */
-  pstrcpy(drivdata+8,"NULL");
-  PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
+       char drivdata[4 + 4 + 32];
+       SIVAL(drivdata, 0, sizeof drivdata);    /* cb */
+       SIVAL(drivdata, 4, 1000);       /* lVersion */
+       memset(drivdata + 8, 0, 32);    /* szDeviceName */
+       pstrcpy(drivdata + 8, "NULL");
+       PACKl(desc, "l", drivdata, sizeof drivdata);    /* pDriverData */
 }
 
-static int check_printq_info(struct pack_descdesc,
-                            int uLevel, char *id1, char *id2)
+static int check_printq_info(struct pack_desc *desc,
+                            int uLevel, char *id1, char *id2)
 {
-  desc->subformat = NULL;
-  switch( uLevel ) {
-  case 0:
-    desc->format = "B13";
-    break;
-  case 1:
-    desc->format = "B13BWWWzzzzzWW";
-    break;
-  case 2:
-    desc->format = "B13BWWWzzzzzWN";
-    desc->subformat = "WB21BB16B10zWWzDDz";
-    break;
-  case 3:
-    desc->format = "zWWWWzzzzWWzzl";
-    break;
-  case 4:
-    desc->format = "zWWWWzzzzWNzzl";
-    desc->subformat = "WWzWWDDzz";
-    break;
-  case 5:
-    desc->format = "z";
-    break;
-  case 52:
-    desc->format = "WzzzzzzzzN";
-    desc->subformat = "z";
-    break;
-  default: return False;
-  }
-  if (strcmp(desc->format,id1) != 0) return False;
-  if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
-  return True;
+       desc->subformat = NULL;
+       switch (uLevel)
+       {
+               case 0:
+                       desc->format = "B13";
+                       break;
+               case 1:
+                       desc->format = "B13BWWWzzzzzWW";
+                       break;
+               case 2:
+                       desc->format = "B13BWWWzzzzzWN";
+                       desc->subformat = "WB21BB16B10zWWzDDz";
+                       break;
+               case 3:
+                       desc->format = "zWWWWzzzzWWzzl";
+                       break;
+               case 4:
+                       desc->format = "zWWWWzzzzWNzzl";
+                       desc->subformat = "WWzWWDDzz";
+                       break;
+               case 5:
+                       desc->format = "z";
+                       break;
+               case 52:
+                       desc->format = "WzzzzzzzzN";
+                       desc->subformat = "z";
+                       break;
+               default:
+                       return False;
+       }
+       if (strcmp(desc->format, id1) != 0)
+               return False;
+       if (desc->subformat && strcmp(desc->subformat, id2) != 0)
+               return False;
+       return True;
 }
 
-static void fill_printjob_info(connection_struct *conn, 
-                               int snum, int uLevel,
-                              struct pack_desc* desc,
-                              print_queue_struct* queue, int n)
+static void fill_printjob_info(connection_struct * conn, int snum, int uLevel,
+                              struct pack_desc *desc,
+                              print_queue_struct * queue, int n)
 {
-  time_t t = queue->time;
-
-  /* the client expects localtime */
-  t -= TimeDiff(t);
-
-  PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
-  if (uLevel == 1) {
-    PACKS(desc,"B21",queue->user); /* szUserName */
-    PACKS(desc,"B","");                /* pad */
-    PACKS(desc,"B16","");      /* szNotifyName */
-    PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
-    PACKS(desc,"z","");                /* pszParms */
-    PACKI(desc,"W",n+1);               /* uPosition */
-    PACKI(desc,"W",queue->status); /* fsStatus */
-    PACKS(desc,"z","");                /* pszStatus */
-    PACKI(desc,"D",t); /* ulSubmitted */
-    PACKI(desc,"D",queue->size); /* ulSize */
-    PACKS(desc,"z",queue->file); /* pszComment */
-  }
-  if (uLevel == 2 || uLevel == 3) {
-    PACKI(desc,"W",queue->priority);           /* uPriority */
-    PACKS(desc,"z",queue->user); /* pszUserName */
-    PACKI(desc,"W",n+1);               /* uPosition */
-    PACKI(desc,"W",queue->status); /* fsStatus */
-    PACKI(desc,"D",t); /* ulSubmitted */
-    PACKI(desc,"D",queue->size); /* ulSize */
-    PACKS(desc,"z","Samba");   /* pszComment */
-    PACKS(desc,"z",queue->file); /* pszDocument */
-    if (uLevel == 3) {
-      PACKS(desc,"z","");      /* pszNotifyName */
-      PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
-      PACKS(desc,"z","");      /* pszParms */
-      PACKS(desc,"z","");      /* pszStatus */
-      PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
-      PACKS(desc,"z","lpd");   /* pszQProcName */
-      PACKS(desc,"z","");      /* pszQProcParms */
-      PACKS(desc,"z","NULL"); /* pszDriverName */
-      PackDriverData(desc);    /* pDriverData */
-      PACKS(desc,"z","");      /* pszPrinterName */
-    }
-  }
+       time_t t = queue->time;
+
+       /* the client expects localtime */
+       t -= TimeDiff(t);
+
+       PACKI(desc, "W", printjob_encode(snum, queue->job));    /* uJobId */
+       if (uLevel == 1)
+       {
+               PACKS(desc, "B21", queue->user);        /* szUserName */
+               PACKS(desc, "B", "");   /* pad */
+               PACKS(desc, "B16", ""); /* szNotifyName */
+               PACKS(desc, "B10", "PM_Q_RAW"); /* szDataType */
+               PACKS(desc, "z", "");   /* pszParms */
+               PACKI(desc, "W", n + 1);        /* uPosition */
+               PACKI(desc, "W", queue->status);        /* fsStatus */
+               PACKS(desc, "z", "");   /* pszStatus */
+               PACKI(desc, "D", t);    /* ulSubmitted */
+               PACKI(desc, "D", queue->size);  /* ulSize */
+               PACKS(desc, "z", queue->file);  /* pszComment */
+       }
+       if (uLevel == 2 || uLevel == 3)
+       {
+               PACKI(desc, "W", queue->priority);      /* uPriority */
+               PACKS(desc, "z", queue->user);  /* pszUserName */
+               PACKI(desc, "W", n + 1);        /* uPosition */
+               PACKI(desc, "W", queue->status);        /* fsStatus */
+               PACKI(desc, "D", t);    /* ulSubmitted */
+               PACKI(desc, "D", queue->size);  /* ulSize */
+               PACKS(desc, "z", "Samba");      /* pszComment */
+               PACKS(desc, "z", queue->file);  /* pszDocument */
+               if (uLevel == 3)
+               {
+                       PACKS(desc, "z", "");   /* pszNotifyName */
+                       PACKS(desc, "z", "PM_Q_RAW");   /* pszDataType */
+                       PACKS(desc, "z", "");   /* pszParms */
+                       PACKS(desc, "z", "");   /* pszStatus */
+                       PACKS(desc, "z", SERVICE(snum));        /* pszQueue */
+                       PACKS(desc, "z", "lpd");        /* pszQProcName */
+                       PACKS(desc, "z", "");   /* pszQProcParms */
+                       PACKS(desc, "z", "NULL");       /* pszDriverName */
+                       PackDriverData(desc);   /* pDriverData */
+                       PACKS(desc, "z", "");   /* pszPrinterName */
+               }
+       }
 }
 
-static void fill_printq_info(connection_struct *conn, const vuser_key *key,
-                               int snum, int uLevel,
-                            struct pack_desc* desc,
-                            int count, print_queue_struct* queue,
-                            print_status_struct* status)
+static void fill_printq_info(connection_struct * conn, const vuser_key * key,
+                            int snum, int uLevel, struct pack_desc *desc,
+                            int count, print_queue_struct * queue,
+                            print_status_struct * status)
 {
-  switch (uLevel) {
-    case 1:
-    case 2:
-      PACKS(desc,"B13",SERVICE(snum));
-      break;
-    case 3:
-    case 4:
-    case 5:
-      PACKS(desc,"z",Expand(conn,key, snum,SERVICE(snum)));
-      break;
-  }
-
-  if (uLevel == 1 || uLevel == 2) {
-    PACKS(desc,"B","");                /* alignment */
-    PACKI(desc,"W",5);         /* priority */
-    PACKI(desc,"W",0);         /* start time */
-    PACKI(desc,"W",0);         /* until time */
-    PACKS(desc,"z","");                /* pSepFile */
-    PACKS(desc,"z","lpd");     /* pPrProc */
-    PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
-    PACKS(desc,"z","");                /* pParms */
-    if (snum < 0) {
-      PACKS(desc,"z","UNKNOWN PRINTER");
-      PACKI(desc,"W",LPSTAT_ERROR);
-    }
-    else if (!status || !status->message[0]) {
-      PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum)));
-      PACKI(desc,"W",LPSTAT_OK); /* status */
-    } else {
-      PACKS(desc,"z",status->message);
-      PACKI(desc,"W",status->status); /* status */
-    }
-    PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
-  }
-  if (uLevel == 3 || uLevel == 4) {
-    PACKI(desc,"W",5);         /* uPriority */
-    PACKI(desc,"W",0);         /* uStarttime */
-    PACKI(desc,"W",0);         /* uUntiltime */
-    PACKI(desc,"W",5);         /* pad1 */
-    PACKS(desc,"z","");                /* pszSepFile */
-    PACKS(desc,"z","WinPrint");        /* pszPrProc */
-    PACKS(desc,"z","");                /* pszParms */
-    if (!status || !status->message[0]) {
-      PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum))); /* pszComment */
-      PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
-    } else {
-      PACKS(desc,"z",status->message); /* pszComment */
-      PACKI(desc,"W",status->status); /* fsStatus */
-    }
-    PACKI(desc,(uLevel == 3 ? "W" : "N"),count);       /* cJobs */
-    PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
-    PACKS(desc,"z",lp_printerdriver(snum));            /* pszDriverName */
-    PackDriverData(desc);      /* pDriverData */
-  }
-  if (uLevel == 2 || uLevel == 4) {
-    int i;
-    for (i=0;i<count;i++)
-      fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
-  }
-
-  if (uLevel==52) {
-    int i,ok=0;
-    pstring tok,driver,datafile,langmon,helpfile,datatype;
-    char *p,*q;
-    FILE *f;
-    pstring fname;
-
-    pstrcpy(fname,lp_driverfile());
-    f=sys_fopen(fname,"r");
-    if (!f) {
-      DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
-      desc->errcode=NERR_notsupported;
-      return;
-    }
-
-    if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
-      DEBUG(0,("fill_printq_info: malloc fail !\n"));
-      desc->errcode=NERR_notsupported;
-      fclose(f);
-      return;
-    }
-
-    memset(p, 0,  8192*sizeof(char));
-    q=p;
-
-    /* lookup the long printer driver name in the file description */
-    while (f && !feof(f) && !ok)
-    {
-      p = q;                   /* reset string pointer */
-      fgets(p,8191,f);
-      p[strlen(p)-1]='\0';
-      if (next_token(&p,tok,":",sizeof(tok)) &&
-        (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
-        (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
-       ok=1;
-    }
-    fclose(f);
-
-    /* driver file name */
-    if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
-    /* data file name */
-    if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
-      /*
-       * for the next tokens - which may be empty - I have to check for empty
-       * tokens first because the next_token function will skip all empty
-       * token fields 
-       */
-    if (ok) {
-      /* help file */
-      if (*p == ':') {
-         *helpfile = '\0';
-         p++;
-      } else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
-    }
-
-    if (ok) {
-      /* language monitor */
-      if (*p == ':') {
-         *langmon = '\0';
-         p++;
-      } else if (!next_token(&p,langmon,":",sizeof(langmon))) ok = 0;
-    }
-
-    /* default data type */
-    if (ok && !next_token(&p,datatype,":",sizeof(datatype))) ok = 0;
-
-    if (ok) {
-      PACKI(desc,"W",0x0400);                    /* don't know */
-      PACKS(desc,"z",lp_printerdriver(snum));    /* long printer name */
-      PACKS(desc,"z",driver);                    /* Driverfile Name */
-      PACKS(desc,"z",datafile);                  /* Datafile name */
-      PACKS(desc,"z",langmon);                  /* language monitor */
-      PACKS(desc,"z",lp_driverlocation(snum));   /* share to retrieve files */
-      PACKS(desc,"z",datatype);                         /* default data type */
-      PACKS(desc,"z",helpfile);                  /* helpfile name */
-      PACKS(desc,"z",driver);                    /* driver name */
-      DEBUG(3,("Driver:%s:\n",driver));
-      DEBUG(3,("Data File:%s:\n",datafile));
-      DEBUG(3,("Language Monitor:%s:\n",langmon));
-      DEBUG(3,("Data Type:%s:\n",datatype));
-      DEBUG(3,("Help File:%s:\n",helpfile));
-      PACKI(desc,"N",count);                     /* number of files to copy */
-      for (i=0;i<count;i++)
-      {
-       /* no need to check return value here - it was already tested in
-        * get_printerdrivernumber
-        */
-        next_token(&p,tok,",",sizeof(tok));
-        PACKS(desc,"z",tok);                        /* driver files to copy */
-        DEBUG(3,("file:%s:\n",tok));
-      }
-
-      DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
-           SERVICE(snum),count));
-    } else {
-      DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
-      desc->errcode=NERR_notsupported;
-    }
-    free(q);
-  }
+       switch (uLevel)
+       {
+               case 1:
+               case 2:
+                       PACKS(desc, "B13", SERVICE(snum));
+                       break;
+               case 3:
+               case 4:
+               case 5:
+                       PACKS(desc, "z",
+                             Expand(conn, key, snum, SERVICE(snum)));
+                       break;
+       }
+
+       if (uLevel == 1 || uLevel == 2)
+       {
+               PACKS(desc, "B", "");   /* alignment */
+               PACKI(desc, "W", 5);    /* priority */
+               PACKI(desc, "W", 0);    /* start time */
+               PACKI(desc, "W", 0);    /* until time */
+               PACKS(desc, "z", "");   /* pSepFile */
+               PACKS(desc, "z", "lpd");        /* pPrProc */
+               PACKS(desc, "z", SERVICE(snum));        /* pDestinations */
+               PACKS(desc, "z", "");   /* pParms */
+               if (snum < 0)
+               {
+                       PACKS(desc, "z", "UNKNOWN PRINTER");
+                       PACKI(desc, "W", LPSTAT_ERROR);
+               }
+               else if (!status || !status->message[0])
+               {
+                       PACKS(desc, "z",
+                             Expand(conn, key, snum, lp_comment(snum)));
+                       PACKI(desc, "W", LPSTAT_OK);    /* status */
+               }
+               else
+               {
+                       PACKS(desc, "z", status->message);
+                       PACKI(desc, "W", status->status);       /* status */
+               }
+               PACKI(desc, (uLevel == 1 ? "W" : "N"), count);
+       }
+       if (uLevel == 3 || uLevel == 4)
+       {
+               PACKI(desc, "W", 5);    /* uPriority */
+               PACKI(desc, "W", 0);    /* uStarttime */
+               PACKI(desc, "W", 0);    /* uUntiltime */
+               PACKI(desc, "W", 5);    /* pad1 */
+               PACKS(desc, "z", "");   /* pszSepFile */
+               PACKS(desc, "z", "WinPrint");   /* pszPrProc */
+               PACKS(desc, "z", "");   /* pszParms */
+               if (!status || !status->message[0])
+               {
+                       PACKS(desc, "z", Expand(conn, key, snum, lp_comment(snum)));    /* pszComment */
+                       PACKI(desc, "W", LPSTAT_OK);    /* fsStatus */
+               }
+               else
+               {
+                       PACKS(desc, "z", status->message);      /* pszComment */
+                       PACKI(desc, "W", status->status);       /* fsStatus */
+               }
+               PACKI(desc, (uLevel == 3 ? "W" : "N"), count);  /* cJobs */
+               PACKS(desc, "z", SERVICE(snum));        /* pszPrinters */
+               PACKS(desc, "z", lp_printerdriver(snum));       /* pszDriverName */
+               PackDriverData(desc);   /* pDriverData */
+       }
+       if (uLevel == 2 || uLevel == 4)
+       {
+               int i;
+               for (i = 0; i < count; i++)
+                       fill_printjob_info(conn, snum, uLevel == 2 ? 1 : 2,
+                                          desc, &queue[i], i);
+       }
+
+       if (uLevel == 52)
+       {
+               int i, ok = 0;
+               pstring tok, driver, datafile, langmon, helpfile, datatype;
+               char *p, *q;
+               FILE *f;
+               pstring fname;
+
+               pstrcpy(fname, lp_driverfile());
+               f = sys_fopen(fname, "r");
+               if (!f)
+               {
+                       DEBUG(3,
+                             ("fill_printq_info: Can't open %s - %s\n",
+                              fname, strerror(errno)));
+                       desc->errcode = NERR_notsupported;
+                       return;
+               }
+
+               if ((p = (char *)malloc(8192 * sizeof(char))) == NULL)
+               {
+                       DEBUG(0, ("fill_printq_info: malloc fail !\n"));
+                       desc->errcode = NERR_notsupported;
+                       fclose(f);
+                       return;
+               }
+
+               memset(p, 0, 8192 * sizeof(char));
+               q = p;
+
+               /* lookup the long printer driver name in the file description */
+               while (f && !feof(f) && !ok)
+               {
+                       p = q;  /* reset string pointer */
+                       fgets(p, 8191, f);
+                       p[strlen(p) - 1] = '\0';
+                       if (next_token(&p, tok, ":", sizeof(tok)) &&
+                           (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
+                           (!strncmp(tok, lp_printerdriver(snum),
+                                     strlen(lp_printerdriver(snum)))))
+                               ok = 1;
+               }
+               fclose(f);
+
+               /* driver file name */
+               if (ok && !next_token(&p, driver, ":", sizeof(driver)))
+                       ok = 0;
+               /* data file name */
+               if (ok && !next_token(&p, datafile, ":", sizeof(datafile)))
+                       ok = 0;
+               /*
+                * for the next tokens - which may be empty - I have to check for empty
+                * tokens first because the next_token function will skip all empty
+                * token fields 
+                */
+               if (ok)
+               {
+                       /* help file */
+                       if (*p == ':')
+                       {
+                               *helpfile = '\0';
+                               p++;
+                       }
+                       else
+                               if (!next_token
+                                   (&p, helpfile, ":",
+                                    sizeof(helpfile))) ok = 0;
+               }
+
+               if (ok)
+               {
+                       /* language monitor */
+                       if (*p == ':')
+                       {
+                               *langmon = '\0';
+                               p++;
+                       }
+                       else
+                               if (!next_token
+                                   (&p, langmon, ":", sizeof(langmon))) ok =
+                                       0;
+               }
+
+               /* default data type */
+               if (ok && !next_token(&p, datatype, ":", sizeof(datatype)))
+                       ok = 0;
+
+               if (ok)
+               {
+                       PACKI(desc, "W", 0x0400);       /* don't know */
+                       PACKS(desc, "z", lp_printerdriver(snum));       /* long printer name */
+                       PACKS(desc, "z", driver);       /* Driverfile Name */
+                       PACKS(desc, "z", datafile);     /* Datafile name */
+                       PACKS(desc, "z", langmon);      /* language monitor */
+                       PACKS(desc, "z", lp_driverlocation(snum));      /* share to retrieve files */
+                       PACKS(desc, "z", datatype);     /* default data type */
+                       PACKS(desc, "z", helpfile);     /* helpfile name */
+                       PACKS(desc, "z", driver);       /* driver name */
+                       DEBUG(3, ("Driver:%s:\n", driver));
+                       DEBUG(3, ("Data File:%s:\n", datafile));
+                       DEBUG(3, ("Language Monitor:%s:\n", langmon));
+                       DEBUG(3, ("Data Type:%s:\n", datatype));
+                       DEBUG(3, ("Help File:%s:\n", helpfile));
+                       PACKI(desc, "N", count);        /* number of files to copy */
+                       for (i = 0; i < count; i++)
+                       {
+                               /* no need to check return value here - it was already tested in
+                                * get_printerdrivernumber
+                                */
+                               next_token(&p, tok, ",", sizeof(tok));
+                               PACKS(desc, "z", tok);  /* driver files to copy */
+                               DEBUG(3, ("file:%s:\n", tok));
+                       }
+
+                       DEBUG(3,
+                             ("fill_printq_info on <%s> gave %d entries\n",
+                              SERVICE(snum), count));
+               }
+               else
+               {
+                       DEBUG(3,
+                             ("fill_printq_info: Can't supply driver files\n"));
+                       desc->errcode = NERR_notsupported;
+               }
+               free(q);
+       }
 }
 
 /* This function returns the number of files for a given driver */
 static int get_printerdrivernumber(int snum)
 {
-  int i=0,ok=0;
-  pstring tok;
-  char *p,*q;
-  FILE *f;
-  pstring fname;
-
-  pstrcpy(fname,lp_driverfile());
-
-  DEBUG(4,("In get_printerdrivernumber: %s\n",fname));
-  f=sys_fopen(fname,"r");
-  if (!f) {
-    DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",fname,strerror(errno)));
-    return(0);
-  }
-
-  if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
-    DEBUG(3,("get_printerdrivernumber: malloc fail !\n"));
-    fclose(f);
-    return 0;
-  }
-
-  q=p; /* need it to free memory because p change ! */
-
-  /* lookup the long printer driver name in the file description */
-  while (!feof(f) && !ok)
-  {
-    p = q;                     /* reset string pointer */
-    fgets(p,8191,f);
-    if (next_token(&p,tok,":",sizeof(tok)) &&
-      (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum))))) 
-       ok=1;
-  }
-  fclose(f);
-
-  if (ok) {
-    /* skip 5 fields */
-    i = 5;
-    while (*p && i) {
-      if (*p++ == ':') i--;
-    }
-    if (!*p || i)
-      return(0);
-
-    /* count the number of files */
-    while (next_token(&p,tok,",",sizeof(tok)))
-       i++;
-  }
-  free(q);
-
-  return(i);
+       int i = 0, ok = 0;
+       pstring tok;
+       char *p, *q;
+       FILE *f;
+       pstring fname;
+
+       pstrcpy(fname, lp_driverfile());
+
+       DEBUG(4, ("In get_printerdrivernumber: %s\n", fname));
+       f = sys_fopen(fname, "r");
+       if (!f)
+       {
+               DEBUG(3,
+                     ("get_printerdrivernumber: Can't open %s - %s\n", fname,
+                      strerror(errno)));
+               return (0);
+       }
+
+       if ((p = (char *)malloc(8192 * sizeof(char))) == NULL)
+       {
+               DEBUG(3, ("get_printerdrivernumber: malloc fail !\n"));
+               fclose(f);
+               return 0;
+       }
+
+       q = p;                  /* need it to free memory because p change ! */
+
+       /* lookup the long printer driver name in the file description */
+       while (!feof(f) && !ok)
+       {
+               p = q;          /* reset string pointer */
+               fgets(p, 8191, f);
+               if (next_token(&p, tok, ":", sizeof(tok)) &&
+                   (!strncmp
+                    (tok, lp_printerdriver(snum),
+                     strlen(lp_printerdriver(snum)))))
+                       ok = 1;
+       }
+       fclose(f);
+
+       if (ok)
+       {
+               /* skip 5 fields */
+               i = 5;
+               while (*p && i)
+               {
+                       if (*p++ == ':')
+                               i--;
+               }
+               if (!*p || i)
+                       return (0);
+
+               /* count the number of files */
+               while (next_token(&p, tok, ",", sizeof(tok)))
+                       i++;
+       }
+       free(q);
+
+       return (i);
 }
 
-static BOOL api_DosPrintQGetInfo(connection_struct *conn,
-                                uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_DosPrintQGetInfo(connection_struct * conn,
+                                uint16 vuid, char *param, char *data,
+                                int mdrcnt, int mprcnt,
+                                char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  char *QueueName = p;
-  int uLevel;
-  int count=0;
-  int snum;
-  char* str3;
-  struct pack_desc desc;
-  print_queue_struct *queue=NULL;
-  print_status_struct status;
-
-  VUSER_KEY;
-  
-  ZERO_STRUCT(status);
-  ZERO_STRUCT(desc);
-  p = skip_string(p,1);
-  uLevel = SVAL(p,0);
-  str3 = p + 4;
-  /* remove any trailing username */
-  if ((p = strchr(QueueName,'%'))) *p = 0;
-  DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
-  /* check it's a supported varient */
-  if (!prefix_ok(str1,"zWrLh")) return False;
-  if (!check_printq_info(&desc,uLevel,str2,str3)) return False;
-  snum = lp_servicenumber(QueueName);
-  if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(QueueName,pnum);
-      snum = lp_servicenumber(QueueName);
-    }
-  }
-  
-  if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
-  if (uLevel==52) {
-         count = get_printerdrivernumber(snum);
-         DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
-  } else {
-         count = get_printqueue(snum, conn,&key,&queue,&status);
-  }
-
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  if (init_package(&desc,1,count)) {
-         desc.subcount = count;
-         fill_printq_info(conn,&key,snum,uLevel,&desc,count,queue,&status);
-  } else if (uLevel == 0) {
-       /*
-        * This is a *disgusting* hack.
-        * This is *so* bad that even I'm embarrassed (and I
-        * have no shame). Here's the deal :
-        * Until we get the correct SPOOLSS code into smbd
-        * then when we're running with NT SMB support then
-        * NT makes this call with a level of zero, and then
-        * immediately follows it with an open request to
-        * the \\SRVSVC pipe. If we allow that open to
-        * succeed then NT barfs when it cannot open the
-        * \\SPOOLSS pipe immediately after and continually
-        * whines saying "Printer name is invalid" forever
-        * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
-        * to fail, then NT downgrades to using the downlevel code
-        * and everything works as well as before. I hate
-        * myself for adding this code.... JRA.
-        */
-
-       fail_next_srvsvc_open();
-  }
-
-  *rdata_len = desc.usedlen;
-  
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,desc.neededlen);
-  
-  DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
-
-  if (queue) free(queue);
-  
-  return(True);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       char *QueueName = p;
+       int uLevel;
+       int count = 0;
+       int snum;
+       char *str3;
+       struct pack_desc desc;
+       print_queue_struct *queue = NULL;
+       print_status_struct status;
+
+       VUSER_KEY;
+
+       ZERO_STRUCT(status);
+       ZERO_STRUCT(desc);
+
+       p = skip_string(p, 1);
+       uLevel = SVAL(p, 0);
+       str3 = p + 4;
+
+       /* remove any trailing username */
+       if ((p = strchr(QueueName, '%')))
+               *p = 0;
+
+       DEBUG(3, ("PrintQueue uLevel=%d name=%s\n", uLevel, QueueName));
+
+       /* check it's a supported varient */
+       if (!prefix_ok(str1, "zWrLh"))
+               return False;
+       if (!check_printq_info(&desc, uLevel, str2, str3))
+       {
+               /*
+                * Patch from Scott Moomaw <scott@bridgewater.edu>
+                * to return the 'invalid info level' error if an
+                * unknown level was requested.
+                */
+               *rdata_len = 0;
+               *rparam_len = 6;
+               *rparam = REALLOC(*rparam, *rparam_len);
+               SSVALS(*rparam, 0, ERROR_INVALID_LEVEL);
+               SSVAL(*rparam, 2, 0);
+               SSVAL(*rparam, 4, 0);
+               return (True);
+       }
+
+       snum = lp_servicenumber(QueueName);
+       if (snum < 0 && pcap_printername_ok(QueueName, NULL))
+       {
+               int pnum = lp_servicenumber(PRINTERS_NAME);
+               if (pnum >= 0)
+               {
+                       lp_add_printer(QueueName, pnum);
+                       snum = lp_servicenumber(QueueName);
+               }
+       }
+
+       if (snum < 0 || !VALID_SNUM(snum))
+               return (False);
+
+       if (uLevel == 52)
+       {
+               count = get_printerdrivernumber(snum);
+               DEBUG(3,
+                     ("api_DosPrintQGetInfo: Driver files count: %d\n",
+                      count));
+       }
+       else
+       {
+               count = get_printqueue(snum, conn, &key, &queue, &status);
+       }
+
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       if (init_package(&desc, 1, count))
+       {
+               desc.subcount = count;
+               fill_printq_info(conn, &key, snum, uLevel, &desc, count,
+                                queue, &status);
+       }
+       else if (uLevel == 0)
+       {
+               /*
+                * This is a *disgusting* hack.
+                * This is *so* bad that even I'm embarrassed (and I
+                * have no shame). Here's the deal :
+                * Until we get the correct SPOOLSS code into smbd
+                * then when we're running with NT SMB support then
+                * NT makes this call with a level of zero, and then
+                * immediately follows it with an open request to
+                * the \\SRVSVC pipe. If we allow that open to
+                * succeed then NT barfs when it cannot open the
+                * \\SPOOLSS pipe immediately after and continually
+                * whines saying "Printer name is invalid" forever
+                * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
+                * to fail, then NT downgrades to using the downlevel code
+                * and everything works as well as before. I hate
+                * myself for adding this code.... JRA.
+                */
+
+               fail_next_srvsvc_open();
+       }
+
+       *rdata_len = desc.usedlen;
+
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, desc.neededlen);
+
+       DEBUG(4, ("printqgetinfo: errorcode %d\n", desc.errcode));
+
+       if (queue)
+               free(queue);
+
+       return (True);
 }
 
 
 /****************************************************************************
   view list of all print jobs on all queues
   ****************************************************************************/
-static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
-                             int mdrcnt, int mprcnt,
-                             char **rdata, char** rparam,
-                             int *rdata_len, int *rparam_len)
+static BOOL api_DosPrintQEnum(connection_struct * conn, uint16 vuid,
+                             char *param, char *data, int mdrcnt, int mprcnt,
+                             char **rdata, char **rparam, int *rdata_len,
+                             int *rparam_len)
 {
-  char *param_format = param+2;
-  char *output_format1 = skip_string(param_format,1);
-  char *p = skip_string(output_format1,1);
-  int uLevel = SVAL(p,0);
-  char *output_format2 = p + 4;
-  int services = lp_numservices();
-  int i, n;
-  struct pack_desc desc;
-  print_queue_struct **queue = NULL;
-  print_status_struct *status = NULL;
-  int* subcntarr = NULL;
-  int queuecnt, subcnt=0, succnt=0;
+       char *param_format = param + 2;
+       char *output_format1 = skip_string(param_format, 1);
+       char *p = skip_string(output_format1, 1);
+       int uLevel = SVAL(p, 0);
+       char *output_format2 = p + 4;
+       int services = lp_numservices();
+       int i, n;
+       struct pack_desc desc;
+       print_queue_struct **queue = NULL;
+       print_status_struct *status = NULL;
+       int *subcntarr = NULL;
+       int queuecnt, subcnt = 0, succnt = 0;
        VUSER_KEY;
-  ZERO_STRUCT(desc);
-
-  DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-  if (!prefix_ok(param_format,"WrLeh")) return False;
-  if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
-    return False;
-  queuecnt = 0;
-  for (i = 0; i < services; i++)
-    if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
-      queuecnt++;
-  if (uLevel > 0) {
-    if ((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    memset(queue,0,queuecnt*sizeof(print_queue_struct*));
-    if ((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    memset(status,0,queuecnt*sizeof(print_status_struct));
-    if ((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
-      DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
-      return False;
-    }
-    subcnt = 0;
-    n = 0;
-    for (i = 0; i < services; i++)
-      if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
-       subcntarr[n] = get_printqueue(i, conn, &key, &queue[n],&status[n]);
-       subcnt += subcntarr[n];
-       n++;
-      }
-  }
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-
-  if (init_package(&desc,queuecnt,subcnt)) {
-    n = 0;
-    succnt = 0;
-    for (i = 0; i < services; i++)
-      if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
-       fill_printq_info(conn,&key, i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
-       n++;
-       if (desc.errcode == NERR_Success) succnt = n;
-      }
-  }
-
-  if (subcntarr) free(subcntarr);
-  *rdata_len = desc.usedlen;
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,queuecnt);
-  
-  for (i = 0; i < queuecnt; i++) {
-    if (queue && queue[i]) free(queue[i]);
-  }
-
-  if (queue) free(queue);
-  if (status) free(status);
-  
-  return True;
+
+       ZERO_STRUCT(desc);
+
+       DEBUG(3, ("DosPrintQEnum uLevel=%d\n", uLevel));
+
+       if (!prefix_ok(param_format, "WrLeh"))
+               return False;
+       if (!check_printq_info(&desc, uLevel, output_format1, output_format2))
+       {
+               /*
+                * Patch from Scott Moomaw <scott@bridgewater.edu>
+                * to return the 'invalid info level' error if an
+                * unknown level was requested.
+                */
+               *rdata_len = 0;
+               *rparam_len = 6;
+               *rparam = REALLOC(*rparam, *rparam_len);
+               SSVALS(*rparam, 0, ERROR_INVALID_LEVEL);
+               SSVAL(*rparam, 2, 0);
+               SSVAL(*rparam, 4, 0);
+               return (True);
+       }
+
+       queuecnt = 0;
+       for (i = 0; i < services; i++)
+               if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+                       queuecnt++;
+       if (uLevel > 0)
+       {
+               if (
+                   (queue =
+                    (print_queue_struct **) malloc(queuecnt *
+                                                   sizeof(print_queue_struct
+                                                          *))) == NULL)
+               {
+                       DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+                       return False;
+               }
+               memset(queue, 0, queuecnt * sizeof(print_queue_struct *));
+               if (
+                   (status =
+                    (print_status_struct *) malloc(queuecnt *
+                                                   sizeof
+                                                   (print_status_struct))) ==
+                   NULL)
+               {
+                       DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+                       return False;
+               }
+               memset(status, 0, queuecnt * sizeof(print_status_struct));
+               if ((subcntarr = (int *)malloc(queuecnt * sizeof(int))) ==
+                   NULL)
+               {
+                       DEBUG(0, ("api_DosPrintQEnum: malloc fail !\n"));
+                       return False;
+               }
+               subcnt = 0;
+               n = 0;
+               for (i = 0; i < services; i++)
+                       if (lp_snum_ok(i) && lp_print_ok(i)
+                           && lp_browseable(i))
+                       {
+                               subcntarr[n] =
+                                       get_printqueue(i, conn, &key,
+                                                      &queue[n], &status[n]);
+                               subcnt += subcntarr[n];
+                               n++;
+                       }
+       }
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+
+       if (init_package(&desc, queuecnt, subcnt))
+       {
+               n = 0;
+               succnt = 0;
+               for (i = 0; i < services; i++)
+                       if (lp_snum_ok(i) && lp_print_ok(i)
+                           && lp_browseable(i))
+                       {
+                               fill_printq_info(conn, &key, i, uLevel, &desc,
+                                                subcntarr[n], queue[n],
+                                                &status[n]);
+                               n++;
+                               if (desc.errcode == NERR_Success)
+                                       succnt = n;
+                       }
+       }
+
+       if (subcntarr)
+               free(subcntarr);
+
+       *rdata_len = desc.usedlen;
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, queuecnt);
+
+       for (i = 0; i < queuecnt; i++)
+       {
+               if (queue && queue[i])
+                       free(queue[i]);
+       }
+
+       if (queue)
+               free(queue);
+       if (status)
+               free(status);
+
+       return True;
 }
 
 /****************************************************************************
   get info level for a server list query
   ****************************************************************************/
-static BOOL check_server_info(int uLevel, charid)
+static BOOL check_server_info(int uLevel, char *id)
 {
-  switch( uLevel ) {
-  case 0:
-    if (strcmp(id,"B16") != 0) return False;
-    break;
-  case 1:
-    if (strcmp(id,"B16BBDz") != 0) return False;
-    break;
-  default: 
-    return False;
-  }
-  return True;
+       switch (uLevel)
+       {
+               case 0:
+                       if (strcmp(id, "B16") != 0)
+                               return False;
+                       break;
+               case 1:
+                       if (strcmp(id, "B16BBDz") != 0)
+                               return False;
+                       break;
+               default:
+                       return False;
+       }
+       return True;
 }
 
 struct srv_info_struct
 {
-  fstring name;
-  uint32 type;
-  fstring comment;
-  fstring domain;
-  BOOL server_added;
+       fstring name;
+       uint32 type;
+       fstring comment;
+       fstring domain;
+       BOOL server_added;
 };
 
 
@@ -901,580 +1070,664 @@ struct srv_info_struct
   get server info lists from the files saved by nmbd. Return the
   number of entries
   ******************************************************************/
-static int get_server_info(uint32 servertype, 
-                          struct srv_info_struct **servers,
-                          char *domain)
+static int get_server_info(uint32 servertype,
+                          struct srv_info_struct **servers, char *domain)
 {
-  FILE *f;
-  pstring fname;
-  int count=0;
-  int alloced=0;
-  pstring line;
-  BOOL local_list_only;
-
-  pstrcpy(fname,lp_lockdir());
-  trim_string(fname,NULL,"/");
-  pstrcat(fname,"/");
-  pstrcat(fname,SERVER_LIST);
-
-  f = sys_fopen(fname,"r");
-
-  if (!f) {
-    DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
-    return(0);
-  }
-
-  /* request for everything is code for request all servers */
-  if (servertype == SV_TYPE_ALL) 
-       servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
-  local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
-
-  DEBUG(4,("Servertype search: %8x\n",servertype));
-
-  while (!feof(f))
-  {
-    fstring stype;
-    struct srv_info_struct *s;
-    char *ptr = line;
-    BOOL ok = True;
-    *ptr = 0;
-
-    fgets(line,sizeof(line)-1,f);
-    if (!*line) continue;
-    
-    if (count == alloced) {
-      alloced += 10;
-      (*servers) = (struct srv_info_struct *)
-       Realloc(*servers,sizeof(**servers)*alloced);
-      if (!(*servers)) return(0);
-      memset((char *)((*servers)+count), 0, sizeof(**servers)*(alloced-count));
-    }
-    s = &(*servers)[count];
-    
-    if (!next_token(&ptr,s->name   , NULL, sizeof(s->name))) continue;
-    if (!next_token(&ptr,stype     , NULL, sizeof(stype))) continue;
-    if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
-    if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
-      /* this allows us to cope with an old nmbd */
-      pstrcpy(s->domain,global_myworkgroup); 
-    }
-    
-    if (sscanf(stype,"%X",&s->type) != 1) { 
-      DEBUG(4,("r:host file ")); 
-      ok = False; 
-    }
-    
-       /* Filter the servers/domains we return based on what was asked for. */
-
-       /* Check to see if we are being asked for a local list only. */
-       if (local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
-         DEBUG(4,("r: local list only"));
-         ok = False;
-       }
-
-    /* doesn't match up: don't want it */
-    if (!(servertype & s->type)) { 
-      DEBUG(4,("r:serv type ")); 
-      ok = False; 
-    }
-    
-    if ((servertype & SV_TYPE_DOMAIN_ENUM) != 
-       (s->type & SV_TYPE_DOMAIN_ENUM))
-      {
-       DEBUG(4,("s: dom mismatch "));
-       ok = False;
-      }
-    
-    if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM))
-      {
-       ok = False;
-      }
-    
-       /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
-       s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
-
-    if (ok)
-      {
-       DEBUG(4,("**SV** %20s %8x %25s %15s\n",
-                s->name, s->type, s->comment, s->domain));
-       
-       s->server_added = True;
-       count++;
-      }
-    else
-      {
-       DEBUG(4,("%20s %8x %25s %15s\n",
-                s->name, s->type, s->comment, s->domain));
-      }
-  }
-  
-  fclose(f);
-  return(count);
+       FILE *f;
+       pstring fname;
+       int count = 0;
+       int alloced = 0;
+       pstring line;
+       BOOL local_list_only;
+
+       pstrcpy(fname, lp_lockdir());
+       trim_string(fname, NULL, "/");
+       pstrcat(fname, "/");
+       pstrcat(fname, SERVER_LIST);
+
+       f = sys_fopen(fname, "r");
+
+       if (!f)
+       {
+               DEBUG(4, ("Can't open %s - %s\n", fname, strerror(errno)));
+               return (0);
+       }
+
+       /* request for everything is code for request all servers */
+       if (servertype == SV_TYPE_ALL)
+               servertype &=
+                       ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);
+
+       local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
+
+       DEBUG(4, ("Servertype search: %8x\n", servertype));
+
+       while (!feof(f))
+       {
+               fstring stype;
+               struct srv_info_struct *s;
+               char *ptr = line;
+               BOOL ok = True;
+               *ptr = 0;
+
+               fgets(line, sizeof(line) - 1, f);
+               if (!*line)
+                       continue;
+
+               if (count == alloced)
+               {
+                       alloced += 10;
+                       (*servers) = (struct srv_info_struct *)Realloc
+                               (*servers, sizeof(**servers) * alloced);
+                       if (!(*servers))
+                               return (0);
+                       memset((char *)((*servers) + count), 0,
+                              sizeof(**servers) * (alloced - count));
+               }
+               s = &(*servers)[count];
+
+               if (!next_token(&ptr, s->name, NULL, sizeof(s->name)))
+                       continue;
+               if (!next_token(&ptr, stype, NULL, sizeof(stype)))
+                       continue;
+               if (!next_token(&ptr, s->comment, NULL, sizeof(s->comment)))
+                       continue;
+               if (!next_token(&ptr, s->domain, NULL, sizeof(s->domain)))
+               {
+                       /* this allows us to cope with an old nmbd */
+                       pstrcpy(s->domain, global_myworkgroup);
+               }
+
+               if (sscanf(stype, "%X", &s->type) != 1)
+               {
+                       DEBUG(4, ("r:host file "));
+                       ok = False;
+               }
+
+               /* Filter the servers/domains we return based on what was asked for. */
+
+               /* Check to see if we are being asked for a local list only. */
+               if (local_list_only
+                   && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0))
+               {
+                       DEBUG(4, ("r: local list only"));
+                       ok = False;
+               }
+
+               /* doesn't match up: don't want it */
+               if (!(servertype & s->type))
+               {
+                       DEBUG(4, ("r:serv type "));
+                       ok = False;
+               }
+
+               if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
+                   (s->type & SV_TYPE_DOMAIN_ENUM))
+               {
+                       DEBUG(4, ("s: dom mismatch "));
+                       ok = False;
+               }
+
+               if (!strequal(domain, s->domain)
+                   && !(servertype & SV_TYPE_DOMAIN_ENUM))
+               {
+                       ok = False;
+               }
+
+               /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
+               s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
+
+               if (ok)
+               {
+                       DEBUG(4, ("**SV** %20s %8x %25s %15s\n",
+                                 s->name, s->type, s->comment, s->domain));
+
+                       s->server_added = True;
+                       count++;
+               }
+               else
+               {
+                       DEBUG(4, ("%20s %8x %25s %15s\n",
+                                 s->name, s->type, s->comment, s->domain));
+               }
+       }
+
+       fclose(f);
+       return (count);
 }
 
 
 /*******************************************************************
   fill in a server info structure
   ******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service, 
-                        int uLevel, char **buf, int *buflen, 
+static int fill_srv_info(struct srv_info_struct *service,
+                        int uLevel, char **buf, int *buflen,
                         char **stringbuf, int *stringspace, char *baseaddr)
 {
-  int struct_len;
-  char* p;
-  char* p2;
-  int l2;
-  int len;
-  switch (uLevel) {
-  case 0: struct_len = 16; break;
-  case 1: struct_len = 26; break;
-  default: return -1;
-  }  
-  if (!buf)
-    {
-      len = 0;
-      switch (uLevel) 
-       {
-       case 1:
-         len = strlen(service->comment)+1;
-         break;
-       }
-
-      if (buflen) *buflen = struct_len;
-      if (stringspace) *stringspace = len;
-      return struct_len + len;
-    }
-  
-  len = struct_len;
-  p = *buf;
-  if (*buflen < struct_len) return -1;
-  if (stringbuf)
-    {
-      p2 = *stringbuf;
-      l2 = *stringspace;
-    }
-  else
-    {
-      p2 = p + struct_len;
-      l2 = *buflen - struct_len;
-    }
-  if (!baseaddr) baseaddr = p;
-  
-  switch (uLevel)
-    {
-    case 0:
-      StrnCpy(p,service->name,15);
-      break;
-
-    case 1:
-      StrnCpy(p,service->name,15);
-      SIVAL(p,18,service->type);
-      SIVAL(p,22,PTR_DIFF(p2,baseaddr));
-      len += CopyAndAdvance(&p2,service->comment,&l2);
-      break;
-    }
-
-  if (stringbuf)
-    {
-      *buf = p + struct_len;
-      *buflen -= struct_len;
-      *stringbuf = p2;
-      *stringspace = l2;
-    }
-  else
-    {
-      *buf = p2;
-      *buflen -= len;
-    }
-  return len;
+       int struct_len;
+       char *p;
+       char *p2;
+       int l2;
+       int len;
+
+       switch (uLevel)
+       {
+               case 0:
+                       struct_len = 16;
+                       break;
+               case 1:
+                       struct_len = 26;
+                       break;
+               default:
+                       return -1;
+       }
+
+       if (!buf)
+       {
+               len = 0;
+               switch (uLevel)
+               {
+                       case 1:
+                               len = strlen(service->comment) + 1;
+                               break;
+               }
+
+               if (buflen)
+                       *buflen = struct_len;
+               if (stringspace)
+                       *stringspace = len;
+               return struct_len + len;
+       }
+
+       len = struct_len;
+       p = *buf;
+       if (*buflen < struct_len)
+               return -1;
+       if (stringbuf)
+       {
+               p2 = *stringbuf;
+               l2 = *stringspace;
+       }
+       else
+       {
+               p2 = p + struct_len;
+               l2 = *buflen - struct_len;
+       }
+       if (!baseaddr)
+               baseaddr = p;
+
+       switch (uLevel)
+       {
+               case 0:
+                       StrnCpy(p, service->name, 15);
+                       break;
+
+               case 1:
+                       StrnCpy(p, service->name, 15);
+                       SIVAL(p, 18, service->type);
+                       SIVAL(p, 22, PTR_DIFF(p2, baseaddr));
+                       len += CopyAndAdvance(&p2, service->comment, &l2);
+                       break;
+       }
+
+       if (stringbuf)
+       {
+               *buf = p + struct_len;
+               *buflen -= struct_len;
+               *stringbuf = p2;
+               *stringspace = l2;
+       }
+       else
+       {
+               *buf = p2;
+               *buflen -= len;
+       }
+       return len;
 }
 
 
-static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
+static BOOL srv_comp(struct srv_info_struct *s1, struct srv_info_struct *s2)
 {
-  return(strcmp(s1->name,s2->name));
+       return (strcmp(s1->name, s2->name));
 }
 
 /****************************************************************************
   view list of servers available (or possibly domains). The info is
   extracted from lists saved by nmbd on the local host
   ****************************************************************************/
-static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
-                              int mdrcnt, int mprcnt, char **rdata, 
-                              char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetServerEnum(connection_struct * conn, uint16 vuid,
+                              char *param, char *data, int mdrcnt,
+                              int mprcnt, char **rdata, char **rparam,
+                              int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel = SVAL(p,0);
-  int buf_len = SVAL(p,2);
-  uint32 servertype = IVAL(p,4);
-  char *p2;
-  int data_len, fixed_len, string_len;
-  int f_len = 0, s_len = 0;
-  struct srv_info_struct *servers=NULL;
-  int counted=0,total=0;
-  int i,missed;
-  fstring domain;
-  BOOL domain_request;
-  BOOL local_request;
-
-  /* If someone sets all the bits they don't really mean to set
-     DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
-     known servers. */
-
-  if (servertype == SV_TYPE_ALL) 
-    servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
-  /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
-     any other bit (they may just set this bit on it's own) they 
-     want all the locally seen servers. However this bit can be 
-     set on its own so set the requested servers to be 
-     ALL - DOMAIN_ENUM. */
-
-  if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) 
-    servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
-
-  domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
-  local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
-
-  p += 8;
-
-  if (!prefix_ok(str1,"WrLehD")) return False;
-  if (!check_server_info(uLevel,str2)) return False;
-  
-  DEBUG(4, ("server request level: %s %8x ", str2, servertype));
-  DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
-  DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
-
-  if (strcmp(str1, "WrLehDz") == 0) {
-    StrnCpy(domain, p, sizeof(fstring)-1);
-  } else {
-    StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);    
-  }
-
-  if (lp_browse_list())
-    total = get_server_info(servertype,&servers,domain);
-
-  data_len = fixed_len = string_len = 0;
-  missed = 0;
-
-  qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
-
-  {
-    char *lastname=NULL;
-
-    for (i=0;i<total;i++)
-    {
-      struct srv_info_struct *s = &servers[i];
-      if (lastname && strequal(lastname,s->name)) continue;
-      lastname = s->name;
-      data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
-      DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
-              s->name, s->type, s->comment, s->domain));
-      
-      if (data_len <= buf_len) {
-         counted++;
-         fixed_len += f_len;
-         string_len += s_len;
-      } else {
-       missed++;
-      }
-    }
-  }
-
-  *rdata_len = fixed_len + string_len;
-  *rdata = REALLOC(*rdata,*rdata_len);
-  memset(*rdata, 0, *rdata_len);
-  
-  p2 = (*rdata) + fixed_len;   /* auxilliary data (strings) will go here */
-  p = *rdata;
-  f_len = fixed_len;
-  s_len = string_len;
-
-  {
-    char *lastname=NULL;
-    int count2 = counted;
-    for (i = 0; i < total && count2;i++)
-      {
-       struct srv_info_struct *s = &servers[i];
-       if (lastname && strequal(lastname,s->name)) continue;
-       lastname = s->name;
-       fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
-       DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
-                s->name, s->type, s->comment, s->domain));
-       count2--;
-      }
-  }
-  
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,counted);
-  SSVAL(*rparam,6,counted+missed);
-
-  if (servers) free(servers);
-
-  DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
-          domain,uLevel,counted,counted+missed));
-
-  return(True);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel = SVAL(p, 0);
+       int buf_len = SVAL(p, 2);
+       uint32 servertype = IVAL(p, 4);
+       char *p2;
+       int data_len, fixed_len, string_len;
+       int f_len = 0, s_len = 0;
+       struct srv_info_struct *servers = NULL;
+       int counted = 0, total = 0;
+       int i, missed;
+       fstring domain;
+       BOOL domain_request;
+       BOOL local_request;
+
+       /* If someone sets all the bits they don't really mean to set
+          DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
+          known servers. */
+
+       if (servertype == SV_TYPE_ALL)
+               servertype &=
+                       ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);
+
+       /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
+          any other bit (they may just set this bit on it's own) they 
+          want all the locally seen servers. However this bit can be 
+          set on its own so set the requested servers to be 
+          ALL - DOMAIN_ENUM. */
+
+       if ((servertype & SV_TYPE_LOCAL_LIST_ONLY)
+           && !(servertype & SV_TYPE_DOMAIN_ENUM))
+               servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
+
+       domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
+       local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
+
+       p += 8;
+
+       if (!prefix_ok(str1, "WrLehD"))
+               return False;
+       if (!check_server_info(uLevel, str2))
+               return False;
+
+       DEBUG(4, ("server request level: %s %8x ", str2, servertype));
+       DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
+       DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
+
+       if (strcmp(str1, "WrLehDz") == 0)
+       {
+               StrnCpy(domain, p, sizeof(fstring) - 1);
+       }
+       else
+       {
+               StrnCpy(domain, global_myworkgroup, sizeof(fstring) - 1);
+       }
+
+       if (lp_browse_list())
+               total = get_server_info(servertype, &servers, domain);
+
+       data_len = fixed_len = string_len = 0;
+       missed = 0;
+
+       qsort(servers, total, sizeof(servers[0]), QSORT_CAST srv_comp);
+
+       {
+               char *lastname = NULL;
+
+               for (i = 0; i < total; i++)
+               {
+                       struct srv_info_struct *s = &servers[i];
+                       if (lastname && strequal(lastname, s->name))
+                               continue;
+                       lastname = s->name;
+                       data_len +=
+                               fill_srv_info(s, uLevel, 0, &f_len, 0, &s_len,
+                                             0);
+                       DEBUG(4,
+                             ("fill_srv_info %20s %8x %25s %15s\n", s->name,
+                              s->type, s->comment, s->domain));
+
+                       if (data_len <= buf_len)
+                       {
+                               counted++;
+                               fixed_len += f_len;
+                               string_len += s_len;
+                       }
+                       else
+                       {
+                               missed++;
+                       }
+               }
+       }
+
+       *rdata_len = fixed_len + string_len;
+       *rdata = REALLOC(*rdata, *rdata_len);
+       memset(*rdata, 0, *rdata_len);
+
+       p2 = (*rdata) + fixed_len;      /* auxilliary data (strings) will go here */
+       p = *rdata;
+       f_len = fixed_len;
+       s_len = string_len;
+
+       {
+               char *lastname = NULL;
+               int count2 = counted;
+               for (i = 0; i < total && count2; i++)
+               {
+                       struct srv_info_struct *s = &servers[i];
+                       if (lastname && strequal(lastname, s->name))
+                               continue;
+                       lastname = s->name;
+                       fill_srv_info(s, uLevel, &p, &f_len, &p2, &s_len,
+                                     *rdata);
+                       DEBUG(4,
+                             ("fill_srv_info %20s %8x %25s %15s\n", s->name,
+                              s->type, s->comment, s->domain));
+                       count2--;
+               }
+       }
+
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVAL(*rparam, 0, (missed == 0 ? NERR_Success : ERRmoredata));
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, counted);
+       SSVAL(*rparam, 6, counted + missed);
+
+       if (servers)
+               free(servers);
+
+       DEBUG(3, ("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
+                 domain, uLevel, counted, counted + missed));
+
+       return (True);
 }
 
 /****************************************************************************
   command 0x34 - suspected of being a "Lookup Names" stub api
   ****************************************************************************/
-static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
-                              int mdrcnt, int mprcnt, char **rdata, 
-                              char **rparam, int *rdata_len, int *rparam_len)
+static BOOL api_RNetGroupGetUsers(connection_struct * conn, uint16 vuid,
+                                 char *param, char *data, int mdrcnt,
+                                 int mprcnt, char **rdata, char **rparam,
+                                 int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel = SVAL(p,0);
-  int buf_len = SVAL(p,2);
-  int counted=0;
-  int missed=0;
-
-       DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
-               str1, str2, p, uLevel, buf_len));
-
-  if (!prefix_ok(str1,"zWrLeh")) return False;
-  
-  *rdata_len = 0;
-  *rdata = NULL;
-  
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-
-  SSVAL(*rparam,0,0x08AC); /* informational warning message */
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,counted);
-  SSVAL(*rparam,6,counted+missed);
-
-  return(True);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel = SVAL(p, 0);
+       int buf_len = SVAL(p, 2);
+       int counted = 0;
+       int missed = 0;
+
+       DEBUG(5, ("RNetGroupGetUsers: %s %s %s %d %d\n",
+                 str1, str2, p, uLevel, buf_len));
+
+       if (!prefix_ok(str1, "zWrLeh"))
+               return False;
+
+       *rdata_len = 0;
+       *rdata = NULL;
+
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+
+       SSVAL(*rparam, 0, 0x08AC);      /* informational warning message */
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, counted);
+       SSVAL(*rparam, 6, counted + missed);
+
+       return (True);
 }
 
 /****************************************************************************
   get info about a share
   ****************************************************************************/
-static BOOL check_share_info(int uLevel, charid)
+static BOOL check_share_info(int uLevel, char *id)
 {
-  switch( uLevel ) {
-  case 0:
-    if (strcmp(id,"B13") != 0) return False;
-    break;
-  case 1:
-    if (strcmp(id,"B13BWz") != 0) return False;
-    break;
-  case 2:
-    if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
-    break;
-  case 91:
-    if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
-    break;
-  default: return False;
-  }
-  return True;
+       switch (uLevel)
+       {
+               case 0:
+                       if (strcmp(id, "B13") != 0)
+                               return False;
+                       break;
+               case 1:
+                       if (strcmp(id, "B13BWz") != 0)
+                               return False;
+                       break;
+               case 2:
+                       if (strcmp(id, "B13BWzWWWzB9B") != 0)
+                               return False;
+                       break;
+               case 91:
+                       if (strcmp(id, "B13BWzWWWzB9BB9BWzWWzWW") != 0)
+                               return False;
+                       break;
+               default:
+                       return False;
+       }
+       return True;
 }
 
-static int fill_share_info(connection_struct *conn, const vuser_key *key,
-                               int snum, int uLevel,
-                          char** buf, int* buflen,
-                          char** stringbuf, int* stringspace, char* baseaddr)
+static int fill_share_info(connection_struct * conn, const vuser_key * key,
+                          int snum, int uLevel,
+                          char **buf, int *buflen,
+                          char **stringbuf, int *stringspace, char *baseaddr)
 {
-  int struct_len;
-  char* p;
-  char* p2;
-  int l2;
-  int len;
-  switch( uLevel ) {
-  case 0: struct_len = 13; break;
-  case 1: struct_len = 20; break;
-  case 2: struct_len = 40; break;
-  case 91: struct_len = 68; break;
-  default: return -1;
-  }
-  
-  if (!buf)
-    {
-      len = 0;
-      if (uLevel > 0) len += StrlenExpanded(conn,key,snum,lp_comment(snum));
-      if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
-      if (buflen) *buflen = struct_len;
-      if (stringspace) *stringspace = len;
-      return struct_len + len;
-    }
-  
-  len = struct_len;
-  p = *buf;
-  if ((*buflen) < struct_len) return -1;
-  if (stringbuf)
-    {
-      p2 = *stringbuf;
-      l2 = *stringspace;
-    }
-  else
-    {
-      p2 = p + struct_len;
-      l2 = (*buflen) - struct_len;
-    }
-  if (!baseaddr) baseaddr = p;
-  
-  StrnCpy(p,lp_servicename(snum),13);
-  
-  if (uLevel > 0)
-    {
-      int type;
-      CVAL(p,13) = 0;
-      type = STYPE_DISKTREE;
-      if (lp_print_ok(snum)) type = STYPE_PRINTQ;
-      if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
-      SSVAL(p,14,type);                /* device type */
-      SIVAL(p,16,PTR_DIFF(p2,baseaddr));
-      len += CopyExpanded(conn,key, snum,&p2,lp_comment(snum),&l2);
-    }
-  
-  if (uLevel > 1)
-    {
-      SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
-      SSVALS(p,22,-1);         /* max uses */
-      SSVAL(p,24,1); /* current uses */
-      SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
-      len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
-      memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
-    }
-  
-  if (uLevel > 2)
-    {
-      memset(p+40,0,SHPWLEN+2);
-      SSVAL(p,50,0);
-      SIVAL(p,52,0);
-      SSVAL(p,56,0);
-      SSVAL(p,58,0);
-      SIVAL(p,60,0);
-      SSVAL(p,64,0);
-      SSVAL(p,66,0);
-    }
-       
-  if (stringbuf)
-    {
-      (*buf) = p + struct_len;
-      (*buflen) -= struct_len;
-      (*stringbuf) = p2;
-      (*stringspace) = l2;
-    }
-  else
-    {
-      (*buf) = p2;
-      (*buflen) -= len;
-    }
-  return len;
+       int struct_len;
+       char *p;
+       char *p2;
+       int l2;
+       int len;
+
+       switch (uLevel)
+       {
+               case 0:
+                       struct_len = 13;
+                       break;
+               case 1:
+                       struct_len = 20;
+                       break;
+               case 2:
+                       struct_len = 40;
+                       break;
+               case 91:
+                       struct_len = 68;
+                       break;
+               default:
+                       return -1;
+       }
+
+
+       if (!buf)
+       {
+               len = 0;
+               if (uLevel > 0)
+                       len +=
+                               StrlenExpanded(conn, key, snum,
+                                              lp_comment(snum));
+               if (uLevel > 1)
+                       len += strlen(lp_pathname(snum)) + 1;
+               if (buflen)
+                       *buflen = struct_len;
+               if (stringspace)
+                       *stringspace = len;
+               return struct_len + len;
+       }
+
+       len = struct_len;
+       p = *buf;
+       if ((*buflen) < struct_len)
+               return -1;
+       if (stringbuf)
+       {
+               p2 = *stringbuf;
+               l2 = *stringspace;
+       }
+       else
+       {
+               p2 = p + struct_len;
+               l2 = (*buflen) - struct_len;
+       }
+       if (!baseaddr)
+               baseaddr = p;
+
+       StrnCpy(p, lp_servicename(snum), 13);
+
+       if (uLevel > 0)
+       {
+               int type;
+               CVAL(p, 13) = 0;
+               type = STYPE_DISKTREE;
+               if (lp_print_ok(snum))
+                       type = STYPE_PRINTQ;
+               if (strequal("IPC$", lp_servicename(snum)))
+                       type = STYPE_IPC;
+               SSVAL(p, 14, type);     /* device type */
+               SIVAL(p, 16, PTR_DIFF(p2, baseaddr));
+               len +=
+                       CopyExpanded(conn, key, snum, &p2, lp_comment(snum),
+                                    &l2);
+       }
+
+       if (uLevel > 1)
+       {
+               SSVAL(p, 20, ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE);       /* permissions */
+               SSVALS(p, 22, -1);      /* max uses */
+               SSVAL(p, 24, 1);        /* current uses */
+               SIVAL(p, 26, PTR_DIFF(p2, baseaddr));   /* local pathname */
+               len += CopyAndAdvance(&p2, lp_pathname(snum), &l2);
+               memset(p + 30, 0, SHPWLEN + 2); /* passwd (reserved), pad field */
+       }
+
+       if (uLevel > 2)
+       {
+               memset(p + 40, 0, SHPWLEN + 2);
+               SSVAL(p, 50, 0);
+               SIVAL(p, 52, 0);
+               SSVAL(p, 56, 0);
+               SSVAL(p, 58, 0);
+               SIVAL(p, 60, 0);
+               SSVAL(p, 64, 0);
+               SSVAL(p, 66, 0);
+       }
+
+       if (stringbuf)
+       {
+               (*buf) = p + struct_len;
+               (*buflen) -= struct_len;
+               (*stringbuf) = p2;
+               (*stringspace) = l2;
+       }
+       else
+       {
+               (*buf) = p2;
+               (*buflen) -= len;
+       }
+       return len;
 }
 
-static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareGetInfo(connection_struct * conn, uint16 vuid,
+                                char *param, char *data, int mdrcnt,
+                                int mprcnt, char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *netname = skip_string(str2,1);
-  char *p = skip_string(netname,1);
-  int uLevel = SVAL(p,0);
-  int snum = find_service(netname);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *netname = skip_string(str2, 1);
+       char *p = skip_string(netname, 1);
+       int uLevel = SVAL(p, 0);
+       int snum = find_service(netname);
        VUSER_KEY;
-  
-  if (snum < 0) return False;
-  
-  /* check it's a supported varient */
-  if (!prefix_ok(str1,"zWrLh")) return False;
-  if (!check_share_info(uLevel,str2)) return False;
-  *rdata = REALLOC(*rdata,mdrcnt);
-  p = *rdata;
-  *rdata_len = fill_share_info(conn,&key,snum,uLevel,&p,&mdrcnt,0,0,0);
-  if (*rdata_len < 0) return False;
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
-  SSVAL(*rparam,4,*rdata_len);
-  return(True);
+
+       if (snum < 0)
+               return False;
+
+       /* check it's a supported varient */
+       if (!prefix_ok(str1, "zWrLh"))
+               return False;
+       if (!check_share_info(uLevel, str2))
+               return False;
+
+       *rdata = REALLOC(*rdata, mdrcnt);
+       p = *rdata;
+       *rdata_len =
+               fill_share_info(conn, &key, snum, uLevel, &p, &mdrcnt, 0, 0,
+                               0);
+       if (*rdata_len < 0)
+               return False;
+
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
+       SSVAL(*rparam, 4, *rdata_len);
+
+       return (True);
 }
 
 /****************************************************************************
   view list of shares available
   ****************************************************************************/
-static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
-                             int mdrcnt,int mprcnt,
-                             char **rdata,char **rparam,
-                             int *rdata_len,int *rparam_len)
+static BOOL api_RNetShareEnum(connection_struct * conn, uint16 vuid,
+                             char *param, char *data, int mdrcnt, int mprcnt,
+                             char **rdata, char **rparam, int *rdata_len,
+                             int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel = SVAL(p,0);
-  int buf_len = SVAL(p,2);
-  char *p2;
-  int count=lp_numservices();
-  int total=0,counted=0;
-  BOOL missed = False;
-  int i;
-  int data_len, fixed_len, string_len;
-  int f_len = 0, s_len = 0;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel = SVAL(p, 0);
+       int buf_len = SVAL(p, 2);
+       char *p2;
+       int count = lp_numservices();
+       int total = 0, counted = 0;
+       BOOL missed = False;
+       int i;
+       int data_len, fixed_len, string_len;
+       int f_len = 0, s_len = 0;
        VUSER_KEY;
-  if (!prefix_ok(str1,"WrLeh")) return False;
-  if (!check_share_info(uLevel,str2)) return False;
-  
-  data_len = fixed_len = string_len = 0;
-  for (i=0;i<count;i++)
-    if (lp_browseable(i) && lp_snum_ok(i))
-    {
-      total++;
-      data_len += fill_share_info(conn,&key,i,uLevel,0,&f_len,0,&s_len,0);
-      if (data_len <= buf_len)
-      {
-        counted++;
-        fixed_len += f_len;
-        string_len += s_len;
-      }
-      else
-        missed = True;
-    }
-  *rdata_len = fixed_len + string_len;
-  *rdata = REALLOC(*rdata,*rdata_len);
-  memset(*rdata,0,*rdata_len);
-  
-  p2 = (*rdata) + fixed_len;   /* auxillery data (strings) will go here */
-  p = *rdata;
-  f_len = fixed_len;
-  s_len = string_len;
-  for (i = 0; i < count;i++)
-    if (lp_browseable(i) && lp_snum_ok(i))
-      if (fill_share_info(conn,&key,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
-       break;
-  
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,counted);
-  SSVAL(*rparam,6,total);
-  
-  DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
-          counted,total,uLevel,
-          buf_len,*rdata_len,mdrcnt));
-  return(True);
+
+       if (!prefix_ok(str1, "WrLeh"))
+               return False;
+       if (!check_share_info(uLevel, str2))
+               return False;
+
+       data_len = fixed_len = string_len = 0;
+       for (i = 0; i < count; i++)
+               if (lp_browseable(i) && lp_snum_ok(i))
+               {
+                       total++;
+                       data_len +=
+                               fill_share_info(conn, &key, i, uLevel, 0,
+                                               &f_len, 0, &s_len, 0);
+                       if (data_len <= buf_len)
+                       {
+                               counted++;
+                               fixed_len += f_len;
+                               string_len += s_len;
+                       }
+                       else
+                               missed = True;
+               }
+       *rdata_len = fixed_len + string_len;
+       *rdata = REALLOC(*rdata, *rdata_len);
+       memset(*rdata, 0, *rdata_len);
+
+       p2 = (*rdata) + fixed_len;      /* auxillery data (strings) will go here */
+       p = *rdata;
+       f_len = fixed_len;
+       s_len = string_len;
+       for (i = 0; i < count; i++)
+               if (lp_browseable(i) && lp_snum_ok(i))
+                       if (fill_share_info
+                           (conn, &key, i, uLevel, &p, &f_len, &p2, &s_len,
+                            *rdata) < 0)
+                               break;
+
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVAL(*rparam, 0, missed ? ERRmoredata : NERR_Success);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, counted);
+       SSVAL(*rparam, 6, total);
+
+       DEBUG(3, ("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
+                 counted, total, uLevel, buf_len, *rdata_len, mdrcnt));
+       return (True);
 }
 
 
@@ -1482,313 +1735,351 @@ static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,c
 /****************************************************************************
   get the time of day info
   ****************************************************************************/
-static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
-                            int mdrcnt,int mprcnt,
-                            char **rdata,char **rparam,
-                            int *rdata_len,int *rparam_len)
+static BOOL api_NetRemoteTOD(connection_struct * conn, uint16 vuid,
+                            char *param, char *data, int mdrcnt, int mprcnt,
+                            char **rdata, char **rparam, int *rdata_len,
+                            int *rparam_len)
 {
-  char *p;
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
-
-  *rdata_len = 21;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
-
-  p = *rdata;
+       char *p;
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  {
-    struct tm *t;
-    time_t unixdate = time(NULL);
+       *rdata_len = 21;
+       *rdata = REALLOC(*rdata, *rdata_len);
 
-    put_dos_date3(p,0,unixdate); /* this is the time that is looked at
-                                   by NT in a "net time" operation,
-                                   it seems to ignore the one below */
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
-    /* the client expects to get localtime, not GMT, in this bit 
-       (I think, this needs testing) */
-    t = LocalTime(&unixdate);
+       p = *rdata;
 
-    SIVAL(p,4,0);              /* msecs ? */
-    CVAL(p,8) = t->tm_hour;
-    CVAL(p,9) = t->tm_min;
-    CVAL(p,10) = t->tm_sec;
-    CVAL(p,11) = 0;            /* hundredths of seconds */
-    SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
-    SSVAL(p,14,10000);         /* timer interval in 0.0001 of sec */
-    CVAL(p,16) = t->tm_mday;
-    CVAL(p,17) = t->tm_mon + 1;
-    SSVAL(p,18,1900+t->tm_year);
-    CVAL(p,20) = t->tm_wday;
-  }
+       {
+               struct tm *t;
+               time_t unixdate = time(NULL);
+
+               put_dos_date3(p, 0, unixdate);  /* this is the time that is looked at
+                                                  by NT in a "net time" operation,
+                                                  it seems to ignore the one below */
+
+               /* the client expects to get localtime, not GMT, in this bit 
+                  (I think, this needs testing) */
+               t = LocalTime(&unixdate);
+
+               SIVAL(p, 4, 0); /* msecs ? */
+               CVAL(p, 8) = t->tm_hour;
+               CVAL(p, 9) = t->tm_min;
+               CVAL(p, 10) = t->tm_sec;
+               CVAL(p, 11) = 0;        /* hundredths of seconds */
+               SSVALS(p, 12, TimeDiff(unixdate) / 60); /* timezone in minutes from GMT */
+               SSVAL(p, 14, 10000);    /* timer interval in 0.0001 of sec */
+               CVAL(p, 16) = t->tm_mday;
+               CVAL(p, 17) = t->tm_mon + 1;
+               SSVAL(p, 18, 1900 + t->tm_year);
+               CVAL(p, 20) = t->tm_wday;
+       }
 
 
-  return(True);
+       return (True);
 }
 
 /****************************************************************************
   set the user password
   ****************************************************************************/
-static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_SetUserPassword(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-  char *p = skip_string(param+2,2);
-  fstring user;
-  fstring pass1,pass2;
-  uchar pwbuf[516];
-  uchar nt_pw[16];
-  uchar lm_pw[16];
-
-  fstrcpy(user,p);
+       char *p = skip_string(param + 2, 2);
+       fstring user;
+       fstring pass1, pass2;
+       uchar pwbuf[516];
+       uchar nt_pw[16];
+       uchar lm_pw[16];
 
-  p = skip_string(p,1);
+       fstrcpy(user, p);
 
-  memcpy(pass1,p,16);
-  memcpy(pass2,p+16,16);
+       p = skip_string(p, 1);
 
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       memcpy(pass1, p, 16);
+       memcpy(pass2, p + 16, 16);
 
-  *rdata_len = 0;
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  SSVAL(*rparam,0,NERR_badpass);
-  SSVAL(*rparam,2,0);          /* converter word */
+       *rdata_len = 0;
 
-  DEBUG(3,("Set password for <%s>\n",user));
+       SSVAL(*rparam, 0, NERR_badpass);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
-  /*
-   * Pass the user through the NT -> unix user mapping
-   * function.
-   */
+       DEBUG(3, ("Set password for <%s>\n", user));
 
-  (void)map_username(user);
+       /*
+        * Pass the user through the NT -> unix user mapping
+        * function.
+        */
 
-  /*
-   * Do any UNIX username case mangling.
-   */
-  (void)Get_Pwnam( user, True);
+       (void)map_username(user);
 
-  if (strequal(param + 2, "zb16b16WW"))
-  {
-  /*
-   * attempt the encrypted pw change. NT will generate this
-   * after trying the samr method.
-   */
+       /*
+        * Do any UNIX username case mangling.
+        */
+       (void)Get_Pwnam(user, True);
 
-       if (SVAL(*rparam,0) != NERR_Success)
+       if (strequal(param + 2, "zb16b16WW"))
        {
-               if (make_oem_passwd_hash(pwbuf, pass1, 16, NULL, False) &&
-                   msrpc_sam_ntpasswd_set("\\\\.", user,  NULL,
-                            pwbuf, pass2, /* lm pw */
-                            NULL, NULL)) /* nt pw */
+               /*
+                * attempt the encrypted pw change. NT will generate this
+                * after trying the samr method.
+                */
+
+               if (SVAL(*rparam, 0) != NERR_Success)
                {
-                       SSVAL(*rparam,0,NERR_Success);
+                       if (make_oem_passwd_hash
+                           (pwbuf, pass1, 16, NULL, False)
+                           && msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+                                                     pwbuf, pass2,     /* lm pw */
+                                                     NULL, NULL))      /* nt pw */
+                       {
+                               SSVAL(*rparam, 0, NERR_Success);
+                       }
                }
        }
-  }
-  else
-  {
-  /*
-   * Attempt the plaintext password change first.
-   * Older versions of Windows seem to do this.
-   */
-
-       nt_lm_owf_gen(pass1, nt_pw, lm_pw);
-       if (msrpc_sam_ntchange_pwd("\\\\.", user, global_sam_name,
-                                  lm_pw, nt_pw, pass2))
+       else
        {
-               SSVAL(*rparam,0,NERR_Success);
+               /*
+                * Attempt the plaintext password change first.
+                * Older versions of Windows seem to do this.
+                */
+
+               nt_lm_owf_gen(pass1, nt_pw, lm_pw);
+               if (msrpc_sam_ntchange_pwd("\\\\.", user, global_sam_name,
+                                          lm_pw, nt_pw, pass2))
+               {
+                       SSVAL(*rparam, 0, NERR_Success);
+               }
        }
-  }
        ZERO_STRUCT(pwbuf);
        ZERO_STRUCT(pass1);
        ZERO_STRUCT(pass2);
 
-       return(True);
+       return (True);
 }
 
 /****************************************************************************
   Set the user password (SamOEM version - gets plaintext).
 ****************************************************************************/
 
-static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_SamOEMChangePassword(connection_struct * conn, uint16 vuid,
+                                    char *param, char *data, int mdrcnt,
+                                    int mprcnt, char **rdata, char **rparam,
+                                    int *rdata_len, int *rparam_len)
 {
-  fstring user;
-  char *p = param + 2;
-  *rparam_len = 2;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       fstring user;
+       char *p = param + 2;
+       *rparam_len = 2;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_badpass);
+       SSVAL(*rparam, 0, NERR_badpass);
 
-  /*
-   * Check the parameter definition is correct.
-   */
-  if (!strequal(param + 2, "zsT")) {
-    DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
-    return False;
-  }
-  p = skip_string(p, 1);
-
-  if (!strequal(p, "B516B16")) {
-    DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
-    return False;
-  }
-  p = skip_string(p,1);
-
-  fstrcpy(user,p);
-  p = skip_string(p,1);
-
-  DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
-
-  if (msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
-                             (uchar*) data, (uchar *)&data[516], /* lm pw */
-                             NULL, NULL)) /* nt pw */
-  {
-    SSVAL(*rparam,0,NERR_Success);
-  }
-
-  return(True);
+       /*
+        * Check the parameter definition is correct.
+        */
+       if (!strequal(param + 2, "zsT"))
+       {
+               DEBUG(0,
+                     ("api_SamOEMChangePassword: Invalid parameter string %s\n",
+                      param + 2));
+               return False;
+       }
+       p = skip_string(p, 1);
+
+       if (!strequal(p, "B516B16"))
+       {
+               DEBUG(0,
+                     ("api_SamOEMChangePassword: Invalid data parameter string %s\n",
+                      p));
+               return False;
+       }
+       p = skip_string(p, 1);
+
+       fstrcpy(user, p);
+       p = skip_string(p, 1);
+
+       DEBUG(3,
+             ("api_SamOEMChangePassword: Change password for <%s>\n", user));
+
+       if (msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+                                  (uchar *) data, (uchar *) & data[516],       /* lm pw */
+                                  NULL, NULL)) /* nt pw */
+       {
+               SSVAL(*rparam, 0, NERR_Success);
+       }
+
+       return (True);
 }
 
 /****************************************************************************
   delete a print job
   Form: <W> <> 
   ****************************************************************************/
-static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_RDosPrintJobDel(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-  int function = SVAL(param,0);
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int jobid, snum;
-  int i, count;
+       int function = SVAL(param, 0);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int jobid, snum;
+       int i, count;
        VUSER_KEY;
 
-  printjob_decode(SVAL(p,0), &snum, &jobid);
-
-  /* check it's a supported varient */
-  if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
-    return(False);
-
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
-
-  *rdata_len = 0;
-
-  SSVAL(*rparam,0,NERR_Success);
-
-  if (snum >= 0 && VALID_SNUM(snum))
-    {
-      print_queue_struct *queue=NULL;
-      lpq_reset(snum);
-      count = get_printqueue(snum,conn,&key,&queue,NULL);
-  
-      for (i=0;i<count;i++)
-       if ((queue[i].job&0xFF) == jobid)
-         {
-           switch (function) {
-           case 81:            /* delete */ 
-             DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
-             del_printqueue(conn,&key,snum,queue[i].job);
-             break;
-           case 82:            /* pause */
-           case 83:            /* resume */
-             DEBUG(3,("%s queue entry %d\n",
-                      (function==82?"pausing":"resuming"),queue[i].job));
-             status_printjob(conn,&key,snum,queue[i].job,
-                             (function==82?LPQ_PAUSED:LPQ_QUEUED));
-             break;
-           }
-           break;
-         }
-  
-      if (i==count)
-       SSVAL(*rparam,0,NERR_JobNotFound);
-
-      if (queue) free(queue);
-    }
-
-  SSVAL(*rparam,2,0);          /* converter word */
-
-  return(True);
+       printjob_decode(SVAL(p, 0), &snum, &jobid);
+
+       /* check it's a supported varient */
+       if (!(strcsequal(str1, "W") && strcsequal(str2, "")))
+               return (False);
+
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam, *rparam_len);
+
+       *rdata_len = 0;
+
+       SSVAL(*rparam, 0, NERR_Success);
+
+       if (snum >= 0 && VALID_SNUM(snum))
+       {
+               print_queue_struct *queue = NULL;
+               lpq_reset(snum);
+               count = get_printqueue(snum, conn, &key, &queue, NULL);
+
+               for (i = 0; i < count; i++)
+                       if ((queue[i].job & 0xFF) == jobid)
+                       {
+                               switch (function)
+                               {
+                                       case 81:        /* delete */
+                                               DEBUG(3,
+                                                     ("Deleting queue entry %d\n",
+                                                      queue[i].job));
+                                               del_printqueue(conn, &key,
+                                                              snum,
+                                                              queue[i].job);
+                                               break;
+                                       case 82:        /* pause */
+                                       case 83:        /* resume */
+                                               DEBUG(3,
+                                                     ("%s queue entry %d\n",
+                                                      (function ==
+                                                       82 ? "pausing" :
+                                                       "resuming"),
+                                                      queue[i].job));
+                                               status_printjob(conn, &key,
+                                                               snum,
+                                                               queue[i].job,
+                                                               (function ==
+                                                                82 ?
+                                                                LPQ_PAUSED :
+                                                                LPQ_QUEUED));
+                                               break;
+                               }
+                               break;
+                       }
+
+               if (i == count)
+                       SSVAL(*rparam, 0, NERR_JobNotFound);
+
+               if (queue)
+                       free(queue);
+       }
+
+       SSVAL(*rparam, 2, 0);   /* converter word */
+
+       return (True);
 }
 
 /****************************************************************************
   Purge a print queue - or pause or resume it.
   ****************************************************************************/
-static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_WPrintQueuePurge(connection_struct * conn, uint16 vuid,
+                                char *param, char *data, int mdrcnt,
+                                int mprcnt, char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  int function = SVAL(param,0);
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *QueueName = skip_string(str2,1);
-  int snum;
+       int function = SVAL(param, 0);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *QueueName = skip_string(str2, 1);
+       int snum;
        VUSER_KEY;
 
-  /* check it's a supported varient */
-  if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
-    return(False);
-
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
-
-  *rdata_len = 0;
-
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
-
-  snum = lp_servicenumber(QueueName);
-  if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(QueueName,pnum);
-      snum = lp_servicenumber(QueueName);
-    }
-  }
-
-  if (snum >= 0 && VALID_SNUM(snum)) {
-    lpq_reset(snum);
-    
-    switch (function) {
-    case 74: /* Pause queue */
-    case 75: /* Resume queue */
-    {
-      status_printqueue(conn,&key,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
-      DEBUG(3,("Print queue %s, queue=%s\n",
-            (function==74?"pause":"resume"),QueueName));
-      break;
-      }
-    case 103: /* Purge */
-      {
-        print_queue_struct *queue=NULL;
-        int i, count;
-        count = get_printqueue(snum,conn,&key,&queue,NULL);
-        for (i = 0; i < count; i++)
-          del_printqueue(conn,&key,snum,queue[i].job);
-        if (queue) free(queue);
-        DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
-        break;
-      }
-    }
-  }
-
-  return(True);
+       /* check it's a supported varient */
+       if (!(strcsequal(str1, "z") && strcsequal(str2, "")))
+               return (False);
+
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam, *rparam_len);
+
+       *rdata_len = 0;
+
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
+
+       snum = lp_servicenumber(QueueName);
+       if (snum < 0 && pcap_printername_ok(QueueName, NULL))
+       {
+               int pnum = lp_servicenumber(PRINTERS_NAME);
+               if (pnum >= 0)
+               {
+                       lp_add_printer(QueueName, pnum);
+                       snum = lp_servicenumber(QueueName);
+               }
+       }
+
+       if (snum >= 0 && VALID_SNUM(snum))
+       {
+               lpq_reset(snum);
+
+               switch (function)
+               {
+                       case 74:        /* Pause queue */
+                       case 75:        /* Resume queue */
+                       {
+                               status_printqueue(conn, &key, snum,
+                                                 (function ==
+                                                  74 ? LPSTAT_STOPPED :
+                                                  LPSTAT_OK));
+                               DEBUG(3,
+                                     ("Print queue %s, queue=%s\n",
+                                      (function == 74 ? "pause" : "resume"),
+                                      QueueName));
+                               break;
+                       }
+                       case 103:       /* Purge */
+                       {
+                               print_queue_struct *queue = NULL;
+                               int i, count;
+                               count =
+                                       get_printqueue(snum, conn, &key,
+                                                      &queue, NULL);
+                               for (i = 0; i < count; i++)
+                                       del_printqueue(conn, &key, snum,
+                                                      queue[i].job);
+
+                               if (queue)
+                                       free(queue);
+                               DEBUG(3,
+                                     ("Print queue purge, queue=%s\n",
+                                      QueueName));
+                               break;
+                       }
+               }
+       }
+
+       return (True);
 }
 
 
@@ -1799,311 +2090,376 @@ static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *para
   Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz> 
   or   <WWsTP> <WB21BB16B10zWWzDDz> 
 ****************************************************************************/
-static int check_printjob_info(struct pack_desc* desc,
-                              int uLevel, char* id)
+static int check_printjob_info(struct pack_desc *desc, int uLevel, char *id)
 {
-  desc->subformat = NULL;
-  switch( uLevel ) {
-  case 0: desc->format = "W"; break;
-  case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
-  case 2: desc->format = "WWzWWDDzz"; break;
-  case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
-  default: return False;
-  }
-  if (strcmp(desc->format,id) != 0) return False;
-  return True;
+       desc->subformat = NULL;
+       switch (uLevel)
+       {
+               case 0:
+                       desc->format = "W";
+                       break;
+               case 1:
+                       desc->format = "WB21BB16B10zWWzDDz";
+                       break;
+               case 2:
+                       desc->format = "WWzWWDDzz";
+                       break;
+               case 3:
+                       desc->format = "WWzWWDDzzzzzzzzzzlz";
+                       break;
+               default:
+                       return False;
+       }
+       if (strcmp(desc->format, id) != 0)
+               return False;
+       return True;
 }
 
-static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
-                            int mdrcnt,int mprcnt,
-                            char **rdata,char **rparam,
-                            int *rdata_len,int *rparam_len)
+static BOOL api_PrintJobInfo(connection_struct * conn, uint16 vuid,
+                            char *param, char *data, int mdrcnt, int mprcnt,
+                            char **rdata, char **rparam, int *rdata_len,
+                            int *rparam_len)
 {
        struct pack_desc desc;
-       char *str1 = param+2;
-       char *str2 = skip_string(str1,1);
-       char *p = skip_string(str2,1);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
        int jobid, snum;
-       int uLevel = SVAL(p,2);
-       int function = SVAL(p,4);       /* what is this ?? */
+       int uLevel = SVAL(p, 2);
+       int function = SVAL(p, 4);      /* what is this ?? */
        int i;
        char *s = data;
        files_struct *fsp;
        VUSER_KEY;
 
-       printjob_decode(SVAL(p,0), &snum, &jobid);
-   
+       printjob_decode(SVAL(p, 0), &snum, &jobid);
+
        *rparam_len = 4;
-       *rparam = REALLOC(*rparam,*rparam_len);
-  
+       *rparam = REALLOC(*rparam, *rparam_len);
+
        *rdata_len = 0;
-       
+
        /* check it's a supported varient */
-       if ((strcmp(str1,"WWsTP")) || 
-           (!check_printjob_info(&desc,uLevel,str2)))
-               return(False);
-   
-       switch (function) {
-       case 0x6:       /* change job place in the queue, 
-                          data gives the new place */
-               if (snum >= 0 && VALID_SNUM(snum)) {
-                       print_queue_struct *queue=NULL;
-                       int count;
-  
-                       lpq_reset(snum);
-                       count = get_printqueue(snum,conn,&key,&queue,NULL);
-                       for (i=0;i<count;i++)   /* find job */
-                               if ((queue[i].job&0xFF) == jobid) break;
-           
-                       if (i==count) {
-                               desc.errcode=NERR_JobNotFound;
-                               if (queue) free(queue);
-                       } else {
-                               desc.errcode=NERR_Success;
-                               i++;
-#if 0  
+       if ((strcmp(str1, "WWsTP")) ||
+           (!check_printjob_info(&desc, uLevel, str2)))
+               return (False);
+
+       switch (function)
+       {
+               case 0x6:       /* change job place in the queue, 
+                                  data gives the new place */
+                       if (snum >= 0 && VALID_SNUM(snum))
+                       {
+                               print_queue_struct *queue = NULL;
+                               int count;
+
+                               lpq_reset(snum);
+                               count =
+                                       get_printqueue(snum, conn, &key,
+                                                      &queue, NULL);
+                               for (i = 0; i < count; i++)     /* find job */
+                                       if ((queue[i].job & 0xFF) == jobid)
+                                               break;
+
+                               if (i == count)
                                {
-                                       int place= SVAL(data,0);
-                                       /* we currently have no way of
-                                          doing this. Can any unix do it? */
-                                       if (i < place)  /* move down */;
-                                       else if (i > place )    /* move up */;
+                                       desc.errcode = NERR_JobNotFound;
+                                       if (queue)
+                                               free(queue);
                                }
+                               else
+                               {
+                                       desc.errcode = NERR_Success;
+                                       i++;
+#if 0
+                                       {
+                                               int place = SVAL(data, 0);
+                                               /* we currently have no way of
+                                                  doing this. Can any unix do it? */
+                                               if (i <
+                                                   place) /* move down */ ;
+                                               else if (i > place)     /* move up */
+                                                       ;
+                                       }
 #endif
-                               desc.errcode=NERR_notsupported; /* not yet 
-                                                                  supported */
-                               if (queue) free(queue);
+                                       desc.errcode = NERR_notsupported;       /* not yet 
+                                                                                  supported */
+                                       if (queue)
+                                               free(queue);
+                               }
                        }
-               } else {
-                       desc.errcode=NERR_JobNotFound;
-               }
-               break;
-
-       case 0xb:   /* change print job name, data gives the name */
-               /* jobid, snum should be zero */
-               if (isalpha((int)*s)) {
-                       pstring name;
-                       int l = 0;
-                       while (l<64 && *s) {
-                               if (issafe(*s)) name[l++] = *s;
-                               s++;
-                       }      
-                       name[l] = 0;
-       
-                       DEBUG(3,("Setting print name to %s\n",name));
-       
-                       fsp = file_find_print();        
-
-                       if (fsp) {
-                               connection_struct *fconn = fsp->conn;
-                               unbecome_user();
-             
-                               if (!become_user(fconn,vuid) || 
-                                   !become_service(fconn,True))
+                       else
+                       {
+                               desc.errcode = NERR_JobNotFound;
+                       }
+                       break;
+
+               case 0xb:       /* change print job name, data gives the name */
+                       /* jobid, snum should be zero */
+                       if (isalpha((int)*s))
+                       {
+                               pstring name;
+                               int l = 0;
+                               while (l < 64 && *s)
+                               {
+                                       if (issafe(*s))
+                                               name[l++] = *s;
+                                       s++;
+                               }
+                               name[l] = 0;
+
+                               DEBUG(3,
+                                     ("Setting print name to %s\n", name));
+
+                               fsp = file_find_print();
+
+                               if (fsp)
+                               {
+                                       pstring zfrom, zto;
+                                       connection_struct *fconn = fsp->conn;
+                                       unbecome_user();
+
+                                       if (!become_user(fconn, vuid) ||
+                                           !become_service(fconn, True))
+                                               break;
+
+                                       pstrcpy(zfrom,
+                                               dos_to_unix(fsp->fsp_name,
+                                                           False));
+                                       pstrcpy(zto,
+                                               dos_to_unix(name, False));
+
+                                       if (fsp->conn->
+                                           vfs_ops.rename(zfrom, zto) == 0)
+                                       {
+                                               string_set(&fsp->fsp_name,
+                                                          name);
+                                       }
                                        break;
-             
-                               if (conn->vfs_ops.rename(dos_to_unix(fsp->fsp_name,False),name) == 0) {
-                                       string_set(&fsp->fsp_name,name);
                                }
-                               break;
                        }
-               }
-               desc.errcode=NERR_Success;
-               break;
+                       desc.errcode = NERR_Success;
+                       break;
 
-       default:                        /* not implemented */
-               return False;
+               default:        /* not implemented */
+                       return False;
        }
-       SSVALS(*rparam,0,desc.errcode);
-       SSVAL(*rparam,2,0);             /* converter word */
-       
-       return(True);
+
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);   /* converter word */
+
+       return (True);
 }
 
 
 /****************************************************************************
   get info about the server
   ****************************************************************************/
-static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                 int mdrcnt,int mprcnt,
-                                 char **rdata,char **rparam,
-                                 int *rdata_len,int *rparam_len)
+static BOOL api_RNetServerGetInfo(connection_struct * conn, uint16 vuid,
+                                 char *param, char *data, int mdrcnt,
+                                 int mprcnt, char **rdata, char **rparam,
+                                 int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel = SVAL(p,0);
-  char *p2;
-  int struct_len;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel = SVAL(p, 0);
+       char *p2;
+       int struct_len;
        VUSER_KEY;
 
-  DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
-
-  /* check it's a supported varient */
-  if (!prefix_ok(str1,"WrLh")) return False;
-  switch( uLevel ) {
-  case 0:
-    if (strcmp(str2,"B16") != 0) return False;
-    struct_len = 16;
-    break;
-  case 1:
-    if (strcmp(str2,"B16BBDz") != 0) return False;
-    struct_len = 26;
-    break;
-  case 2:
-    if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
-       != 0) return False;
-    struct_len = 134;
-    break;
-  case 3:
-    if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
-       != 0) return False;
-    struct_len = 144;
-    break;
-  case 20:
-    if (strcmp(str2,"DN") != 0) return False;
-    struct_len = 6;
-    break;
-  case 50:
-    if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
-    struct_len = 42;
-    break;
-  default: return False;
-  }
-
-  *rdata_len = mdrcnt;
-  *rdata = REALLOC(*rdata,*rdata_len);
-
-  p = *rdata;
-  p2 = p + struct_len;
-  if (uLevel != 20) {
-    StrnCpy(p,local_machine,16);
-    strupper(p);
-  }
-  p += 16;
-  if (uLevel > 0)
-    {
-      struct srv_info_struct *servers=NULL;
-      int i,count;
-      pstring comment;
-      uint32 servertype= lp_default_server_announce();
-
-      pstrcpy(comment,lp_serverstring());
-
-      if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
-       for (i=0;i<count;i++)
-         if (strequal(servers[i].name,local_machine))
-      {
-           servertype = servers[i].type;
-           pstrcpy(comment,servers[i].comment);            
-         }
-      }
-      if (servers) free(servers);
-
-      SCVAL(p,0,lp_major_announce_version());
-      SCVAL(p,1,lp_minor_announce_version());
-      SIVAL(p,2,servertype);
-
-      if (mdrcnt == struct_len) {
-       SIVAL(p,6,0);
-      } else {
-        user_struct *vuser = get_valid_user_struct(&key);
-       SIVAL(p,6,PTR_DIFF(p2,*rdata));
-       standard_sub(conn,vuser, comment);
-       StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
-       p2 = skip_string(p2,1);
-       vuid_free_user_struct(vuser);
+       DEBUG(4, ("NetServerGetInfo level %d\n", uLevel));
+
+       /* check it's a supported varient */
+       if (!prefix_ok(str1, "WrLh"))
+               return False;
+       switch (uLevel)
+       {
+               case 0:
+                       if (strcmp(str2, "B16") != 0)
+                               return False;
+                       struct_len = 16;
+                       break;
+               case 1:
+                       if (strcmp(str2, "B16BBDz") != 0)
+                               return False;
+                       struct_len = 26;
+                       break;
+               case 2:
+                       if (strcmp
+                           (str2,
+                            "B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
+                           != 0)
+                               return False;
+                       struct_len = 134;
+                       break;
+               case 3:
+                       if (strcmp
+                           (str2,
+                            "B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
+                           != 0)
+                               return False;
+                       struct_len = 144;
+                       break;
+               case 20:
+                       if (strcmp(str2, "DN") != 0)
+                               return False;
+                       struct_len = 6;
+                       break;
+               case 50:
+                       if (strcmp(str2, "B16BBDzWWzzz") != 0)
+                               return False;
+                       struct_len = 42;
+                       break;
+               default:
+                       return False;
+       }
+
+       *rdata_len = mdrcnt;
+       *rdata = REALLOC(*rdata, *rdata_len);
+
+       p = *rdata;
+       p2 = p + struct_len;
+       if (uLevel != 20)
+       {
+               StrnCpy(p, local_machine, 16);
+               strupper(p);
+       }
+       p += 16;
+       if (uLevel > 0)
+       {
+               struct srv_info_struct *servers = NULL;
+               int i, count;
+               pstring comment;
+               uint32 servertype = lp_default_server_announce();
+
+               pstrcpy(comment,
+                       string_truncate(lp_serverstring(),
+                                       MAX_SERVER_STRING_LENGTH));
+
+               if (
+                   (count =
+                    get_server_info(SV_TYPE_ALL, &servers,
+                                    global_myworkgroup)) > 0)
+               {
+                       for (i = 0; i < count; i++)
+                               if (strequal(servers[i].name, local_machine))
+                               {
+                                       servertype = servers[i].type;
+                                       pstrcpy(comment, servers[i].comment);
+                               }
+               }
+               if (servers)
+                       free(servers);
 
-      }
-    }
-  if (uLevel > 1)
-    {
-      return False;            /* not yet implemented */
-    }
+               SCVAL(p, 0, lp_major_announce_version());
+               SCVAL(p, 1, lp_minor_announce_version());
+               SIVAL(p, 2, servertype);
+
+               if (mdrcnt == struct_len)
+               {
+                       SIVAL(p, 6, 0);
+               }
+               else
+               {
+                       user_struct *vuser = get_valid_user_struct(&key);
+                       SIVAL(p, 6, PTR_DIFF(p2, *rdata));
+                       standard_sub(conn, vuser, comment);
+                       StrnCpy(p2, comment, MAX(mdrcnt - struct_len, 0));
+                       p2 = skip_string(p2, 1);
+                       vuid_free_user_struct(vuser);
+
+               }
+       }
+       if (uLevel > 1)
+       {
+               return False;   /* not yet implemented */
+       }
 
-  *rdata_len = PTR_DIFF(p2,*rdata);
+       *rdata_len = PTR_DIFF(p2, *rdata);
 
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
-  SSVAL(*rparam,4,*rdata_len);
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
+       SSVAL(*rparam, 4, *rdata_len);
 
-  return(True);
+       return (True);
 }
 
 
 /****************************************************************************
   get info about the server
   ****************************************************************************/
-static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_NetWkstaGetInfo(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  char *p2;
-  extern pstring sesssetup_user;
-  int level = SVAL(p,0);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       char *p2;
+       extern pstring sesssetup_user;
+       int level = SVAL(p, 0);
 
-  DEBUG(4,("NetWkstaGetInfo level %d\n",level));
+       DEBUG(4, ("NetWkstaGetInfo level %d\n", level));
 
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  /* check it's a supported varient */
-  if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
-    return(False);
+       /* check it's a supported varient */
+       if (!
+           (level == 10 && strcsequal(str1, "WrLh")
+            && strcsequal(str2, "zzzBBzz")))
+               return (False);
 
-  *rdata_len = mdrcnt + 1024;
-  *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata_len = mdrcnt + 1024;
+       *rdata = REALLOC(*rdata, *rdata_len);
 
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
-  p = *rdata;
-  p2 = p + 22;
+       p = *rdata;
+       p2 = p + 22;
 
 
-  SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
-  pstrcpy(p2,local_machine);
-  strupper(p2);
-  p2 = skip_string(p2,1);
-  p += 4;
+       SIVAL(p, 0, PTR_DIFF(p2, *rdata));      /* host name */
+       pstrcpy(p2, local_machine);
+       strupper(p2);
+       p2 = skip_string(p2, 1);
+       p += 4;
 
-  SIVAL(p,0,PTR_DIFF(p2,*rdata));
-  pstrcpy(p2,sesssetup_user);
-  p2 = skip_string(p2,1);
-  p += 4;
+       SIVAL(p, 0, PTR_DIFF(p2, *rdata));
+       pstrcpy(p2, sesssetup_user);
+       p2 = skip_string(p2, 1);
+       p += 4;
 
-  SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
-  pstrcpy(p2,global_myworkgroup);
-  strupper(p2);
-  p2 = skip_string(p2,1);
-  p += 4;
+       SIVAL(p, 0, PTR_DIFF(p2, *rdata));      /* login domain */
+       pstrcpy(p2, global_myworkgroup);
+       strupper(p2);
+       p2 = skip_string(p2, 1);
+       p += 4;
 
-  SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
-  SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
-  p += 2;
+       SCVAL(p, 0, lp_major_announce_version());       /* system version - e.g 4 in 4.1 */
+       SCVAL(p, 1, lp_minor_announce_version());       /* system version - e.g .1 in 4.1 */
+       p += 2;
 
-  SIVAL(p,0,PTR_DIFF(p2,*rdata));
-  pstrcpy(p2,global_myworkgroup);      /* don't know.  login domain?? */
-  p2 = skip_string(p2,1);
-  p += 4;
+       SIVAL(p, 0, PTR_DIFF(p2, *rdata));
+       pstrcpy(p2, global_myworkgroup);        /* don't know.  login domain?? */
+       p2 = skip_string(p2, 1);
+       p += 4;
 
-  SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
-  pstrcpy(p2,"");
-  p2 = skip_string(p2,1);
-  p += 4;
+       SIVAL(p, 0, PTR_DIFF(p2, *rdata));      /* don't know */
+       pstrcpy(p2, "");
+       p2 = skip_string(p2, 1);
+       p += 4;
 
-  *rdata_len = PTR_DIFF(p2,*rdata);
+       *rdata_len = PTR_DIFF(p2, *rdata);
 
-  SSVAL(*rparam,4,*rdata_len);
+       SSVAL(*rparam, 4, *rdata_len);
 
-  return(True);
+       return (True);
 }
 
 /****************************************************************************
@@ -2241,7 +2597,7 @@ There is no auxiliary data in the response.
 
   ****************************************************************************/
 
-#define usri11_name           0 
+#define usri11_name           0
 #define usri11_pad            21
 #define usri11_comment        22
 #define usri11_usr_comment    26
@@ -2268,22 +2624,22 @@ There is no auxiliary data in the response.
 #define USER_PRIV_USER 1
 #define USER_PRIV_ADMIN 2
 
-#define AF_OP_PRINT     0 
+#define AF_OP_PRINT     0
 #define AF_OP_COMM      1
 #define AF_OP_SERVER    2
 #define AF_OP_ACCOUNTS  3
 
 
-static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_RNetUserGetInfo(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-       char *str1 = param+2;
-       char *str2 = skip_string(str1,1);
-       char *UserName = skip_string(str2,1);
-       char *p = skip_string(UserName,1);
-       int uLevel = SVAL(p,0);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *UserName = skip_string(str2, 1);
+       char *p = skip_string(UserName, 1);
+       int uLevel = SVAL(p, 0);
        char *p2;
 
        fstring nt_name;
@@ -2292,27 +2648,38 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
        fstring home_dir;
        fstring logon_srv;
 
-    /* get NIS home of a previously validated user - simeon */
-    /* With share level security vuid will always be zero.
-       Don't depend on vuser being non-null !!. JRA */
-    user_struct *vuser = NULL;
-    /* moved here due to initialization code (req for IRIX cc) */
+       /* get NIS home of a previously validated user - simeon */
+       /* With share level security vuid will always be zero.
+          Don't depend on vuser being non-null !!. JRA */
+       user_struct *vuser = NULL;
+       /* moved here due to initialization code (req for IRIX cc) */
        VUSER_KEY;
 
-    *rparam_len = 6;
-    *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+
+       DEBUG(4, ("RNetUserGetInfo level=%d\n", uLevel));
 
-    DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
-  
        /* check it's a supported variant */
-       if (strcmp(str1,"zWrLh") != 0) return False;
-       switch( uLevel )
-       {
-               case 0: p2 = "B21"; break;
-               case 1: p2 = "B21BB16DWzzWz"; break;
-               case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
-               case 10: p2 = "B21Bzzz"; break;
-               case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
+       if (strcmp(str1, "zWrLh") != 0)
+               return False;
+       switch (uLevel)
+       {
+               case 0:
+                       p2 = "B21";
+                       break;
+               case 1:
+                       p2 = "B21BB16DWzzWz";
+                       break;
+               case 2:
+                       p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW";
+                       break;
+               case 10:
+                       p2 = "B21Bzzz";
+                       break;
+               case 11:
+                       p2 = "B21BzzzWDDzzDDWWzWzDWb21W";
+                       break;
                default:
                {
                        vuid_free_user_struct(vuser);
@@ -2320,788 +2687,888 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
                }
        }
 
-       if (strcmp(p2,str2) != 0)
+       if (strcmp(p2, str2) != 0)
+       {
+               return False;
+       }
+
+       vuser = get_valid_user_struct(&key);
+       if (vuser != NULL)
+       {
+               DEBUG(3,
+                     ("  Username of UID %d is %s\n", (int)vuser->uid,
+                      vuser->name));
+       }
+       else
        {
                return False;
        }
 
-    vuser = get_valid_user_struct(&key);
-    if (vuser != NULL)
-    {
-      DEBUG(3,("  Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
-    }
-    else
-    {
-       return False;
-    }
-
-       unistr2_to_ascii(full_name, &vuser->usr.uni_full_name, sizeof(full_name)-1);
-       unistr2_to_ascii(home_dir, &vuser->usr.uni_home_dir, sizeof(home_dir)-1);
-       unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
-       unistr2_to_ascii(logon_path, &vuser->usr.uni_logon_script, sizeof(logon_path)-1);
+       unistr2_to_ascii(full_name, &vuser->usr.uni_full_name,
+                        sizeof(full_name) - 1);
+       unistr2_to_ascii(home_dir, &vuser->usr.uni_home_dir,
+                        sizeof(home_dir) - 1);
+       unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name,
+                        sizeof(nt_name) - 1);
+       unistr2_to_ascii(logon_path, &vuser->usr.uni_logon_script,
+                        sizeof(logon_path) - 1);
        fstrcpy(logon_srv, "\\\\");
-       unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
+       unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv,
+                        sizeof(logon_srv) - 3);
 
        *rdata_len = mdrcnt + 1024;
-       *rdata = REALLOC(*rdata,*rdata_len);
+       *rdata = REALLOC(*rdata, *rdata_len);
 
-       SSVAL(*rparam,0,NERR_Success);
-       SSVAL(*rparam,2,0);             /* converter word */
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
        p = *rdata;
        p2 = p + usri11_end;
 
-       memset(p,0,21); 
-       fstrcpy(p+usri11_name,nt_name); /* 21 bytes - user name */
+       memset(p, 0, 21);
+       fstrcpy(p + usri11_name, nt_name);      /* 21 bytes - user name */
 
        if (uLevel > 0)
        {
-               SCVAL(p,usri11_pad,0); /* padding - 1 byte */
+               SCVAL(p, usri11_pad, 0);        /* padding - 1 byte */
                *p2 = 0;
        }
        if (uLevel >= 10)
        {
-               SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
+               SIVAL(p, usri11_comment, PTR_DIFF(p2, p));      /* comment */
                pstrcpy(p2, "");
-               p2 = skip_string(p2,1);
+               p2 = skip_string(p2, 1);
 
-               SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
+               SIVAL(p, usri11_usr_comment, PTR_DIFF(p2, p));  /* user_comment */
                pstrcpy(p2, "");
-               p2 = skip_string(p2,1);
+               p2 = skip_string(p2, 1);
 
                /* EEK! the cifsrap.txt doesn't have this in!!!! */
-               SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
+               SIVAL(p, usri11_full_name, PTR_DIFF(p2, p));    /* full name */
                pstrcpy(p2, full_name);
-               p2 = skip_string(p2,1);
+               p2 = skip_string(p2, 1);
        }
 
-       if (uLevel == 11) /* modelled after NTAS 3.51 reply */
-       {         
-               SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER); 
-               SIVAL(p,usri11_auth_flags,AF_OP_PRINT);         /* auth flags */
-               SIVALS(p,usri11_password_age,-1);               /* password age */
-               SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
+       if (uLevel == 11)       /* modelled after NTAS 3.51 reply */
+       {
+               SSVAL(p, usri11_priv,
+                     conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+               SIVAL(p, usri11_auth_flags, AF_OP_PRINT);       /* auth flags */
+               SIVALS(p, usri11_password_age, -1);     /* password age */
+               SIVAL(p, usri11_homedir, PTR_DIFF(p2, p));      /* home dir */
                pstrcpy(p2, home_dir);
-               p2 = skip_string(p2,1);
-               SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
-               pstrcpy(p2,"");
-               p2 = skip_string(p2,1);
-               SIVAL(p,usri11_last_logon,0);           /* last logon */
-               SIVAL(p,usri11_last_logoff,0);          /* last logoff */
-               SSVALS(p,usri11_bad_pw_count,vuser->usr.bad_pw_count);  /* bad pw counts */
-               SSVALS(p,usri11_num_logons,vuser->usr.logon_count);             /* num logons */
-               SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
-               pstrcpy(p2,logon_srv);
-               p2 = skip_string(p2,1);
-               SSVAL(p,usri11_country_code,0);         /* country code */
-
-               SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
+               p2 = skip_string(p2, 1);
+               SIVAL(p, usri11_parms, PTR_DIFF(p2, p));        /* parms */
                pstrcpy(p2, "");
-               p2 = skip_string(p2,1);
+               p2 = skip_string(p2, 1);
+               SIVAL(p, usri11_last_logon, 0); /* last logon */
+               SIVAL(p, usri11_last_logoff, 0);        /* last logoff */
+               SSVALS(p, usri11_bad_pw_count, vuser->usr.bad_pw_count);        /* bad pw counts */
+               SSVALS(p, usri11_num_logons, vuser->usr.logon_count);   /* num logons */
+               SIVAL(p, usri11_logon_server, PTR_DIFF(p2, p)); /* logon server */
+               pstrcpy(p2, logon_srv);
+               p2 = skip_string(p2, 1);
+               SSVAL(p, usri11_country_code, 0);       /* country code */
+
+               SIVAL(p, usri11_workstations, PTR_DIFF(p2, p)); /* workstations */
+               pstrcpy(p2, "");
+               p2 = skip_string(p2, 1);
 
-               SIVALS(p,usri11_max_storage,-1);                /* max storage */
-               SSVAL(p,usri11_units_per_week,168);             /* units per week */
-               SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
+               SIVALS(p, usri11_max_storage, -1);      /* max storage */
+               SSVAL(p, usri11_units_per_week, 168);   /* units per week */
+               SIVAL(p, usri11_logon_hours, PTR_DIFF(p2, p));  /* logon hours */
 
                /* a simple way to get logon hours at all times. */
-               memset(p2,0xff,21);
-               SCVAL(p2,21,0);           /* fix zero termination */
-               p2 = skip_string(p2,1);
+               memset(p2, 0xff, 21);
+               SCVAL(p2, 21, 0);       /* fix zero termination */
+               p2 = skip_string(p2, 1);
 
-               SSVAL(p,usri11_code_page,0);            /* code page */
+               SSVAL(p, usri11_code_page, 0);  /* code page */
        }
        if (uLevel == 1 || uLevel == 2)
        {
-               memset(p+22,' ',16);    /* password */
-               SIVALS(p,38,-1);                /* password age */
-               SSVAL(p,42,
-               conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
-               SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
-               pstrcpy(p2,logon_path);
-               p2 = skip_string(p2,1);
-               SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
+               memset(p + 22, ' ', 16);        /* password */
+               SIVALS(p, 38, -1);      /* password age */
+               SSVAL(p, 42,
+                     conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+               SIVAL(p, 44, PTR_DIFF(p2, *rdata));     /* home dir */
+               pstrcpy(p2, logon_path);
+               p2 = skip_string(p2, 1);
+               SIVAL(p, 48, PTR_DIFF(p2, *rdata));     /* comment */
                *p2++ = 0;
-               SSVAL(p,52,0);          /* flags */
-               SIVAL(p,54,0);          /* script_path */
+               SSVAL(p, 52, 0);        /* flags */
+               SIVAL(p, 54, 0);        /* script_path */
                if (uLevel == 2)
                {
-                       SIVAL(p,60,0);          /* auth_flags */
-                       SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
-                       pstrcpy(p2, nt_name);
-                       p2 = skip_string(p2,1);
-                       SIVAL(p,68,0);          /* urs_comment */
-                       SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
-                       pstrcpy(p2,"");
-                       p2 = skip_string(p2,1);
-                       SIVAL(p,76,0);          /* workstations */
-                       SIVAL(p,80,0);          /* last_logon */
-                       SIVAL(p,84,0);          /* last_logoff */
-                       SIVALS(p,88,-1);                /* acct_expires */
-                       SIVALS(p,92,-1);                /* max_storage */
-                       SSVAL(p,96,168);        /* units_per_week */
-                       SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
-                       memset(p2,-1,21);
+                       SIVAL(p, 60, 0);        /* auth_flags */
+                       SIVAL(p, 64, PTR_DIFF(p2, *rdata));     /* full_name */
+                       pstrcpy(p2, nt_name);
+                       p2 = skip_string(p2, 1);
+                       SIVAL(p, 68, 0);        /* urs_comment */
+                       SIVAL(p, 72, PTR_DIFF(p2, *rdata));     /* parms */
+                       pstrcpy(p2, "");
+                       p2 = skip_string(p2, 1);
+                       SIVAL(p, 76, 0);        /* workstations */
+                       SIVAL(p, 80, 0);        /* last_logon */
+                       SIVAL(p, 84, 0);        /* last_logoff */
+                       SIVALS(p, 88, -1);      /* acct_expires */
+                       SIVALS(p, 92, -1);      /* max_storage */
+                       SSVAL(p, 96, 168);      /* units_per_week */
+                       SIVAL(p, 98, PTR_DIFF(p2, *rdata));     /* logon_hours */
+                       memset(p2, -1, 21);
                        p2 += 21;
-                       SSVALS(p,102,vuser->usr.bad_pw_count);  /* bad_pw_count */
-                       SSVALS(p,104,vuser->usr.logon_count);   /* num_logons */
-                       SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
-                       pstrcpy(p2,logon_srv);
-                       p2 = skip_string(p2,1);
-                       SSVAL(p,110,49);        /* country_code */
-                       SSVAL(p,112,860);       /* code page */
+                       SSVALS(p, 102, vuser->usr.bad_pw_count);        /* bad_pw_count */
+                       SSVALS(p, 104, vuser->usr.logon_count); /* num_logons */
+                       SIVAL(p, 106, PTR_DIFF(p2, *rdata));    /* logon_server */
+                       pstrcpy(p2, logon_srv);
+                       p2 = skip_string(p2, 1);
+                       SSVAL(p, 110, 49);      /* country_code */
+                       SSVAL(p, 112, 860);     /* code page */
                }
        }
 
-       *rdata_len = PTR_DIFF(p2,*rdata);
+       *rdata_len = PTR_DIFF(p2, *rdata);
 
-       SSVAL(*rparam,4,*rdata_len);    /* is this right?? */
+       SSVAL(*rparam, 4, *rdata_len);  /* is this right?? */
 
        vuid_free_user_struct(vuser);
 
-       return(True);
+       return (True);
 }
 
 /*******************************************************************
   get groups that a user is a member of
   ******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_NetUserGetGroups(connection_struct * conn, uint16 vuid,
+                                char *param, char *data, int mdrcnt,
+                                int mprcnt, char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *UserName = skip_string(str2,1);
-  char *p = skip_string(UserName,1);
-  int uLevel = SVAL(p,0);
-  char *p2;
-  int count=0;
-
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-
-  /* check it's a supported varient */
-  if (strcmp(str1,"zWrLeh") != 0) return False;
-  switch( uLevel ) {
-  case 0: p2 = "B21"; break;
-  default: return False;
-  }
-  if (strcmp(p2,str2) != 0) return False;
-
-  *rdata_len = mdrcnt + 1024;
-  *rdata = REALLOC(*rdata,*rdata_len);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *UserName = skip_string(str2, 1);
+       char *p = skip_string(UserName, 1);
+       int uLevel = SVAL(p, 0);
+       char *p2;
+       int count = 0;
 
-  SSVAL(*rparam,0,NERR_Success);
-  SSVAL(*rparam,2,0);          /* converter word */
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  p = *rdata;
+       /* check it's a supported varient */
+       if (strcmp(str1, "zWrLeh") != 0)
+               return False;
+       switch (uLevel)
+       {
+               case 0:
+                       p2 = "B21";
+                       break;
+               default:
+                       return False;
+       }
+       if (strcmp(p2, str2) != 0)
+               return False;
 
-  /* XXXX we need a real SAM database some day */
-  pstrcpy(p,"Users"); p += 21; count++;
-  pstrcpy(p,"Domain Users"); p += 21; count++;
-  pstrcpy(p,"Guests"); p += 21; count++;
-  pstrcpy(p,"Domain Guests"); p += 21; count++;
+       *rdata_len = mdrcnt + 1024;
+       *rdata = REALLOC(*rdata, *rdata_len);
 
-  *rdata_len = PTR_DIFF(p,*rdata);
+       SSVAL(*rparam, 0, NERR_Success);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
-  SSVAL(*rparam,4,count);      /* is this right?? */
-  SSVAL(*rparam,6,count);      /* is this right?? */
+       p = *rdata;
 
-  return(True);
+       /* XXXX we need a real SAM database some day */
+       pstrcpy(p, "Users");
+       p += 21;
+       count++;
+       pstrcpy(p, "Domain Users");
+       p += 21;
+       count++;
+       pstrcpy(p, "Guests");
+       p += 21;
+       count++;
+       pstrcpy(p, "Domain Guests");
+       p += 21;
+       count++;
+
+       *rdata_len = PTR_DIFF(p, *rdata);
+
+       SSVAL(*rparam, 4, count);       /* is this right?? */
+       SSVAL(*rparam, 6, count);       /* is this right?? */
+
+       return (True);
 }
 
 
-static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_WWkstaUserLogon(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  struct pack_desc desc;
-  char* name;
-    user_struct *vuser;
-  VUSER_KEY;
-  vuser = get_valid_user_struct(&key); /* moved due to VUSER_KEY initialization */
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       struct pack_desc desc;
+       char *name;
+       user_struct *vuser;
+       VUSER_KEY;
+       vuser = get_valid_user_struct(&key);    /* moved due to VUSER_KEY initialization */
 
        if (vuser == NULL)
        {
                return False;
        }
 
-  uLevel = SVAL(p,0);
-  name = p + 2;
-
-  ZERO_STRUCT(desc);
-
-  DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
-
-  /* check it's a supported varient */
-  if (strcmp(str1,"OOWb54WrLh") != 0) return False;
-  if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  desc.subformat = NULL;
-  desc.format = str2;
-  
-  if (init_package(&desc,1,0))
-  {
-    fstring nt_name;
-    fstring logon_script;
-    fstring logon_srv;
-    fstring logon_dom;
-
-       unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
-       unistr2_to_ascii(logon_script, &vuser->usr.uni_logon_script, sizeof(logon_script)-1);
-       unistr2_to_ascii(logon_dom, &vuser->usr.uni_logon_dom, sizeof(logon_dom)-1);
-       fstrcpy(logon_srv, "\\\\");
-       unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
-
-    PACKI(&desc,"W",0);                /* code */
-    PACKS(&desc,"B21",nt_name);        /* eff. name */
-    PACKS(&desc,"B","");               /* pad */
-    PACKI(&desc,"W",
-         conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
-    PACKI(&desc,"D",0);                /* auth flags XXX */
-    PACKI(&desc,"W",0);                /* num logons */
-    PACKI(&desc,"W",0);                /* bad pw count */
-    PACKI(&desc,"D",0);                /* last logon */
-    PACKI(&desc,"D",-1);               /* last logoff */
-    PACKI(&desc,"D",-1);               /* logoff time */
-    PACKI(&desc,"D",-1);               /* kickoff time */
-    PACKI(&desc,"D",0);                /* password age */
-    PACKI(&desc,"D",0);                /* password can change */
-    PACKI(&desc,"D",-1);               /* password must change */
-    {
-      PACKS(&desc,"z",logon_srv); /* computer */
-    }
-    PACKS(&desc,"z",logon_dom);/* domain */
-    PACKS(&desc,"z", logon_script);            /* script path */
-
-    PACKI(&desc,"D",0x00000000);               /* reserved */
-  }
-
-  *rdata_len = desc.usedlen;
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,desc.neededlen);
-
-  DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
-  vuid_free_user_struct(vuser);
-
-  return(True);
+       uLevel = SVAL(p, 0);
+       name = p + 2;
+
+       ZERO_STRUCT(desc);
+
+       DEBUG(3, ("WWkstaUserLogon uLevel=%d name=%s\n", uLevel, name));
+
+       /* check it's a supported varient */
+       if (strcmp(str1, "OOWb54WrLh") != 0)
+               return False;
+       if (uLevel != 1 || strcmp(str2, "WB21BWDWWDDDDDDDzzzD") != 0)
+               return False;
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       desc.subformat = NULL;
+       desc.format = str2;
+
+       if (init_package(&desc, 1, 0))
+       {
+               fstring nt_name;
+               fstring logon_script;
+               fstring logon_srv;
+               fstring logon_dom;
+
+               unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name,
+                                sizeof(nt_name) - 1);
+               unistr2_to_ascii(logon_script, &vuser->usr.uni_logon_script,
+                                sizeof(logon_script) - 1);
+               unistr2_to_ascii(logon_dom, &vuser->usr.uni_logon_dom,
+                                sizeof(logon_dom) - 1);
+               fstrcpy(logon_srv, "\\\\");
+               unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv,
+                                sizeof(logon_srv) - 3);
+
+               PACKI(&desc, "W", 0);   /* code */
+               PACKS(&desc, "B21", nt_name);   /* eff. name */
+               PACKS(&desc, "B", "");  /* pad */
+               PACKI(&desc, "W",
+                     conn->admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER);
+               PACKI(&desc, "D", 0);   /* auth flags XXX */
+               PACKI(&desc, "W", 0);   /* num logons */
+               PACKI(&desc, "W", 0);   /* bad pw count */
+               PACKI(&desc, "D", 0);   /* last logon */
+               PACKI(&desc, "D", -1);  /* last logoff */
+               PACKI(&desc, "D", -1);  /* logoff time */
+               PACKI(&desc, "D", -1);  /* kickoff time */
+               PACKI(&desc, "D", 0);   /* password age */
+               PACKI(&desc, "D", 0);   /* password can change */
+               PACKI(&desc, "D", -1);  /* password must change */
+               {
+                       PACKS(&desc, "z", logon_srv);   /* computer */
+               }
+               PACKS(&desc, "z", logon_dom);   /* domain */
+               PACKS(&desc, "z", logon_script);        /* script path */
+
+               PACKI(&desc, "D", 0x00000000);  /* reserved */
+       }
+
+       *rdata_len = desc.usedlen;
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, desc.neededlen);
+
+       DEBUG(4, ("WWkstaUserLogon: errorcode %d\n", desc.errcode));
+       vuid_free_user_struct(vuser);
+
+       return (True);
 }
 
 
 /****************************************************************************
   api_WAccessGetUserPerms
   ****************************************************************************/
-static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                   int mdrcnt,int mprcnt,
-                                   char **rdata,char **rparam,
-                                   int *rdata_len,int *rparam_len)
+static BOOL api_WAccessGetUserPerms(connection_struct * conn, uint16 vuid,
+                                   char *param, char *data, int mdrcnt,
+                                   int mprcnt, char **rdata, char **rparam,
+                                   int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *user = skip_string(str2,1);
-  char *resource = skip_string(user,1);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *user = skip_string(str2, 1);
+       char *resource = skip_string(user, 1);
 
-  DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
+       DEBUG(3,
+             ("WAccessGetUserPerms user=%s resource=%s\n", user, resource));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"zzh") != 0) return False;
-  if (strcmp(str2,"") != 0) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "zzh") != 0)
+               return False;
+       if (strcmp(str2, "") != 0)
+               return False;
 
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,0);         /* errorcode */
-  SSVAL(*rparam,2,0);          /* converter word */
-  SSVAL(*rparam,4,0x7f);       /* permission flags */
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, 0);  /* errorcode */
+       SSVAL(*rparam, 2, 0);   /* converter word */
+       SSVAL(*rparam, 4, 0x7f);        /* permission flags */
 
-  return(True);
+       return (True);
 }
 
 /****************************************************************************
   api_WPrintJobEnumerate
   ****************************************************************************/
-static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobGetInfo(connection_struct * conn, uint16 vuid,
+                                char *param, char *data, int mdrcnt,
+                                int mprcnt, char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  int count;
-  int i;
-  int snum;
-  int job;
-  struct pack_desc desc;
-  print_queue_struct *queue=NULL;
-  print_status_struct status;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       int count;
+       int i;
+       int snum;
+       int job;
+       struct pack_desc desc;
+       print_queue_struct *queue = NULL;
+       print_status_struct status;
        VUSER_KEY;
 
-  uLevel = SVAL(p,2);
+       uLevel = SVAL(p, 2);
 
-  ZERO_STRUCT(desc);
-  ZERO_STRUCT(status);
+       ZERO_STRUCT(desc);
+       ZERO_STRUCT(status);
 
-  DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
+       DEBUG(3,
+             ("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n", uLevel,
+              SVAL(p, 0)));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"WWrLh") != 0) return False;
-  if (!check_printjob_info(&desc,uLevel,str2)) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "WWrLh") != 0)
+               return False;
+       if (!check_printjob_info(&desc, uLevel, str2))
+               return False;
 
-  printjob_decode(SVAL(p,0), &snum, &job);
+       printjob_decode(SVAL(p, 0), &snum, &job);
 
-  if (snum < 0 || !VALID_SNUM(snum)) return(False);
+       if (snum < 0 || !VALID_SNUM(snum))
+               return (False);
 
-  count = get_printqueue(snum,conn,&key,&queue,&status);
-  for (i = 0; i < count; i++) {
-    if ((queue[i].job & 0xFF) == job) break;
-  }
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
+       count = get_printqueue(snum, conn, &key, &queue, &status);
+       for (i = 0; i < count; i++)
+       {
+               if ((queue[i].job & 0xFF) == job)
+                       break;
+       }
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
 
-  if (init_package(&desc,1,0)) {
-    if (i < count) {
-      fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
-      *rdata_len = desc.usedlen;
-    }
-    else {
-      desc.errcode = NERR_JobNotFound;
-      *rdata_len = 0;
-    }
-  }
+       if (init_package(&desc, 1, 0))
+       {
+               if (i < count)
+               {
+                       fill_printjob_info(conn, snum, uLevel, &desc,
+                                          &queue[i], i);
+                       *rdata_len = desc.usedlen;
+               }
+               else
+               {
+                       desc.errcode = NERR_JobNotFound;
+                       *rdata_len = 0;
+               }
+       }
 
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,desc.neededlen);
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, desc.neededlen);
 
-  if (queue) free(queue);
+       if (queue)
+               free(queue);
 
-  DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
-  return(True);
+       DEBUG(4, ("WPrintJobGetInfo: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                  int mdrcnt,int mprcnt,
-                                  char **rdata,char **rparam,
-                                  int *rdata_len,int *rparam_len)
+static BOOL api_WPrintJobEnumerate(connection_struct * conn, uint16 vuid,
+                                  char *param, char *data, int mdrcnt,
+                                  int mprcnt, char **rdata, char **rparam,
+                                  int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  char* name = p;
-  int uLevel;
-  int count;
-  int i, succnt=0;
-  int snum;
-  struct pack_desc desc;
-  print_queue_struct *queue=NULL;
-  print_status_struct status;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       char *name = p;
+       int uLevel;
+       int count;
+       int i, succnt = 0;
+       int snum;
+       struct pack_desc desc;
+       print_queue_struct *queue = NULL;
+       print_status_struct status;
        VUSER_KEY;
 
-  ZERO_STRUCT(desc);
-  ZERO_STRUCT(status);
+       ZERO_STRUCT(desc);
+       ZERO_STRUCT(status);
 
-  p = skip_string(p,1);
-  uLevel = SVAL(p,0);
+       p = skip_string(p, 1);
+       uLevel = SVAL(p, 0);
 
-  DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
+       DEBUG(3, ("WPrintJobEnumerate uLevel=%d name=%s\n", uLevel, name));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"zWrLeh") != 0) return False;
-  if (uLevel > 2) return False;        /* defined only for uLevel 0,1,2 */
-  if (!check_printjob_info(&desc,uLevel,str2)) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "zWrLeh") != 0)
+               return False;
+       if (uLevel > 2)
+               return False;   /* defined only for uLevel 0,1,2 */
+       if (!check_printjob_info(&desc, uLevel, str2))
+               return False;
 
-  snum = lp_servicenumber(name);
-  if (snum < 0 && pcap_printername_ok(name,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(name,pnum);
-      snum = lp_servicenumber(name);
-    }
-  }
+       snum = lp_servicenumber(name);
+       if (snum < 0 && pcap_printername_ok(name, NULL))
+       {
+               int pnum = lp_servicenumber(PRINTERS_NAME);
+               if (pnum >= 0)
+               {
+                       lp_add_printer(name, pnum);
+                       snum = lp_servicenumber(name);
+               }
+       }
 
-  if (snum < 0 || !VALID_SNUM(snum)) return(False);
+       if (snum < 0 || !VALID_SNUM(snum))
+               return (False);
 
-  count = get_printqueue(snum,conn,&key,&queue,&status);
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
+       count = get_printqueue(snum, conn, &key, &queue, &status);
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
 
-  if (init_package(&desc,count,0)) {
-    succnt = 0;
-    for (i = 0; i < count; i++) {
-      fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
-      if (desc.errcode == NERR_Success) succnt = i+1;
-    }
-  }
+       if (init_package(&desc, count, 0))
+       {
+               succnt = 0;
+               for (i = 0; i < count; i++)
+               {
+                       fill_printjob_info(conn, snum, uLevel, &desc,
+                                          &queue[i], i);
+                       if (desc.errcode == NERR_Success)
+                               succnt = i + 1;
+               }
+       }
 
-  *rdata_len = desc.usedlen;
+       *rdata_len = desc.usedlen;
 
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,count);
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, count);
 
-  if (queue) free(queue);
+       if (queue)
+               free(queue);
 
-  DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
-  return(True);
+       DEBUG(4, ("WPrintJobEnumerate: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static int check_printdest_info(struct pack_desc* desc,
-                               int uLevel, char* id)
+static int check_printdest_info(struct pack_desc *desc, int uLevel, char *id)
 {
-  desc->subformat = NULL;
-  switch( uLevel ) {
-  case 0: desc->format = "B9"; break;
-  case 1: desc->format = "B9B21WWzW"; break;
-  case 2: desc->format = "z"; break;
-  case 3: desc->format = "zzzWWzzzWW"; break;
-  default: return False;
-  }
-  if (strcmp(desc->format,id) != 0) return False;
-  return True;
+       desc->subformat = NULL;
+       switch (uLevel)
+       {
+               case 0:
+                       desc->format = "B9";
+                       break;
+               case 1:
+                       desc->format = "B9B21WWzW";
+                       break;
+               case 2:
+                       desc->format = "z";
+                       break;
+               case 3:
+                       desc->format = "zzzWWzzzWW";
+                       break;
+               default:
+                       return False;
+       }
+       if (strcmp(desc->format, id) != 0)
+               return False;
+       return True;
 }
 
-static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
-                               struct pack_desc* desc)
+static void fill_printdest_info(connection_struct * conn, int snum,
+                               int uLevel, struct pack_desc *desc)
 {
-  char buf[100];
-  strncpy(buf,SERVICE(snum),sizeof(buf)-1);
-  buf[sizeof(buf)-1] = 0;
-  strupper(buf);
-  if (uLevel <= 1) {
-    PACKS(desc,"B9",buf);      /* szName */
-    if (uLevel == 1) {
-      PACKS(desc,"B21","");    /* szUserName */
-      PACKI(desc,"W",0);               /* uJobId */
-      PACKI(desc,"W",0);               /* fsStatus */
-      PACKS(desc,"z","");      /* pszStatus */
-      PACKI(desc,"W",0);               /* time */
-    }
-  }
-  if (uLevel == 2 || uLevel == 3) {
-    PACKS(desc,"z",buf);               /* pszPrinterName */
-    if (uLevel == 3) {
-      PACKS(desc,"z","");      /* pszUserName */
-      PACKS(desc,"z","");      /* pszLogAddr */
-      PACKI(desc,"W",0);               /* uJobId */
-      PACKI(desc,"W",0);               /* fsStatus */
-      PACKS(desc,"z","");      /* pszStatus */
-      PACKS(desc,"z","");      /* pszComment */
-      PACKS(desc,"z","NULL"); /* pszDrivers */
-      PACKI(desc,"W",0);               /* time */
-      PACKI(desc,"W",0);               /* pad1 */
-    }
-  }
+       char buf[100];
+       strncpy(buf, SERVICE(snum), sizeof(buf) - 1);
+       buf[sizeof(buf) - 1] = 0;
+       strupper(buf);
+       if (uLevel <= 1)
+       {
+               PACKS(desc, "B9", buf); /* szName */
+               if (uLevel == 1)
+               {
+                       PACKS(desc, "B21", ""); /* szUserName */
+                       PACKI(desc, "W", 0);    /* uJobId */
+                       PACKI(desc, "W", 0);    /* fsStatus */
+                       PACKS(desc, "z", "");   /* pszStatus */
+                       PACKI(desc, "W", 0);    /* time */
+               }
+       }
+       if (uLevel == 2 || uLevel == 3)
+       {
+               PACKS(desc, "z", buf);  /* pszPrinterName */
+               if (uLevel == 3)
+               {
+                       PACKS(desc, "z", "");   /* pszUserName */
+                       PACKS(desc, "z", "");   /* pszLogAddr */
+                       PACKI(desc, "W", 0);    /* uJobId */
+                       PACKI(desc, "W", 0);    /* fsStatus */
+                       PACKS(desc, "z", "");   /* pszStatus */
+                       PACKS(desc, "z", "");   /* pszComment */
+                       PACKS(desc, "z", "NULL");       /* pszDrivers */
+                       PACKI(desc, "W", 0);    /* time */
+                       PACKI(desc, "W", 0);    /* pad1 */
+               }
+       }
 }
 
-static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                 int mdrcnt,int mprcnt,
-                                 char **rdata,char **rparam,
-                                 int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestGetInfo(connection_struct * conn, uint16 vuid,
+                                 char *param, char *data, int mdrcnt,
+                                 int mprcnt, char **rdata, char **rparam,
+                                 int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  char* PrinterName = p;
-  int uLevel;
-  struct pack_desc desc;
-  int snum;
-
-  ZERO_STRUCT(desc);
-
-  p = skip_string(p,1);
-  uLevel = SVAL(p,0);
-
-  DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
-
-  /* check it's a supported varient */
-  if (strcmp(str1,"zWrLh") != 0) return False;
-  if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
-  snum = lp_servicenumber(PrinterName);
-  if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
-    int pnum = lp_servicenumber(PRINTERS_NAME);
-    if (pnum >= 0) {
-      lp_add_printer(PrinterName,pnum);
-      snum = lp_servicenumber(PrinterName);
-    }
-  }
-
-  if (snum < 0) {
-    *rdata_len = 0;
-    desc.errcode = NERR_DestNotFound;
-    desc.neededlen = 0;
-  }
-  else {
-    if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-    desc.base = *rdata;
-    desc.buflen = mdrcnt;
-    if (init_package(&desc,1,0)) {
-      fill_printdest_info(conn,snum,uLevel,&desc);
-    }
-    *rdata_len = desc.usedlen;
-  }
-
-  *rparam_len = 6;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,desc.neededlen);
-
-  DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
-  return(True);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       char *PrinterName = p;
+       int uLevel;
+       struct pack_desc desc;
+       int snum;
+
+       ZERO_STRUCT(desc);
+
+       p = skip_string(p, 1);
+       uLevel = SVAL(p, 0);
+
+       DEBUG(3,
+             ("WPrintDestGetInfo uLevel=%d PrinterName=%s\n", uLevel,
+              PrinterName));
+
+       /* check it's a supported varient */
+       if (strcmp(str1, "zWrLh") != 0)
+               return False;
+       if (!check_printdest_info(&desc, uLevel, str2))
+               return False;
+
+       snum = lp_servicenumber(PrinterName);
+       if (snum < 0 && pcap_printername_ok(PrinterName, NULL))
+       {
+               int pnum = lp_servicenumber(PRINTERS_NAME);
+               if (pnum >= 0)
+               {
+                       lp_add_printer(PrinterName, pnum);
+                       snum = lp_servicenumber(PrinterName);
+               }
+       }
+
+       if (snum < 0)
+       {
+               *rdata_len = 0;
+               desc.errcode = NERR_DestNotFound;
+               desc.neededlen = 0;
+       }
+       else
+       {
+               if (mdrcnt > 0)
+                       *rdata = REALLOC(*rdata, mdrcnt);
+               desc.base = *rdata;
+               desc.buflen = mdrcnt;
+               if (init_package(&desc, 1, 0))
+               {
+                       fill_printdest_info(conn, snum, uLevel, &desc);
+               }
+               *rdata_len = desc.usedlen;
+       }
+
+       *rparam_len = 6;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, desc.neededlen);
+
+       DEBUG(4, ("WPrintDestGetInfo: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
-                              int mdrcnt,int mprcnt,
-                              char **rdata,char **rparam,
-                              int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDestEnum(connection_struct * conn, uint16 vuid,
+                              char *param, char *data, int mdrcnt,
+                              int mprcnt, char **rdata, char **rparam,
+                              int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  int queuecnt;
-  int i, n, succnt=0;
-  struct pack_desc desc;
-  int services = lp_numservices();
-
-  ZERO_STRUCT(desc);
-
-  uLevel = SVAL(p,0);
-
-  DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
-
-  /* check it's a supported varient */
-  if (strcmp(str1,"WrLeh") != 0) return False;
-  if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
-  queuecnt = 0;
-  for (i = 0; i < services; i++)
-    if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
-      queuecnt++;
-
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  if (init_package(&desc,queuecnt,0)) {    
-    succnt = 0;
-    n = 0;
-    for (i = 0; i < services; i++) {
-      if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
-       fill_printdest_info(conn,i,uLevel,&desc);
-       n++;
-       if (desc.errcode == NERR_Success) succnt = n;
-      }
-    }
-  }
-
-  *rdata_len = desc.usedlen;
-
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,queuecnt);
-
-  DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
-  return(True);
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       int queuecnt;
+       int i, n, succnt = 0;
+       struct pack_desc desc;
+       int services = lp_numservices();
+
+       ZERO_STRUCT(desc);
+
+       uLevel = SVAL(p, 0);
+
+       DEBUG(3, ("WPrintDestEnum uLevel=%d\n", uLevel));
+
+       /* check it's a supported varient */
+       if (strcmp(str1, "WrLeh") != 0)
+               return False;
+       if (!check_printdest_info(&desc, uLevel, str2))
+               return False;
+
+       queuecnt = 0;
+       for (i = 0; i < services; i++)
+               if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+                       queuecnt++;
+
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       if (init_package(&desc, queuecnt, 0))
+       {
+               succnt = 0;
+               n = 0;
+               for (i = 0; i < services; i++)
+               {
+                       if (lp_snum_ok(i) && lp_print_ok(i)
+                           && lp_browseable(i))
+                       {
+                               fill_printdest_info(conn, i, uLevel, &desc);
+                               n++;
+                               if (desc.errcode == NERR_Success)
+                                       succnt = n;
+                       }
+               }
+       }
+
+       *rdata_len = desc.usedlen;
+
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, queuecnt);
+
+       DEBUG(4, ("WPrintDestEnumerate: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
-                                int mdrcnt,int mprcnt,
-                                char **rdata,char **rparam,
-                                int *rdata_len,int *rparam_len)
+static BOOL api_WPrintDriverEnum(connection_struct * conn, uint16 vuid,
+                                char *param, char *data, int mdrcnt,
+                                int mprcnt, char **rdata, char **rparam,
+                                int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  int succnt;
-  struct pack_desc desc;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       int succnt;
+       struct pack_desc desc;
 
-  ZERO_STRUCT(desc);
+       ZERO_STRUCT(desc);
 
-  uLevel = SVAL(p,0);
+       uLevel = SVAL(p, 0);
 
-  DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
+       DEBUG(3, ("WPrintDriverEnum uLevel=%d\n", uLevel));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"WrLeh") != 0) return False;
-  if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "WrLeh") != 0)
+               return False;
+       if (uLevel != 0 || strcmp(str2, "B41") != 0)
+               return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  if (init_package(&desc,1,0)) {
-    PACKS(&desc,"B41","NULL");
-  }
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       if (init_package(&desc, 1, 0))
+       {
+               PACKS(&desc, "B41", "NULL");
+       }
 
-  succnt = (desc.errcode == NERR_Success ? 1 : 0);
+       succnt = (desc.errcode == NERR_Success ? 1 : 0);
 
-  *rdata_len = desc.usedlen;
+       *rdata_len = desc.usedlen;
 
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,1);
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, 1);
 
-  DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
-  return(True);
+       DEBUG(4, ("WPrintDriverEnum: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
-                               int mdrcnt,int mprcnt,
-                               char **rdata,char **rparam,
-                               int *rdata_len,int *rparam_len)
+static BOOL api_WPrintQProcEnum(connection_struct * conn, uint16 vuid,
+                               char *param, char *data, int mdrcnt,
+                               int mprcnt, char **rdata, char **rparam,
+                               int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  int succnt;
-  struct pack_desc desc;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       int succnt;
+       struct pack_desc desc;
 
-  ZERO_STRUCT(desc);
+       ZERO_STRUCT(desc);
 
-  uLevel = SVAL(p,0);
+       uLevel = SVAL(p, 0);
 
-  DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
+       DEBUG(3, ("WPrintQProcEnum uLevel=%d\n", uLevel));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"WrLeh") != 0) return False;
-  if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "WrLeh") != 0)
+               return False;
+       if (uLevel != 0 || strcmp(str2, "B13") != 0)
+               return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  desc.format = str2;
-  if (init_package(&desc,1,0)) {
-    PACKS(&desc,"B13","lpd");
-  }
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       desc.format = str2;
+       if (init_package(&desc, 1, 0))
+       {
+               PACKS(&desc, "B13", "lpd");
+       }
 
-  succnt = (desc.errcode == NERR_Success ? 1 : 0);
+       succnt = (desc.errcode == NERR_Success ? 1 : 0);
 
-  *rdata_len = desc.usedlen;
+       *rdata_len = desc.usedlen;
 
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,1);
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, 1);
 
-  DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
-  return(True);
+       DEBUG(4, ("WPrintQProcEnum: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
-static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
-                              int mdrcnt,int mprcnt,
-                              char **rdata,char **rparam,
-                              int *rdata_len,int *rparam_len)
+static BOOL api_WPrintPortEnum(connection_struct * conn, uint16 vuid,
+                              char *param, char *data, int mdrcnt,
+                              int mprcnt, char **rdata, char **rparam,
+                              int *rdata_len, int *rparam_len)
 {
-  char *str1 = param+2;
-  char *str2 = skip_string(str1,1);
-  char *p = skip_string(str2,1);
-  int uLevel;
-  int succnt;
-  struct pack_desc desc;
+       char *str1 = param + 2;
+       char *str2 = skip_string(str1, 1);
+       char *p = skip_string(str2, 1);
+       int uLevel;
+       int succnt;
+       struct pack_desc desc;
 
-  ZERO_STRUCT(desc);
+       ZERO_STRUCT(desc);
 
-  uLevel = SVAL(p,0);
+       uLevel = SVAL(p, 0);
 
-  DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
+       DEBUG(3, ("WPrintPortEnum uLevel=%d\n", uLevel));
 
-  /* check it's a supported varient */
-  if (strcmp(str1,"WrLeh") != 0) return False;
-  if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
+       /* check it's a supported varient */
+       if (strcmp(str1, "WrLeh") != 0)
+               return False;
+       if (uLevel != 0 || strcmp(str2, "B9") != 0)
+               return False;
 
-  if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  ZERO_STRUCT(desc);
-  desc.base = *rdata;
-  desc.buflen = mdrcnt;
-  desc.format = str2;
-  if (init_package(&desc,1,0)) {
-    PACKS(&desc,"B13","lp0");
-  }
+       if (mdrcnt > 0)
+               *rdata = REALLOC(*rdata, mdrcnt);
+       ZERO_STRUCT(desc);
+       desc.base = *rdata;
+       desc.buflen = mdrcnt;
+       desc.format = str2;
+       if (init_package(&desc, 1, 0))
+       {
+               PACKS(&desc, "B13", "lp0");
+       }
 
-  succnt = (desc.errcode == NERR_Success ? 1 : 0);
+       succnt = (desc.errcode == NERR_Success ? 1 : 0);
 
-  *rdata_len = desc.usedlen;
+       *rdata_len = desc.usedlen;
 
-  *rparam_len = 8;
-  *rparam = REALLOC(*rparam,*rparam_len);
-  SSVALS(*rparam,0,desc.errcode);
-  SSVAL(*rparam,2,0);
-  SSVAL(*rparam,4,succnt);
-  SSVAL(*rparam,6,1);
+       *rparam_len = 8;
+       *rparam = REALLOC(*rparam, *rparam_len);
+       SSVALS(*rparam, 0, desc.errcode);
+       SSVAL(*rparam, 2, 0);
+       SSVAL(*rparam, 4, succnt);
+       SSVAL(*rparam, 6, 1);
 
-  DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
-  return(True);
+       DEBUG(4, ("WPrintPortEnum: errorcode %d\n", desc.errcode));
+       return (True);
 }
 
 
 /****************************************************************************
 the buffer was too small
The buffer was too small
   ****************************************************************************/
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
-                        int mdrcnt,int mprcnt,
-                        char **rdata,char **rparam,
-                        int *rdata_len,int *rparam_len)
+static BOOL api_TooSmall(connection_struct * conn, uint16 vuid, char *param,
+                        char *data, int mdrcnt, int mprcnt, char **rdata,
+                        char **rparam, int *rdata_len, int *rparam_len)
 {
-  *rparam_len = MIN(*rparam_len,mprcnt);
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = MIN(*rparam_len, mprcnt);
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_BufTooSmall);
+       SSVAL(*rparam, 0, NERR_BufTooSmall);
 
-  DEBUG(3,("Supplied buffer too small in API command\n"));
+       DEBUG(3, ("Supplied buffer too small in API command\n"));
 
-  return(True);
+       return (True);
 }
 
 
 /****************************************************************************
 the request is not supported
The request is not supported
   ****************************************************************************/
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
-                           int mdrcnt,int mprcnt,
-                           char **rdata,char **rparam,
-                           int *rdata_len,int *rparam_len)
+static BOOL api_Unsupported(connection_struct * conn, uint16 vuid,
+                           char *param, char *data, int mdrcnt, int mprcnt,
+                           char **rdata, char **rparam, int *rdata_len,
+                           int *rparam_len)
 {
-  *rparam_len = 4;
-  *rparam = REALLOC(*rparam,*rparam_len);
+       *rparam_len = 4;
+       *rparam = REALLOC(*rparam, *rparam_len);
 
-  *rdata_len = 0;
+       *rdata_len = 0;
 
-  SSVAL(*rparam,0,NERR_notsupported);
-  SSVAL(*rparam,2,0);          /* converter word */
+       SSVAL(*rparam, 0, NERR_notsupported);
+       SSVAL(*rparam, 2, 0);   /* converter word */
 
-  DEBUG(3,("Unsupported API command\n"));
+       DEBUG(3, ("Unsupported API command\n"));
 
-  return(True);
+       return (True);
 }
 
 
@@ -3109,111 +3576,179 @@ static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,cha
 
 struct
 {
-  char *name;
-  int id;
-  BOOL (*fn)(connection_struct *,uint16,char *,char *,
-            int,int,char **,char **,int *,int *);
-  int flags;
-} api_commands[] = {
-  {"RNetShareEnum",    0,      api_RNetShareEnum,0},
-  {"RNetShareGetInfo", 1,      api_RNetShareGetInfo,0},
-  {"RNetServerGetInfo",        13,     api_RNetServerGetInfo,0},
-  {"RNetGroupGetUsers", 52,    api_RNetGroupGetUsers,0},
-  {"RNetUserGetInfo",  56,     api_RNetUserGetInfo,0},
-  {"NetUserGetGroups", 59,     api_NetUserGetGroups,0},
-  {"NetWkstaGetInfo",  63,     api_NetWkstaGetInfo,0},
-  {"DosPrintQEnum",    69,     api_DosPrintQEnum,0},
-  {"DosPrintQGetInfo", 70,     api_DosPrintQGetInfo,0},
-  {"WPrintQueuePause",  74, api_WPrintQueuePurge,0},
-  {"WPrintQueueResume", 75, api_WPrintQueuePurge,0},
-  {"WPrintJobEnumerate",76,    api_WPrintJobEnumerate,0},
-  {"WPrintJobGetInfo", 77,     api_WPrintJobGetInfo,0},
-  {"RDosPrintJobDel",  81,     api_RDosPrintJobDel,0},
-  {"RDosPrintJobPause",        82,     api_RDosPrintJobDel,0},
-  {"RDosPrintJobResume",83,    api_RDosPrintJobDel,0},
-  {"WPrintDestEnum",   84,     api_WPrintDestEnum,0},
-  {"WPrintDestGetInfo",        85,     api_WPrintDestGetInfo,0},
-  {"NetRemoteTOD",     91,     api_NetRemoteTOD,0},
-  {"WPrintQueuePurge", 103,    api_WPrintQueuePurge,0},
-  {"NetServerEnum",    104,    api_RNetServerEnum,0},
-  {"WAccessGetUserPerms",105,  api_WAccessGetUserPerms,0},
-  {"SetUserPassword",  115,    api_SetUserPassword,0},
-  {"WWkstaUserLogon",  132,    api_WWkstaUserLogon,0},
-  {"PrintJobInfo",     147,    api_PrintJobInfo,0},
-  {"WPrintDriverEnum", 205,    api_WPrintDriverEnum,0},
-  {"WPrintQProcEnum",  206,    api_WPrintQProcEnum,0},
-  {"WPrintPortEnum",   207,    api_WPrintPortEnum,0},
-  {"SamOEMChangePassword", 214, api_SamOEMChangePassword,0},
-  {NULL,               -1,     api_Unsupported,0}};
+       char *name;
+       int id;
+       BOOL (*fn) (connection_struct *, uint16, char *, char *,
+                   int, int, char **, char **, int *, int *);
+       int flags;
+} api_commands[] =
+{
+       {
+       "RNetShareEnum", 0, api_RNetShareEnum, 0}
+       ,
+       {
+       "RNetShareGetInfo", 1, api_RNetShareGetInfo, 0}
+       ,
+       {
+       "RNetServerGetInfo", 13, api_RNetServerGetInfo, 0}
+       ,
+       {
+       "RNetGroupGetUsers", 52, api_RNetGroupGetUsers, 0}
+       ,
+       {
+       "RNetUserGetInfo", 56, api_RNetUserGetInfo, 0}
+       ,
+       {
+       "NetUserGetGroups", 59, api_NetUserGetGroups, 0}
+       ,
+       {
+       "NetWkstaGetInfo", 63, api_NetWkstaGetInfo, 0}
+       ,
+       {
+       "DosPrintQEnum", 69, api_DosPrintQEnum, 0}
+       ,
+       {
+       "DosPrintQGetInfo", 70, api_DosPrintQGetInfo, 0}
+       ,
+       {
+       "WPrintQueuePause", 74, api_WPrintQueuePurge, 0}
+       ,
+       {
+       "WPrintQueueResume", 75, api_WPrintQueuePurge, 0}
+       ,
+       {
+       "WPrintJobEnumerate", 76, api_WPrintJobEnumerate, 0}
+       ,
+       {
+       "WPrintJobGetInfo", 77, api_WPrintJobGetInfo, 0}
+       ,
+       {
+       "RDosPrintJobDel", 81, api_RDosPrintJobDel, 0}
+       ,
+       {
+       "RDosPrintJobPause", 82, api_RDosPrintJobDel, 0}
+       ,
+       {
+       "RDosPrintJobResume", 83, api_RDosPrintJobDel, 0}
+       ,
+       {
+       "WPrintDestEnum", 84, api_WPrintDestEnum, 0}
+       ,
+       {
+       "WPrintDestGetInfo", 85, api_WPrintDestGetInfo, 0}
+       ,
+       {
+       "NetRemoteTOD", 91, api_NetRemoteTOD, 0}
+       ,
+       {
+       "WPrintQueuePurge", 103, api_WPrintQueuePurge, 0}
+       ,
+       {
+       "NetServerEnum", 104, api_RNetServerEnum, 0}
+       ,
+       {
+       "WAccessGetUserPerms", 105, api_WAccessGetUserPerms, 0}
+       ,
+       {
+       "SetUserPassword", 115, api_SetUserPassword, 0}
+       ,
+       {
+       "WWkstaUserLogon", 132, api_WWkstaUserLogon, 0}
+       ,
+       {
+       "PrintJobInfo", 147, api_PrintJobInfo, 0}
+       ,
+       {
+       "WPrintDriverEnum", 205, api_WPrintDriverEnum, 0}
+       ,
+       {
+       "WPrintQProcEnum", 206, api_WPrintQProcEnum, 0}
+       ,
+       {
+       "WPrintPortEnum", 207, api_WPrintPortEnum, 0}
+       ,
+       {
+       "SamOEMChangePassword", 214, api_SamOEMChangePassword, 0}
+       ,
+       {
+       NULL, -1, api_Unsupported, 0}
+};
 
 
 /****************************************************************************
 handle remote api calls
Handle remote api calls
   ****************************************************************************/
-int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
-                    int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+int api_reply(connection_struct * conn, uint16 vuid, char *outbuf, char *data,
+             char *params, int tdscnt, int tpscnt, int mdrcnt, int mprcnt)
 {
-  int api_command;
-  prs_struct rdata_buf;
-  prs_struct rparam_buf;
-  char *rdata = NULL;
-  char *rparam = NULL;
-  int rdata_len = 0;
-  int rparam_len = 0;
-  BOOL reply=False;
-  int i;
-
-  SMB_ASSERT(params != 0);
-
-  api_command = SVAL(params,0);
-
-  DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
-          api_command,
-          params+2,
-          skip_string(params+2,1),
-          tdscnt,tpscnt,mdrcnt,mprcnt));
-
-  for (i=0;api_commands[i].name;i++)
-    if (api_commands[i].id == api_command && api_commands[i].fn)
-      {
-        DEBUG(3,("Doing %s\n",api_commands[i].name));
-        break;
-      }
-
-  rdata = (char *)malloc(1024); if (rdata) memset(rdata, 0, 1024);
-  rparam = (char *)malloc(1024); if (rparam) memset(rparam, 0, 1024);
-
-  if (!rdata || !rparam) {
-    DEBUG(0,("api_reply: malloc fail !\n"));
-    return -1;
-  }
-
-  reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
-                            &rdata,&rparam,&rdata_len,&rparam_len);
-
-
-  if (rdata_len > mdrcnt ||
-      rparam_len > mprcnt)
-    {
-      reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
-                          &rdata,&rparam,&rdata_len,&rparam_len);
-    }
-           
-
-  /* if we get False back then it's actually unsupported */
-  if (!reply)
-    api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
-                   &rdata,&rparam,&rdata_len,&rparam_len);
-
-  prs_create(&rdata_buf , rdata , rdata_len , 0, False);
-  prs_create(&rparam_buf, rparam, rparam_len, 0, False);
-
-  /* now send the reply */
-  send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
-
-  prs_free_data(&rdata_buf );
-  prs_free_data(&rparam_buf);
-
-  return(-1);
-}
+       int api_command;
+       prs_struct rdata_buf;
+       prs_struct rparam_buf;
+       char *rdata = NULL;
+       char *rparam = NULL;
+       int rdata_len = 0;
+       int rparam_len = 0;
+       BOOL reply = False;
+       int i;
+
+       if (params == 0)
+       {
+               DEBUG(0,("ERROR: NULL params in api_reply()\n"));
+               return 0;
+       }
+
+       api_command = SVAL(params, 0);
+
+       DEBUG(3,
+             ("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
+              api_command, params + 2, skip_string(params + 2, 1), tdscnt,
+              tpscnt, mdrcnt, mprcnt));
+
+       for (i = 0; api_commands[i].name; i++)
+               if (api_commands[i].id == api_command && api_commands[i].fn)
+               {
+                       DEBUG(3, ("Doing %s\n", api_commands[i].name));
+                       break;
+               }
+
+       rdata = (char *)malloc(1024);
+       if (rdata)
+               memset(rdata, 0, 1024);
+       rparam = (char *)malloc(1024);
+       if (rparam)
+               memset(rparam, 0, 1024);
+
+       if (!rdata || !rparam)
+       {
+               DEBUG(0, ("api_reply: malloc fail !\n"));
+               return -1;
+       }
+
+       reply = api_commands[i].fn(conn, vuid, params, data, mdrcnt, mprcnt,
+                                  &rdata, &rparam, &rdata_len, &rparam_len);
+
+
+       if (rdata_len > mdrcnt || rparam_len > mprcnt)
+       {
+               reply = api_TooSmall(conn, vuid, params, data, mdrcnt, mprcnt,
+                                    &rdata, &rparam, &rdata_len,
+                                    &rparam_len);
+       }
+
+
+       /* if we get False back then it's actually unsupported */
+       if (!reply)
+               api_Unsupported(conn, vuid, params, data, mdrcnt, mprcnt,
+                               &rdata, &rparam, &rdata_len, &rparam_len);
 
+       prs_create(&rdata_buf, rdata, rdata_len, 0, False);
+       prs_create(&rparam_buf, rparam, rparam_len, 0, False);
+
+       /* now send the reply */
+       send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
+
+       prs_free_data(&rdata_buf);
+       prs_free_data(&rparam_buf);
+
+       return (-1);
+}
index 6f63760819ccd7219b90c661f9d9233d3a1ab537..e47bcd896f61e00bee8f2d4b64e73174b46aec31 100644 (file)
@@ -63,11 +63,13 @@ extern BOOL case_mangle;    /* If true, all chars in 8.3 should be same case. */
  *                  global.  There is a call to lp_magicchar() in server.c
  *                  that is used to override the initial value.
  *
- * basechars      - The set of 36 characters used for name mangling.  This
+ * MANGLE_BASE    - This is the number of characters we use for name mangling.
+ *
+ * basechars      - The set characters used for name mangling.  This
  *                  is static (scope is this file only).
  *
- * base36()       - Macro used to select a character from basechars (i.e.,
- *                  base36(n) will return the nth digit, modulo 36).
+ * mangle()       - Macro used to select a character from basechars (i.e.,
+ *                  mangle(n) will return the nth digit, modulo MANGLE_BASE).
  *
  * chartest       - array 0..255.  The index range is the set of all possible
  *                  values of a byte.  For each byte value, the content is a
@@ -110,18 +112,19 @@ extern BOOL case_mangle;    /* If true, all chars in 8.3 should be same case. */
 
 char magic_char = '~';
 
-static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
+#define MANGLE_BASE       (sizeof(basechars)/sizeof(char)-1)
 
 static unsigned char chartest[256]  = { 0 };
 static BOOL          ct_initialized = False;
 
-#define base36(V) ((char)(basechars[(V) % 36]))
+#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
 #define BASECHAR_MASK 0xf0
 #define ILLEGAL_MASK  0x0f
 #define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
 #define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
 
-static ubi_cacheRoot mangled_cache[1] = { { { 0 }, 0, 0, 0, 0, 0, 0} };
+static ubi_cacheRoot mangled_cache[1] =  { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
 static BOOL          mc_initialized   = False;
 #define MANGLED_CACHE_MAX_ENTRIES 0
 #define MANGLED_CACHE_MAX_MEMORY  16384
@@ -148,7 +151,7 @@ static void init_chartest( void )
   char          *illegalchars = "*\\/?<>|\":";
   unsigned char *s;
   
-  memset( (char *)chartest, 0,  256 );
+  memset( (char *)chartest, '\0', 256 );
 
   for( s = (unsigned char *)illegalchars; *s; s++ )
     chartest[*s] = ILLEGAL_MASK;
@@ -252,7 +255,7 @@ static BOOL is_illegal_name( char *name )
   s = (unsigned char *)name;
   while( *s )
     {
-    skip = skip_multibyte_char( *s );
+    skip = get_character_len( *s );
     if( skip != 0 )
       {
       s += skip;
@@ -371,7 +374,7 @@ BOOL is_8_3( char *fname, BOOL check_case )
   dot_pos = NULL;
   while( *p )
     {
-    if( (skip = skip_multibyte_char( *p )) != 0 )
+    if( (skip = get_character_len( *p )) != 0 )
       p += skip;
     else 
       {
@@ -514,7 +517,7 @@ void reset_mangled_cache( void )
  *
  *          If the extension of the raw name maps directly to the
  *          extension of the mangled name, then we'll store both names
- *          *without* extensions.  That way, we can provide consistant
+ *          *without* extensions.  That way, we can provide consistent
  *          reverse mangling for all names that match.  The test here is
  *          a bit more careful than the one done in earlier versions of
  *          mangle.c:
@@ -533,9 +536,9 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
   ubi_cacheEntryPtr new_entry;
   char             *s1;
   char             *s2;
-  int               mangled_len;
-  int               raw_len;
-  int               i;
+  size_t               mangled_len;
+  size_t               raw_len;
+  size_t               i;
 
   /* If the cache isn't initialized, give up. */
   if( !mc_initialized )
@@ -561,7 +564,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
       }
     }
 
-  /* Allocate a new cache entry.  If the allcoation fails, just return. */
+  /* Allocate a new cache entry.  If the allocation fails, just return. */
   i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
   new_entry = malloc( i );
   if( !new_entry )
@@ -589,11 +592,13 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
  *
  * ************************************************************************** **
  */
+
 BOOL check_mangled_cache( char *s )
-  {
+{
   ubi_cacheEntryPtr FoundPtr;
   char             *ext_start = NULL;
   char             *found_name;
+  char             *saved_ext = NULL;
 
   /* If the cache isn't initialized, give up. */
   if( !mc_initialized )
@@ -603,19 +608,34 @@ BOOL check_mangled_cache( char *s )
 
   /* If we didn't find the name *with* the extension, try without. */
   if( !FoundPtr )
-    {
+  {
     ext_start = strrchr( s, '.' );
     if( ext_start )
-      {
+    {
+      if((saved_ext = strdup(ext_start)) == NULL)
+        return False;
+
       *ext_start = '\0';
       FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
-      *ext_start = '.';
-      }
+      /* 
+       * At this point s is the name without the
+       * extension. We re-add the extension if saved_ext
+       * is not null, before freeing saved_ext.
+       */
     }
+  }
 
   /* Okay, if we haven't found it we're done. */
   if( !FoundPtr )
+  {
+    if(saved_ext)
+    {
+      /* Replace the saved_ext as it was truncated. */
+      (void)pstrcat( s, saved_ext );
+      free(saved_ext);
+    }
     return( False );
+  }
 
   /* If we *did* find it, we need to copy it into the string buffer. */
   found_name = (char *)(FoundPtr + 1);
@@ -624,13 +644,17 @@ BOOL check_mangled_cache( char *s )
   DEBUG( 3, ("Found %s on mangled stack ", s) );
 
   (void)pstrcpy( s, found_name );
-  if( ext_start )
-    (void)pstrcat( s, ext_start );
+  if( saved_ext )
+  {
+    /* Replace the saved_ext as it was truncated. */
+    (void)pstrcat( s, saved_ext );
+    free(saved_ext);
+  }
 
   DEBUG( 3, ("as %s\n", s) );
 
   return( True );
-  } /* check_mangled_cache */
+} /* check_mangled_cache */
 
 
 /* ************************************************************************** **
@@ -652,6 +676,12 @@ static char *map_filename( char *s,         /* This is null terminated */
   pstrcpy( matching_bit, "" );  /* Match but no star gets this. */
   pp = pat;                     /* Initialize the pointers. */
   sp = s;
+
+  if( strequal(s, ".") || strequal(s, ".."))
+    {
+    return NULL;                /* Do not map '.' and '..' */
+    }
+
   if( (len == 1) && (*pattern == '*') )
     {
     return NULL;                /* Impossible, too ambiguous for */
@@ -807,7 +837,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
  */
 void mangle_name_83( char *s)
   {
-  int csum = str_checksum(s);
+  int csum;
   char *p;
   char extension[4];
   char base[9];
@@ -829,7 +859,11 @@ void mangle_name_83( char *s)
       csum = str_checksum( s );
       *p = '.';
       }
+    else
+      csum = str_checksum(s);
     }
+  else
+    csum = str_checksum(s);
 
   strupper( s );
 
@@ -844,7 +878,7 @@ void mangle_name_83( char *s)
       *p++ = 0;
       while( *p && extlen < 3 )
         {
-        skip = skip_multibyte_char( *p );
+        skip = get_character_len( *p );
         switch( skip )
           {
           case 2: 
@@ -855,7 +889,7 @@ void mangle_name_83( char *s)
               }
             else 
               {
-              extension[extlen++] = base36( (unsigned char)*p );
+              extension[extlen++] = mangle( (unsigned char)*p );
               }
             p += 2;
             break;
@@ -878,7 +912,7 @@ void mangle_name_83( char *s)
 
   while( *p && baselen < 5 )
     {
-    skip = skip_multibyte_char(*p);
+    skip = get_character_len(*p);
     switch( skip )
       {
       case 2:
@@ -889,7 +923,7 @@ void mangle_name_83( char *s)
           }
         else 
           {
-          base[baselen++] = base36( (unsigned char)*p );
+          base[baselen++] = mangle( (unsigned char)*p );
           }
         p += 2;
         break;
@@ -906,10 +940,10 @@ void mangle_name_83( char *s)
     }
   base[baselen] = 0;
 
-  csum = csum % (36*36);
+  csum = csum % (MANGLE_BASE*MANGLE_BASE);
 
   (void)slprintf(s, 12, "%s%c%c%c",
-                 base, magic_char, base36( csum/36 ), base36( csum ) );
+                 base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
 
   if( *extension )
     {
@@ -935,6 +969,11 @@ void mangle_name_83( char *s)
  *                    signal that a client does not require name mangling,
  *                    thus skipping the name mangling even on shares which
  *                    have name-mangling turned on.
+ *          cache83 - If False, the mangled name cache will not be updated.
+ *                    This is usually used to prevent that we overwrite
+ *                    a conflicting cache entry prematurely, i.e. before
+ *                    we know whether the client is really interested in the
+ *                    current name.  (See PR#13758).  UKD.
  *          snum    - Share number.  This identifies the share in which the
  *                    name exists.
  *
@@ -943,11 +982,11 @@ void mangle_name_83( char *s)
  *
  * ****************************************************************************
  */
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
 {
        char *map;
-       DEBUG(5,("name_map_mangle( %s, %s, %d )\n", 
-                OutName, need83?"TRUE":"FALSE", snum));
+       DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
+               need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum));
 
 #ifdef MANGLE_LONG_FILENAMES
        if( !need83 && is_illegal_name(OutName) )
@@ -963,17 +1002,19 @@ BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
 
        /* check if it's already in 8.3 format */
        if (need83 && !is_8_3(OutName, True)) {
-               char *tmp; 
+               char *tmp = NULL
 
                if (!lp_manglednames(snum)) {
                        return(False);
                }
 
                /* mangle it into 8.3 */
-               tmp = strdup(OutName);
+               if (cache83)
+                       tmp = strdup(OutName);
+
                mangle_name_83(OutName);
 
-               if(tmp) {
+               if(tmp != NULL) {
                        cache_mangled_name(OutName, tmp);
                        free(tmp);
                }
index d13dfda1e02c623f9e49ae30518f7c678a816089..cc329d61a656c611e75972014e1c2d318377920c 100644 (file)
@@ -54,7 +54,7 @@ static void msg_deliver(void)
 
   /* put it in a temporary file */
   slprintf(s,sizeof(s)-1, "%s/msg.XXXXXX",tmpdir());
-  fstrcpy(name,(char *)mktemp(s));
+  fstrcpy(name,(char *)smbd_mktemp(s));
 
   fd = sys_open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600);
   if (fd == -1) {
@@ -62,6 +62,16 @@ static void msg_deliver(void)
     return;
   }
 
+  /*
+   * Incoming message is in DOS codepage format. Convert to UNIX in
+   * place.
+   */
+
+  if(msgpos > 0) {
+    msgbuf[msgpos] = '\0'; /* Ensure null terminated. */
+    dos_to_unix(msgbuf,True);
+  }
+
   for (i=0;i<msgpos;) {
     if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n') {
       i++; continue;      
@@ -74,10 +84,13 @@ static void msg_deliver(void)
   /* run the command */
   if (*lp_msg_command())
     {
+      fstring alpha_msgfrom;
+      fstring alpha_msgto;
+
       pstrcpy(s,lp_msg_command());
-      string_sub(s,"%s",name);
-      string_sub(s,"%f",msgfrom);
-      string_sub(s,"%t",msgto);
+      pstring_sub(s,"%s",name);
+      pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,sizeof(alpha_msgfrom)));
+      pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,sizeof(alpha_msgto)));
       standard_sub_basic(s);
       smbrun(s,NULL,False);
     }
@@ -99,7 +112,6 @@ int reply_sends(connection_struct *conn,
 
   msgpos = 0;
 
-
   if (! (*lp_msg_command()))
     return(ERROR(ERRSRV,ERRmsgoff));
 
@@ -113,7 +125,9 @@ int reply_sends(connection_struct *conn,
   fstrcpy(msgto,dest);
 
   len = SVAL(msg,0);
-  len = MIN(len,1600-msgpos);
+  len = MIN(len,sizeof(msgbuf)-msgpos);
+
+  memset(msgbuf,'\0',sizeof(msgbuf));
 
   memcpy(&msgbuf[msgpos],msg+2,len);
   msgpos += len;
@@ -140,6 +154,7 @@ int reply_sendstrt(connection_struct *conn,
 
   outsize = set_message(outbuf,1,0,True);
 
+  memset(msgbuf,'\0',sizeof(msgbuf));
   msgpos = 0;
 
   orig = smb_buf(inbuf)+1;
@@ -172,7 +187,7 @@ int reply_sendtxt(connection_struct *conn,
   msg = smb_buf(inbuf) + 1;
 
   len = SVAL(msg,0);
-  len = MIN(len,1600-msgpos);
+  len = MIN(len,sizeof(msgbuf)-msgpos);
 
   memcpy(&msgbuf[msgpos],msg+2,len);
   msgpos += len;
@@ -202,4 +217,3 @@ int reply_sendend(connection_struct *conn,
 
   return(outsize);
 }
-
index c077ed5e9aae821b8297226d21560579a9de5ebf..55e2e42d6651e9123f433200103801d569f5700a 100644 (file)
@@ -26,7 +26,6 @@ extern int Protocol;
 extern int max_recv;
 extern fstring global_myworkgroup;
 extern fstring remote_machine;
-extern dfs_internal dfs_struct;
 
 /****************************************************************************
 reply for the core protocol
@@ -150,6 +149,16 @@ reply for the nt protocol
 static int reply_nt1(char *outbuf)
 {
   /* dual names + lock_and_read + nt SMBs + remote API calls */
+  int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
+                     (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
+                     (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0);
+
+
+/*
+  other valid capabilities which we may support at some time...
+                     CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
+ */
+
   int secword=0;
   BOOL doencrypt = SMBENCRYPT();
   time_t t = time(NULL);
@@ -157,27 +166,6 @@ static int reply_nt1(char *outbuf)
   char cryptkey[8];
   char crypt_len = 0;
 
-  int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
-
-       if (lp_nt_smb_support())
-       {
-               capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
-       }
-
-       if (SMB_OFF_T_BITS == 64)
-       {
-               capabilities |= CAP_LARGE_FILES;
-       }
-
-       if (dfs_struct.ready==True)
-       {
-               capabilities |= CAP_DFS;
-       }
-
-/*
-  other valid capabilities which we may support at some time...
-                     CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
- */
 
   if (doencrypt) {
          crypt_len = 8;
@@ -188,6 +176,11 @@ static int reply_nt1(char *outbuf)
          capabilities |= CAP_RAW_MODE;
   }
 
+#ifdef MS_DFS
+  if(lp_host_msdfs())
+       capabilities |= CAP_DFS;
+#endif
+
   if (lp_security() >= SEC_USER) secword |= 1;
   if (doencrypt) secword |= 2;
 
@@ -242,6 +235,14 @@ protocol [LM1.2X002]
 protocol [LANMAN2.1]
 protocol [NT LM 0.12]
 
+Win2K:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+
 OS/2:
 protocol [PC NETWORK PROGRAM 1.0]
 protocol [XENIX CORE]
@@ -255,29 +256,31 @@ protocol [LANMAN2.1]
   *
   * This appears to be the matrix of which protocol is used by which
   * MS product.
-       Protocol                       WfWg    Win95   WinNT  OS/2
-       PC NETWORK PROGRAM 1.0          1       1       1      1
+       Protocol                       WfWg    Win95   WinNT  Win2K  OS/2
+       PC NETWORK PROGRAM 1.0          1       1       1      1      1
        XENIX CORE                                      2      2
        MICROSOFT NETWORKS 3.0          2       2       
        DOS LM1.2X002                   3       3       
        MICROSOFT NETWORKS 1.03                         3
        DOS LANMAN2.1                   4       4       
-       LANMAN1.0                                       4      3
-       Windows for Workgroups 3.1a     5       5       5
-       LM1.2X002                                       6      4
-       LANMAN2.1                                       7      5
-       NT LM 0.12                              6       8
+       LANMAN1.0                                       4      2      3
+       Windows for Workgroups 3.1a     5       5       5      3
+       LM1.2X002                                       6      4      4
+       LANMAN2.1                                       7      5      5
+       NT LM 0.12                              6       8      6
   *
   *  tim@fsg.com 09/29/95
+  *  Win2K added by matty 17/7/99
   */
   
 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
 #define ARCH_WIN95    0x2
-#define        ARCH_OS2      0xC      /* Again OS/2 is like NT */
-#define ARCH_WINNT    0x8
-#define ARCH_SAMBA    0x10
+#define ARCH_WINNT    0x4
+#define ARCH_WIN2K    0xC      /* Win2K is like NT */
+#define ARCH_OS2      0x14     /* Again OS/2 is like NT */
+#define ARCH_SAMBA    0x20
  
-#define ARCH_ALL      0x1F
+#define ARCH_ALL      0x3F
  
 /* List of supported protocols, most desired first */
 static struct {
@@ -295,7 +298,7 @@ static struct {
   {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
   {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
   {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
-  {NULL,NULL},
+  {NULL,NULL,NULL,0},
 };
 
 
@@ -320,17 +323,17 @@ int reply_negprot(connection_struct *conn,
       Index++;
       DEBUG(3,("Requested protocol [%s]\n",p));
       if (strcsequal(p,"Windows for Workgroups 3.1a"))
-       arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
+       arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
       else if (strcsequal(p,"DOS LM1.2X002"))
        arch &= ( ARCH_WFWG | ARCH_WIN95 );
       else if (strcsequal(p,"DOS LANMAN2.1"))
        arch &= ( ARCH_WFWG | ARCH_WIN95 );
       else if (strcsequal(p,"NT LM 0.12"))
-       arch &= ( ARCH_WIN95 | ARCH_WINNT );
+       arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
       else if (strcsequal(p,"LANMAN2.1"))
-       arch &= ( ARCH_WINNT | ARCH_OS2 );
+       arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
       else if (strcsequal(p,"LM1.2X002"))
-       arch &= ( ARCH_WINNT | ARCH_OS2 );
+       arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
       else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
        arch &= ARCH_WINNT;
       else if (strcsequal(p,"XENIX CORE"))
@@ -354,8 +357,14 @@ int reply_negprot(connection_struct *conn,
     set_remote_arch(RA_WIN95);
     break;
   case ARCH_WINNT:
+   if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE)
+     set_remote_arch(RA_WIN2K);
+   else
     set_remote_arch(RA_WINNT);
     break;
+  case ARCH_WIN2K:
+    set_remote_arch(RA_WIN2K);
+    break;
   case ARCH_OS2:
     set_remote_arch(RA_OS2);
     break;
index b72507d4883472f0fa89e1d56fc95019fcdb28e1..fd4d529b4b1fe0669e12a4766c0819c4f386d5ae 100644 (file)
 
 #include "includes.h"
 #include "nterr.h"
+#include "sids.h"
 
 extern int DEBUGLEVEL;
 extern int Protocol;
 extern int Client;  
 extern int smb_read_error;
 extern int global_oplock_break;
-extern int chain_size;
 extern BOOL case_sensitive;
 extern BOOL case_preserve;
 extern BOOL short_case_preserve;
@@ -37,10 +37,8 @@ static void remove_pending_change_notify_requests_by_mid(int mid);
 static char *known_nt_pipes[] = {
   "\\LANMAN",
   "\\srvsvc",
-  "\\svcctl",
   "\\samr",
   "\\wkssvc",
-  "\\browser",
   "\\NETLOGON",
   "\\ntlsa",
   "\\ntsvcs",
@@ -58,7 +56,7 @@ static char *known_nt_pipes[] = {
  HACK ! Always assumes smb_setup field is zero.
 ****************************************************************************/
 
-static int send_nt_replies(char *outbuf, int bufsize, char *params,
+static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
                            int paramsize, char *pdata, int datasize)
 {
   extern int max_send;
@@ -78,6 +76,13 @@ static int send_nt_replies(char *outbuf, int bufsize, char *params,
 
   set_message(outbuf,18,0,True);
 
+  if(nt_error != 0) {
+    /* NT Error. */
+    SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
+
+    ERROR(0,nt_error);
+  }
+
   /* 
    * If there genuinely are no parameters or data to send just send
    * the empty packet.
@@ -240,16 +245,15 @@ static int send_nt_replies(char *outbuf, int bufsize, char *params,
  strings in NT calls AND DOESN'T SET THE UNICODE BIT !!!!!!!
 ****************************************************************************/
 
-static void my_wcstombs(char *dst, uint16 *src, size_t len)
+static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
 {
-  size_t i;
+  /*
+   * We need various heuristics here to detect a unicode string... JRA.
+   */
 
-  for(i = 0; i < len; i++)
-    dst[i] = (char)SVAL(src,i*2);
-}
+  DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
+           data_offset, data_len, fname_len ));
 
-static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
-{
   if(data_len - fname_len > 1) {
     /*
      * NT 5.0 Beta 2 has kindly sent us a UNICODE string
@@ -261,11 +265,46 @@ static void get_filename( char *fname, char *inbuf, int data_offset, int data_le
     fname_len = fname_len/2;
     if(data_offset & 1)
       data_offset++;
-    my_wcstombs( fname, (uint16 *)(inbuf+data_offset), fname_len);
+    pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+  } else {
+    StrnCpy(fname,inbuf+data_offset,fname_len);
+    fname[fname_len] = '\0';
+  }
+}
+
+/****************************************************************************
+ Fix bugs in Win2000 final release. In trans calls this OS sends unicode
+ strings AND DOESN'T SET THE UNICODE BIT !!!!!!!
+****************************************************************************/
+
+static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
+{
+  /*
+   * We need various heuristics here to detect a unicode string... JRA.
+   */
+
+  DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
+           data_offset, data_len, fname_len ));
+
+  /*
+   * Win2K sends a unicode filename plus one extra alingment byte.
+   * WinNT4.x send an ascii string with multiple garbage bytes on
+   * the end here.
+   */
+
+  if((data_len - fname_len == 1) || (inbuf[data_offset] == '\0')) {
+    /*
+     * Ensure that the data offset is aligned
+     * on a 2 byte boundary - add one if not.
+     */
+    fname_len = fname_len/2;
+    if(data_offset & 1)
+      data_offset++;
+    pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
   } else {
     StrnCpy(fname,inbuf+data_offset,fname_len);
+    fname[fname_len] = '\0';
   }
-  fname[fname_len] = '\0';
 }
 
 /****************************************************************************
@@ -355,18 +394,25 @@ static int map_create_disposition( uint32 create_disposition)
  Utility function to map share modes.
 ****************************************************************************/
 
-static int map_share_mode( char *fname, uint32 desired_access, uint32 share_access, uint32 file_attributes)
+static int map_share_mode( BOOL *pstat_open_only, char *fname,
+                                                       uint32 desired_access, uint32 share_access, uint32 file_attributes)
 {
   int smb_open_mode = -1;
 
-  switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) {
+  *pstat_open_only = False;
+
+  switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
   case FILE_READ_DATA:
     smb_open_mode = DOS_OPEN_RDONLY;
     break;
   case FILE_WRITE_DATA:
+  case FILE_APPEND_DATA:
+  case FILE_WRITE_DATA|FILE_APPEND_DATA:
     smb_open_mode = DOS_OPEN_WRONLY;
     break;
   case FILE_READ_DATA|FILE_WRITE_DATA:
+  case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
+  case FILE_READ_DATA|FILE_APPEND_DATA:
     smb_open_mode = DOS_OPEN_RDWR;
     break;
   }
@@ -386,8 +432,12 @@ static int map_share_mode( char *fname, uint32 desired_access, uint32 share_acce
    */
 
   if (smb_open_mode == -1) {
+       if(desired_access == WRITE_DAC_ACCESS || desired_access == READ_CONTROL_ACCESS)
+               *pstat_open_only = True;
+
     if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
                               FILE_EXECUTE|FILE_READ_ATTRIBUTES|
+                              FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
                               FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS))
       smb_open_mode = DOS_OPEN_RDONLY;
     else {
@@ -464,20 +514,48 @@ static time_t fail_time;
 
 void fail_next_srvsvc_open(void)
 {
+  /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
+  if (get_remote_arch() != RA_WINNT)
+    return;
+
   fail_next_srvsvc = True;
   fail_time = time(NULL);
   DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
 }
 
+/*
+ * HACK alert.... see above - JRA.
+ */
+
+BOOL should_fail_next_srvsvc_open(const char *pipename)
+{
+
+  DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
+    (int)fail_next_srvsvc, pipename));
+
+  if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
+    fail_next_srvsvc = False;
+    fail_time = (time_t)0;
+    DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
+  }
+
+  if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
+    fail_next_srvsvc = False;
+    DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
+    return True;
+  }
+  return False;
+}
+
+
 /****************************************************************************
  Reply to an NT create and X call on a pipe.
 ****************************************************************************/
 static int nt_open_pipe(char *fname, connection_struct *conn,
                        char *inbuf, char *outbuf, int *ppnum)
 {
-       vuser_key key;
        pipes_struct *p = NULL;
-
+       vuser_key key;
        uint16 vuid = SVAL(inbuf, smb_uid);
        int i;
 
@@ -488,32 +566,15 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
                if( strequal(fname,known_nt_pipes[i]))
                        break;
     
-       /*
-        * HACK alert.... see above - JRA.
-        */
-
-       if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
-               fail_next_srvsvc = False;
-               fail_time = (time_t)0;
-               DEBUG(10,("nt_open_pipe: End of timeout close of \\srvsvc pipe for print fix.\n"));
-       }
-
-       if(fail_next_srvsvc && strequal(fname, "\\srvsvc")) {
-               fail_next_srvsvc = False;
-               DEBUG(10,("nt_open_pipe: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
-               return(ERROR(ERRSRV,ERRaccess));
-       }
-
-       /*
-        * End hack alert.... see above - JRA.
-        */
-
        if ( known_nt_pipes[i] == NULL )
                return(ERROR(ERRSRV,ERRaccess));
     
        /* Strip \\ off the name. */
        fname++;
     
+       if(should_fail_next_srvsvc_open(fname))
+               return (ERROR(ERRSRV,ERRaccess));
+
        DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
 
        key.pid = getpid();
@@ -550,7 +611,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
        /* Breakout the oplock request bits so we can set the
           reply bits separately. */
        int oplock_request = 0;
-    mode_t unixmode;
+       mode_t unixmode;
        int pnum = -1;
        int fmode=0,rmode=0;
        SMB_OFF_T file_len = 0;
@@ -559,6 +620,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
        BOOL bad_path = False;
        files_struct *fsp=NULL;
        char *p = NULL;
+       BOOL stat_open_only = False;
 
        /* 
         * We need to construct the open_and_X ofun value from the
@@ -579,8 +641,23 @@ int reply_ntcreate_and_X(connection_struct *conn,
       files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
       size_t dir_name_len;
 
-      if(!dir_fsp || !dir_fsp->is_directory)
+      if(!dir_fsp)
+        return(ERROR(ERRDOS,ERRbadfid));
+
+      if(!dir_fsp->is_directory) {
+        /* 
+         * Check to see if this is a mac fork of some kind.
+         */
+
+        get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf, 
+                   smb_buflen(inbuf),fname_len);
+
+        if( fname[0] == ':') {
+          SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+          return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
+        }
         return(ERROR(ERRDOS,ERRbadfid));
+      }
 
       /*
        * Copy in the base directory name.
@@ -598,31 +675,27 @@ int reply_ntcreate_and_X(connection_struct *conn,
         dir_name_len++;
       }
 
+      /*
+       * This next calculation can refuse a correct filename if we're dealing
+       * with the Win2k unicode bug, but that would be rare. JRA.
+       */
+
       if(fname_len + dir_name_len >= sizeof(pstring))
         return(ERROR(ERRSRV,ERRfilespecs));
 
       get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf, 
                    smb_buflen(inbuf),fname_len);
-#if 0
-      StrnCpy(&fname[dir_name_len], smb_buf(inbuf),fname_len);
-      fname[dir_name_len+fname_len] = '\0';
-#endif
 
     } else {
       
       get_filename(fname, inbuf, smb_buf(inbuf)-inbuf, 
                    smb_buflen(inbuf),fname_len);
-
-#if 0
-         StrnCpy(fname,smb_buf(inbuf),fname_len);
-      fname[fname_len] = '\0';
-#endif
     }
        
        /* If it's an IPC, use the pipe handler. */
 
-       if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
-       {
+       if (IS_IPC(conn) && lp_nt_pipe_support()) {
+
                int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
                if(ret != 0)
                        return ret;
@@ -656,12 +729,15 @@ int reply_ntcreate_and_X(connection_struct *conn,
         * Now contruct the smb_open_mode value from the filename, 
      * desired access and the share access.
         */
-       
-       if((smb_open_mode = map_share_mode(fname, desired_access, 
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access, 
                                           share_access, 
-                                          file_attributes)) == -1) {
+                                          file_attributes)) == -1)
                return(ERROR(ERRDOS,ERRbadaccess));
-       }
+
+       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+       oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
 
        /*
         * Ordinary file or directory.
@@ -673,11 +749,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
                
        set_posix_case_semantics(file_attributes);
                
-       if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+       unix_convert(fname,conn,0,&bad_path,NULL);
                
        fsp = file_new();
        if (!fsp) {
@@ -697,11 +769,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
                return(UNIXERROR(ERRDOS,ERRnoaccess));
        } 
                
-       unixmode = unix_mode(conn,smb_attr | aARCH);
+       unixmode = unix_mode(conn,smb_attr | aARCH, fname);
     
-       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
-       oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
        /* 
         * If it's a request for a directory open, deal with it separately.
         */
@@ -709,8 +778,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
        if(create_options & FILE_DIRECTORY_FILE) {
                oplock_request = 0;
                
-               open_directory(fsp, conn, fname, smb_ofun, unixmode, 
-                              &smb_action);
+               open_directory(fsp, conn, fname, smb_ofun, 
+                              unixmode, &smb_action);
                        
                restore_case_semantics(file_attributes);
 
@@ -736,13 +805,12 @@ int reply_ntcreate_and_X(connection_struct *conn,
                 * before issuing an oplock break request to
                 * our client. JRA.  */
 
-               open_file_shared(fsp,conn,fname,smb_open_mode,
-                                smb_ofun,unixmode,
-                                oplock_request,&rmode,&smb_action);
+               open_file_shared(fsp,conn,fname,smb_open_mode,
+                                smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
 
                if (!fsp->open) { 
-                       /* We cheat here. The only case we
-                        * care about is a directory rename,
+                       /* We cheat here. There are two cases we
+                        * care about. One is a directory rename,
                         * where the NT client will attempt to
                         * open the source directory for
                         * DELETE access. Note that when the
@@ -755,21 +823,54 @@ int reply_ntcreate_and_X(connection_struct *conn,
                         * will generate an EISDIR error, so
                         * we can catch this here and open a
                         * pseudo handle that is flagged as a
-                        * directory. JRA.  */
+                        * directory. The second is an open
+                        * for a permissions read only, which
+                        * we handle in the open_file_stat case. JRA.
+                        */
 
                        if(errno == EISDIR) {
+
+                               /*
+                                * Fail the open if it was explicitly a non-directory file.
+                                */
+
+                               if (create_options & FILE_NON_DIRECTORY_FILE) {
+                                       file_free(fsp);
+                                       restore_case_semantics(file_attributes);
+                                       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+                                       return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
+                               }
+       
                                oplock_request = 0;
+                               open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
                                
-                               open_directory(fsp, conn, fname, 
-                                              smb_ofun, unixmode, 
-                                              &smb_action);
-                               
                                if(!fsp->open) {
                                        file_free(fsp);
                                        restore_case_semantics(file_attributes);
                                        return(UNIXERROR(ERRDOS,ERRnoaccess));
                                }
+#ifdef EROFS
+                       } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
+#else /* !EROFS */
+                       } else if (errno == EACCES && stat_open_only) {
+#endif
+                               /*
+                                * We couldn't open normally and all we want
+                                * are the permissions. Try and do a stat open.
+                                */
+
+                               oplock_request = 0;
+
+                               open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
+
+                               if(!fsp->open) {
+                                       file_free(fsp);
+                                       restore_case_semantics(file_attributes);
+                                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+                               }
+
                        } else {
+
                                if((errno == ENOENT) && bad_path) {
                                        unix_ERR_class = ERRDOS;
                                        unix_ERR_code = ERRbadpath;
@@ -785,15 +886,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
        }
                
        if(fsp->is_directory) {
-               if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
-                                          &sbuf) != 0) {
-                       close_directory(fsp);
+               if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
+                       close_file(fsp,True);
                        restore_case_semantics(file_attributes);
                        return(ERROR(ERRDOS,ERRnoaccess));
                }
        } else {
-               if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) 
-                   != 0) {
+               if (conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
                        close_file(fsp,False);
                        restore_case_semantics(file_attributes);
                        return(ERROR(ERRDOS,ERRnoaccess));
@@ -820,9 +919,9 @@ int reply_ntcreate_and_X(connection_struct *conn,
        if (oplock_request && lp_fake_oplocks(SNUM(conn)))
                smb_action |= EXTENDED_OPLOCK_GRANTED;
        
-       if(oplock_request && fsp->granted_oplock)
+       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
                smb_action |= EXTENDED_OPLOCK_GRANTED;
-       
+
        set_message(outbuf,34,0,True);
        
        p = outbuf + smb_vwv2;
@@ -831,8 +930,14 @@ int reply_ntcreate_and_X(connection_struct *conn,
         * Currently as we don't support level II oplocks we just report
         * exclusive & batch here.
         */
+
+    if (smb_action & EXTENDED_OPLOCK_GRANTED)  
+               SCVAL(p,0, BATCH_OPLOCK_RETURN);
+       else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+        SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
+       else
+               SCVAL(p,0,NO_OPLOCK_RETURN);
        
-       SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
        p++;
        SSVAL(p,0,fsp->fnum);
        p += 2;
@@ -864,26 +969,15 @@ int reply_ntcreate_and_X(connection_struct *conn,
 /****************************************************************************
  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
 ****************************************************************************/
+
 static int call_nt_transact_create(connection_struct *conn,
-                                  char *inbuf, char *outbuf, int length, 
-                                   int bufsize, 
-                                   char **ppsetup, char **ppparams, 
-                                  char **ppdata)
+                                       char *inbuf, char *outbuf, int length, 
+                                       int bufsize, char **ppsetup, char **ppparams, 
+                                       char **ppdata)
 {
   pstring fname;
   char *params = *ppparams;
-  uint32 flags = IVAL(params,0);
-  uint32 desired_access = IVAL(params,8);
-  uint32 file_attributes = IVAL(params,20);
-  uint32 share_access = IVAL(params,24);
-  uint32 create_disposition = IVAL(params,28);
-  uint32 create_options = IVAL(params,32);
-  uint32 fname_len = MIN(((uint32)IVAL(params,44)),
-                         ((uint32)sizeof(fname)-1));
-  uint16 root_dir_fid = (uint16)IVAL(params,4);
-  int smb_ofun;
-  int smb_open_mode;
-  int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
+  int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
   /* Breakout the oplock request bits so we can set the
      reply bits separately. */
   int oplock_request = 0;
@@ -896,6 +990,39 @@ static int call_nt_transact_create(connection_struct *conn,
   BOOL bad_path = False;
   files_struct *fsp = NULL;
   char *p = NULL;
+  BOOL stat_open_only = False;
+  uint32 flags;
+  uint32 desired_access;
+  uint32 file_attributes;
+  uint32 share_access;
+  uint32 create_disposition;
+  uint32 create_options;
+  uint32 fname_len;
+  uint16 root_dir_fid;
+  int smb_ofun;
+  int smb_open_mode;
+  int smb_attr;
+
+  DEBUG(5,("call_nt_transact_create\n"));
+
+  /*
+   * Ensure minimum number of parameters sent.
+   */
+
+  if(total_parameter_count < 54) {
+    DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+    return(ERROR(ERRDOS,ERRbadaccess));
+  }
+
+  flags = IVAL(params,0);
+  desired_access = IVAL(params,8);
+  file_attributes = IVAL(params,20);
+  share_access = IVAL(params,24);
+  create_disposition = IVAL(params,28);
+  create_options = IVAL(params,32);
+  fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
+  root_dir_fid = (uint16)IVAL(params,4);
+  smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
 
   /* 
    * We need to construct the open_and_X ofun value from the
@@ -903,7 +1030,7 @@ static int call_nt_transact_create(connection_struct *conn,
    */    
 
   if((smb_ofun = map_create_disposition( create_disposition )) == -1)
-    return(ERROR(ERRDOS,ERRbadaccess));
+    return(ERROR(ERRDOS,ERRbadmem));
 
   /*
    * Get the file name.
@@ -917,8 +1044,24 @@ static int call_nt_transact_create(connection_struct *conn,
     files_struct *dir_fsp = file_fsp(params,4);
     size_t dir_name_len;
 
-    if(!dir_fsp || !dir_fsp->is_directory)
+    if(!dir_fsp)
+        return(ERROR(ERRDOS,ERRbadfid));
+
+    if(!dir_fsp->is_directory) {
+      /*
+       * Check to see if this is a mac fork of some kind.
+       */
+
+      get_filename_transact(&fname[0], params, 53,
+                            total_parameter_count - 53 - fname_len, fname_len);
+
+      if( fname[0] == ':') {
+          SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+          return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
+      }
+
       return(ERROR(ERRDOS,ERRbadfid));
+    }
 
     /*
      * Copy in the base directory name.
@@ -936,15 +1079,20 @@ static int call_nt_transact_create(connection_struct *conn,
       dir_name_len++;
     }
 
+    /*
+     * This next calculation can refuse a correct filename if we're dealing
+     * with the Win2k unicode bug, but that would be rare. JRA.
+     */
+
     if(fname_len + dir_name_len >= sizeof(pstring))
       return(ERROR(ERRSRV,ERRfilespecs));
 
-    StrnCpy(&fname[dir_name_len], params+53, fname_len);
-    fname[dir_name_len+fname_len] = '\0';
+    get_filename_transact(&fname[dir_name_len], params, 53,
+                 total_parameter_count - 53 - fname_len, fname_len);
 
   } else {
-    StrnCpy(fname,params+53,fname_len);
-    fname[fname_len] = '\0';
+    get_filename_transact(&fname[0], params, 53,
+                 total_parameter_count - 53 - fname_len, fname_len);
   }
 
   /* If it's an IPC, use the pipe handler. */
@@ -954,17 +1102,28 @@ static int call_nt_transact_create(connection_struct *conn,
       return ret;
     smb_action = FILE_WAS_OPENED;
   } else {
+
+    /*
+     * Now contruct the smb_open_mode value from the desired access
+     * and the share access.
+     */
+
+    if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
+                                        share_access, file_attributes)) == -1)
+      return(ERROR(ERRDOS,ERRbadaccess));
+
+    oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+    oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+
     /*
      * Check if POSIX semantics are wanted.
      */
 
     set_posix_case_semantics(file_attributes);
+    
+    RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
 
-       if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+    unix_convert(fname,conn,0,&bad_path,NULL);
     
     fsp = file_new();
     if (!fsp) {
@@ -984,19 +1143,8 @@ static int call_nt_transact_create(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRnoaccess));
     } 
   
-    unixmode = unix_mode(conn,smb_attr | aARCH);
+    unixmode = unix_mode(conn,smb_attr | aARCH, fname);
     
-    oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
-    oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
-    /*
-     * Now contruct the smb_open_mode value from the desired access
-     * and the share access.
-     */
-
-    if((smb_open_mode = map_share_mode( fname, desired_access, share_access, file_attributes)) == -1)
-      return(ERROR(ERRDOS,ERRbadaccess));
-
     /*
      * If it's a request for a directory open, deal with it separately.
      */
@@ -1015,37 +1163,97 @@ static int call_nt_transact_create(connection_struct *conn,
 
       if(!fsp->open) {
         file_free(fsp);
+        restore_case_semantics(file_attributes);
         return(UNIXERROR(ERRDOS,ERRnoaccess));
       }
+
+      if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
+                            &sbuf) != 0) {
+        close_file(fsp,True);
+        restore_case_semantics(file_attributes);
+        return(ERROR(ERRDOS,ERRnoaccess));
+      }
+
     } else {
 
       /*
        * Ordinary file case.
        */
 
-      open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,
-                      unixmode,oplock_request,&rmode,&smb_action);
+      open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode,
+                       oplock_request,&rmode,&smb_action);
 
       if (!fsp->open) { 
-        if((errno == ENOENT) && bad_path) {
-          unix_ERR_class = ERRDOS;
-          unix_ERR_code = ERRbadpath;
-        }
-        file_free(fsp);
 
-        restore_case_semantics(file_attributes);
+               if(errno == EISDIR) {
 
-        return(UNIXERROR(ERRDOS,ERRnoaccess));
-      } 
-  
-      if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
-        close_file(fsp,False);
+                       /*
+                        * Fail the open if it was explicitly a non-directory file.
+                        */
 
-        restore_case_semantics(file_attributes);
+                       if (create_options & FILE_NON_DIRECTORY_FILE) {
+                               file_free(fsp);
+                               restore_case_semantics(file_attributes);
+                               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+                               return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
+                       }
+       
+                       oplock_request = 0;
+                       open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
+                               
+                       if(!fsp->open) {
+                               file_free(fsp);
+                               restore_case_semantics(file_attributes);
+                               return(UNIXERROR(ERRDOS,ERRnoaccess));
+                       }
+#ifdef EROFS
+               } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
+#else /* !EROFS */
+               } else if (errno == EACCES && stat_open_only) {
+#endif
 
-        return(ERROR(ERRDOS,ERRnoaccess));
+                       /*
+                        * We couldn't open normally and all we want
+                        * are the permissions. Try and do a stat open.
+                        */
+
+                       oplock_request = 0;
+
+                       open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
+
+                       if(!fsp->open) {
+                               file_free(fsp);
+                               restore_case_semantics(file_attributes);
+                               return(UNIXERROR(ERRDOS,ERRnoaccess));
+                       }
+               } else {
+
+                       if((errno == ENOENT) && bad_path) {
+                               unix_ERR_class = ERRDOS;
+                               unix_ERR_code = ERRbadpath;
+                       }
+                       file_free(fsp);
+
+                       restore_case_semantics(file_attributes);
+
+                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+               }
       } 
   
+      if(fsp->is_directory) {
+          if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
+              close_file(fsp,True);
+              restore_case_semantics(file_attributes);
+              return(ERROR(ERRDOS,ERRnoaccess));
+          }
+      } else {
+          if (!fsp->stat_open && conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+              close_file(fsp,False);
+              restore_case_semantics(file_attributes);
+              return(ERROR(ERRDOS,ERRnoaccess));
+          } 
+      }
       file_len = sbuf.st_size;
       fmode = dos_mode(conn,fname,&sbuf);
       if(fmode == 0)
@@ -1066,7 +1274,7 @@ static int call_nt_transact_create(connection_struct *conn,
       if (oplock_request && lp_fake_oplocks(SNUM(conn)))
         smb_action |= EXTENDED_OPLOCK_GRANTED;
   
-      if(oplock_request && fsp->granted_oplock)
+      if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
         smb_action |= EXTENDED_OPLOCK_GRANTED;
     }
   }
@@ -1078,8 +1286,16 @@ static int call_nt_transact_create(connection_struct *conn,
   if(params == NULL)
     return(ERROR(ERRDOS,ERRnomem));
 
+  memset((char *)params,'\0',69);
+
   p = params;
-  SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
+  if (smb_action & EXTENDED_OPLOCK_GRANTED)    
+       SCVAL(p,0, BATCH_OPLOCK_RETURN);
+  else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+    SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
+  else
+       SCVAL(p,0,NO_OPLOCK_RETURN);
+       
   p += 2;
   if (IS_IPC(conn)) {
          SSVAL(p,0,pnum);
@@ -1121,8 +1337,10 @@ static int call_nt_transact_create(connection_struct *conn,
     SOFF_T(p,0,file_len);
   }
 
+  DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
+
   /* Send the required number of replies */
-  send_nt_replies(outbuf, bufsize, params, 69, *ppdata, 0);
+  send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
 
   return -1;
 }
@@ -1159,6 +1377,7 @@ int reply_nttranss(connection_struct *conn,
 /****************************************************************************
  Reply to an NT transact rename command.
 ****************************************************************************/
+
 static int call_nt_transact_rename(connection_struct *conn,
                                   char *inbuf, char *outbuf, int length, 
                                    int bufsize,
@@ -1182,7 +1401,7 @@ static int call_nt_transact_rename(connection_struct *conn,
     /*
      * Rename was successful.
      */
-    send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
+    send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
 
     DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
           fsp->fsp_name, new_name));
@@ -1193,6 +1412,18 @@ static int call_nt_transact_rename(connection_struct *conn,
   return(outsize);
 }
    
+/****************************************************************************
+ This is the structure to keep the information needed to
+ determine if a directory has changed.
+*****************************************************************************/
+
+typedef struct {
+  time_t modify_time; /* Info from the directory we're monitoring. */ 
+  time_t status_time; /* Info from the directory we're monitoring. */
+  time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
+  unsigned int num_entries; /* Zero or the number of files in the directory. */
+} change_hash_data;
+
 /****************************************************************************
  This is the structure to queue to implement NT change
  notify. It consists of smb_size bytes stored from the
@@ -1204,9 +1435,9 @@ typedef struct {
   ubi_slNode msg_next;
   files_struct *fsp;
   connection_struct *conn;
+  uint32 flags;
   time_t next_check_time;
-  time_t modify_time; /* Info from the directory we're monitoring. */ 
-  time_t status_time; /* Info from the directory we're monitoring. */
+  change_hash_data change_data;
   char request_buf[smb_size];
 } change_notify_buf;
 
@@ -1247,40 +1478,151 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro
 }
 
 /****************************************************************************
Delete entries by fnum from the change notify pending queue.
Create the hash we will use to determine if the contents changed.
 *****************************************************************************/
-void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
+
+static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
 {
-  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
-  change_notify_buf *prev = NULL;
+  SMB_STRUCT_STAT st;
+  files_struct *fsp = cnbp->fsp;
 
-  while(cnbp != NULL) {
-    if(cnbp->fsp->fnum == fsp->fnum) {
-      free((char *)ubi_slRemNext( &change_notify_queue, prev));
-      cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
-      continue;
-    }
+  memset((char *)change_data, '\0', sizeof(change_data));
 
-    prev = cnbp;
-    cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+  /* 
+   * Store the current timestamp on the directory we are monitoring.
+   */
+
+  if(dos_stat(fsp->fsp_name, &st) < 0) {
+    DEBUG(0,("create_directory_notify_hash: Unable to stat name = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+    return False;
   }
-}
+  change_data->modify_time = st.st_mtime;
+  change_data->status_time = st.st_ctime;
 
-/****************************************************************************
- Delete entries by mid from the change notify pending queue. Always send reply.
-*****************************************************************************/
+  /*
+   * If we are to watch for changes that are only stored
+   * in inodes of files, not in the directory inode, we must
+   * scan the directory and produce a unique identifier with
+   * which we can determine if anything changed. We use the
+   * modify and change times from all the files in the
+   * directory, added together (ignoring wrapping if it's
+   * larger than the max time_t value).
+   */
 
-static void remove_pending_change_notify_requests_by_mid(int mid)
-{
-  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
-  change_notify_buf *prev = NULL;
+  if(cnbp->flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE)) {
+    pstring full_name;
+    char *p;
+    char *fname;
+    size_t remaining_len;
+    size_t fullname_len;
+    void *dp = OpenDir(cnbp->conn, fsp->fsp_name, True);
 
-  while(cnbp != NULL) {
-    if(SVAL(cnbp->request_buf,smb_mid) == mid) {
-      change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
-      free((char *)ubi_slRemNext( &change_notify_queue, prev));
-      cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
-      continue;
+    if(dp == NULL) {
+      DEBUG(0,("create_directory_notify_hash: Unable to open directory = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+      return False;
+    }
+
+    change_data->num_entries = 0;
+
+    pstrcpy(full_name, fsp->fsp_name);
+    pstrcat(full_name, "/");
+
+    fullname_len = strlen(full_name);
+    remaining_len = sizeof(full_name) - fullname_len - 1;
+    p = &full_name[fullname_len];
+
+    while ((fname = ReadDirName(dp))) {
+      if(strequal(fname, ".") || strequal(fname, ".."))
+        continue;
+
+      change_data->num_entries++;
+      safe_strcpy( p, fname, remaining_len);
+
+      memset(&st, '\0', sizeof(st));
+
+      /*
+       * Do the stat - but ignore errors.
+       */
+
+      if(dos_stat(full_name, &st) < 0) {
+        DEBUG(5,("create_directory_notify_hash: Unable to stat content file = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+      }
+      change_data->total_time += (st.st_mtime + st.st_ctime);
+    }
+
+    CloseDir(dp);
+  }
+
+  return True;
+}
+
+/****************************************************************************
+ Delete entries by fnum from the change notify pending queue.
+*****************************************************************************/
+
+void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
+{
+  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+  change_notify_buf *prev = NULL;
+
+  while(cnbp != NULL) {
+    if(cnbp->fsp->fnum == fsp->fnum) {
+      free((char *)ubi_slRemNext( &change_notify_queue, prev));
+      cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+      continue;
+    }
+
+    prev = cnbp;
+    cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+  }
+}
+
+/****************************************************************************
+ Delete entries by mid from the change notify pending queue. Always send reply.
+*****************************************************************************/
+
+static void remove_pending_change_notify_requests_by_mid(int mid)
+{
+  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+  change_notify_buf *prev = NULL;
+
+  while(cnbp != NULL) {
+    if(SVAL(cnbp->request_buf,smb_mid) == mid) {
+      change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
+      free((char *)ubi_slRemNext( &change_notify_queue, prev));
+      cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+      continue;
+    }
+
+    prev = cnbp;
+    cnbp = (change_notify_buf *)ubi_slNext(cnbp);
+  }
+}
+
+/****************************************************************************
+ Delete entries by filename and cnum from the change notify pending queue.
+ Always send reply.
+*****************************************************************************/
+
+void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
+{
+  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+  change_notify_buf *prev = NULL;
+
+  while(cnbp != NULL) {
+    /*
+     * We know it refers to the same directory if the connection number and
+     * the filename are identical.
+     */
+    if((cnbp->fsp->conn == fsp->conn) && strequal(cnbp->fsp->fsp_name,fsp->fsp_name)) {
+      change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
+      free((char *)ubi_slRemNext( &change_notify_queue, prev));
+      cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
+      continue;
     }
 
     prev = cnbp;
@@ -1290,18 +1632,20 @@ static void remove_pending_change_notify_requests_by_mid(int mid)
 
 /****************************************************************************
  Process the change notify queue. Note that this is only called as root.
+ Returns True if there are still outstanding change notify requests on the
+ queue.
 *****************************************************************************/
 
-void process_pending_change_notify_queue(time_t t)
+BOOL process_pending_change_notify_queue(time_t t)
 {
   change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
   change_notify_buf *prev = NULL;
 
   if(cnbp == NULL)
-    return;
+    return False;
 
   if(cnbp->next_check_time >= t)
-    return;
+    return True;
 
   /*
    * It's time to check. Go through the queue and see if
@@ -1309,8 +1653,7 @@ void process_pending_change_notify_queue(time_t t)
    */
 
   while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
-    SMB_STRUCT_STAT st;
-    files_struct *fsp = cnbp->fsp;
+    change_hash_data change_data;
     connection_struct *conn = cnbp->conn;
     uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : 
                   SVAL(cnbp->request_buf,smb_uid);
@@ -1346,9 +1689,9 @@ void process_pending_change_notify_queue(time_t t)
       continue;
     }
 
-    if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
-      DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \
-Error was %s.\n", fsp->fsp_name, strerror(errno) ));
+    if(!create_directory_notify_hash( cnbp, &change_data)) {
+      DEBUG(0,("process_pending_change_notify_queue: Unable to create change data for \
+directory %s\n", cnbp->fsp->fsp_name ));
       /*
        * Remove the entry and return an error to the client.
        */
@@ -1359,13 +1702,12 @@ Error was %s.\n", fsp->fsp_name, strerror(errno) ));
       continue;
     }
 
-    if(cnbp->modify_time != st.st_mtime ||
-       cnbp->status_time != st.st_ctime) {
+    if(memcmp( (char *)&cnbp->change_data, (char *)&change_data, sizeof(change_data))) {
       /*
        * Remove the entry and return a change notify to the client.
        */
-      DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed\n",
-            fsp->fsp_name ));
+      DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed.\n",
+            cnbp->fsp->fsp_name ));
       change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
       free((char *)ubi_slRemNext( &change_notify_queue, prev));
       cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
@@ -1381,22 +1723,34 @@ Error was %s.\n", fsp->fsp_name, strerror(errno) ));
     prev = cnbp;
     cnbp = (change_notify_buf *)ubi_slNext(cnbp);
   }
+
+  return (cnbp != NULL);
+}
+
+/****************************************************************************
+ Return true if there are pending change notifies.
+****************************************************************************/
+
+BOOL change_notifies_pending(void)
+{
+  change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
+  return (cnbp != NULL);
 }
 
 /****************************************************************************
  Reply to a notify change - queue the request and 
  don't allow a directory to be opened.
 ****************************************************************************/
+
 static int call_nt_transact_notify_change(connection_struct *conn,
-                                         char *inbuf, char *outbuf, int length,
+                                          char *inbuf, char *outbuf, int length,
                                           int bufsize, 
                                           char **ppsetup, 
-                                         char **ppparams, char **ppdata)
+                                          char **ppparams, char **ppdata)
 {
   char *setup = *ppsetup;
   files_struct *fsp;
   change_notify_buf *cnbp;
-  SMB_STRUCT_STAT st;
 
   fsp = file_fsp(setup,4);
 
@@ -1417,28 +1771,22 @@ static int call_nt_transact_notify_change(connection_struct *conn,
    */
 
   if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
-    DEBUG(0,("call_nt_transact_notify_change: Malloc fail (2) !\n" ));
+    DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
     return -1;
   }
 
-  /* 
-   * Store the current timestamp on the directory we are monitoring.
-   */
+  memset((char *)cnbp, '\0', sizeof(change_notify_buf));
 
-  if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
-    DEBUG(0,("call_nt_transact_notify_change: Unable to stat name = %s. \
-Error was %s\n", fsp->fsp_name, strerror(errno) ));
-    free((char *)cnbp);
-    return(UNIXERROR(ERRDOS,ERRbadfid));
-  }
   memcpy(cnbp->request_buf, inbuf, smb_size);
   cnbp->fsp = fsp;
   cnbp->conn = conn;
-  cnbp->modify_time = st.st_mtime;
-  cnbp->status_time = st.st_ctime;
-
   cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
+  cnbp->flags = IVAL(setup, 0);
+
+  if(!create_directory_notify_hash( cnbp, &cnbp->change_data )) {
+    free((char *)cnbp);
+    return(UNIXERROR(ERRDOS,ERRbadfid));
+  }
 
   /*
    * Adding to the tail enables us to check only
@@ -1454,44 +1802,799 @@ name = %s\n", fsp->fsp_name ));
   return -1;
 }
 
+/****************************************************************************
+ Map unix perms to NT.
+****************************************************************************/
+
+static SEC_ACCESS map_unix_perms( int *pacl_type, mode_t perm, int r_mask, int w_mask, int x_mask, BOOL is_directory)
+{
+       SEC_ACCESS sa;
+       uint32 nt_mask = 0;
+
+       *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
+
+       if((perm & (r_mask|w_mask|x_mask)) == (r_mask|w_mask|x_mask)) {
+               nt_mask = UNIX_ACCESS_RWX;
+       } else if((perm & (r_mask|w_mask|x_mask)) == 0) {
+               nt_mask = UNIX_ACCESS_NONE;
+       } else {
+               nt_mask |= (perm & r_mask) ? UNIX_ACCESS_R : 0;
+               if(is_directory)
+                       nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
+               else
+                       nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
+               nt_mask |= (perm & x_mask) ? UNIX_ACCESS_X : 0;
+       }
+       make_sec_access(&sa,nt_mask);
+       return sa;
+}
+
+/****************************************************************************
+ Function to create owner and group SIDs from a SMB_STRUCT_STAT.
+****************************************************************************/
+
+static BOOL create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
+{
+       POSIX_ID id;
+
+       ZERO_STRUCTP(powner_sid);
+       ZERO_STRUCTP(pgroup_sid);
+       DEBUG(0,("TODO: create_file_sids: not ok to assume gid is NT group\n"));
+
+       id.type = SURS_POSIX_UID_AS_USR;
+       id.id = (uint32)psbuf->st_uid;
+
+       if (!surs_unixid_to_sam_sid(&id, powner_sid, False))
+       {
+               DEBUG(3,("create_file_sids: map uid %d failed\n",
+                                       (int)psbuf->st_uid));
+               return False;
+       }
+
+       id.type = SURS_POSIX_GID_AS_GRP;
+       id.id = (uint32)psbuf->st_gid;
+
+       if (!surs_unixid_to_sam_sid(&id, pgroup_sid, False))
+       {
+               DEBUG(3,("create_file_sids: map gid %d to group failed\n",
+                                       (int)psbuf->st_gid));
+
+               id.type = SURS_POSIX_GID_AS_ALS;
+               id.id = (uint32)psbuf->st_gid;
+
+               if (surs_unixid_to_sam_sid(&id, pgroup_sid, False))
+               {
+                       return True;
+               }
+               DEBUG(3,("create_file_sids: map gid %d to alias failed\n",
+                                               (int)psbuf->st_gid));
+               return False;
+       }
+       return True;
+}
+
+/****************************************************************************
+ Reply to query a security descriptor from an fsp. If it succeeds it allocates
+ the space for the return elements and returns True.
+****************************************************************************/
+
+static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
+{
+  SMB_STRUCT_STAT sbuf;
+  SEC_ACE *ace_list = NULL;
+  DOM_SID owner_sid;
+  DOM_SID group_sid;
+  size_t sec_desc_size;
+  SEC_ACL *psa = NULL;
+  SEC_ACCESS owner_access;
+  int owner_acl_type;
+  SEC_ACCESS group_access;
+  int grp_acl_type;
+  SEC_ACCESS other_access;
+  int other_acl_type;
+  int num_acls = 0;
+  (*ppdesc) = NULL;
+
+  if(!lp_nt_acl_support()) {
+    sid_copy( &owner_sid, global_sid_everyone);
+    sid_copy( &group_sid, global_sid_everyone);
+  } else {
+
+    if(fsp->is_directory || fsp->fd_ptr == NULL) {
+      if(dos_stat(fsp->fsp_name, &sbuf) != 0)
+      {
+        return 0;
+      }
+    } else {
+      if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+        return 0;
+      }
+    }
+
+    /*
+     * Get the owner, group and world SIDs.
+     */
+
+    if (!create_file_sids(&sbuf, &owner_sid, &group_sid))
+    {
+           DEBUG(3,("create_file_sids: uid or gid not mapped to SIDS\n"));
+               return 0;
+    }
+
+    /*
+     * Create the generic 3 element UNIX acl.
+     */
+
+    owner_access = map_unix_perms(&owner_acl_type, sbuf.st_mode,
+                                                       S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
+    group_access = map_unix_perms(&grp_acl_type, sbuf.st_mode,
+                                                       S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
+    other_access = map_unix_perms(&other_acl_type, sbuf.st_mode,
+                                                       S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
+
+    if(owner_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+      make_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
+                   owner_access, 0);
+    }
+
+    if(group_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+
+      make_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
+                   group_access, 0);
+    }
+
+    if(other_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+
+      make_sec_ace(&ace_list[num_acls++], global_sid_everyone, other_acl_type,
+                   other_access, 0);
+    }
+
+    if(fsp->is_directory) {
+      /*
+       * For directory ACLs we also add in the inherited permissions
+       * ACE entries. These are the permissions a file would get when
+       * being created in the directory.
+       */
+      mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
+
+      owner_access = map_unix_perms(&owner_acl_type, mode,
+                            S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
+      group_access = map_unix_perms(&grp_acl_type, mode,
+                            S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
+      other_access = map_unix_perms(&other_acl_type, mode,
+                            S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
+
+      if(owner_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+
+        make_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
+                     owner_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+    }
+
+      if(group_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+
+        make_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
+                     group_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+    }
+
+      if(other_access.mask)
+    {
+           ace_list = g_renew(SEC_ACE, ace_list, num_acls+1);
+       if (ace_list == NULL)
+       {
+               return 0;
+       }
+
+        make_sec_ace(&ace_list[num_acls++], global_sid_everyone, other_acl_type,
+                     other_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+    }
+    }
+
+    if(num_acls)
+    {
+      psa = g_new(SEC_ACL, 1);
+      if (psa == NULL)
+      {
+             safe_free(ace_list);
+      }
+      if (!make_sec_acl( psa, 3, num_acls, ace_list))
+      {
+        DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+       safe_free(ace_list);
+       safe_free(psa);
+        return 0;
+      }
+    }
+  }
+
+  (*ppdesc) = g_new(SEC_DESC, 1);
+
+  if((*ppdesc) == NULL)
+  {
+    DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
+    sec_desc_size = 0;
+    free_sec_acl(psa);
+    safe_free(psa);
+             return 0;
+  }
+
+  sec_desc_size = make_sec_desc( (*ppdesc), 1,
+                                SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+                                sid_dup(&owner_sid),
+                                sid_dup(&group_sid),
+                                NULL, psa);
+
+  return sec_desc_size;
+}
+
 /****************************************************************************
  Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though).
+ is planned to be though). Right now it just returns the same thing NT would
+ when queried on a FAT filesystem. JRA.
 ****************************************************************************/
+
 static int call_nt_transact_query_security_desc(connection_struct *conn,
-                                               char *inbuf, char *outbuf, 
-                                               int length, 
-                                                int bufsize, 
+                                                char *inbuf, char *outbuf, 
+                                                int length, int bufsize, 
                                                 char **ppsetup, char **ppparams, char **ppdata)
 {
-  static BOOL logged_message = False;
+  uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+  char *params = *ppparams;
+  char *data = *ppdata;
+  prs_struct pd;
+  SEC_DESC *psd = NULL;
+  size_t sec_desc_size;
 
-  if(!logged_message) {
-    DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
-    logged_message = True; /* Only print this once... */
+  files_struct *fsp = file_fsp(params,0);
+
+  if(!fsp)
+    return(ERROR(ERRDOS,ERRbadfid));
+
+  DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
+
+  params = *ppparams = Realloc(*ppparams, 4);
+  if(params == NULL)
+    return(ERROR(ERRDOS,ERRnomem));
+
+  /*
+   * Get the permissions to return.
+   */
+
+  if((sec_desc_size = get_nt_acl(fsp, &psd)) == 0)
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+  DEBUG(3,("call_nt_transact_query_security_desc: sec_desc_size = %d.\n",(int)sec_desc_size));
+
+  SIVAL(params,0,(uint32)sec_desc_size);
+
+  if(max_data_count < sec_desc_size) {
+
+    free_sec_desc(psd);
+    safe_free(psd);
+
+    send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+                    params, 4, *ppdata, 0);
+    return -1;
   }
 
-  return(ERROR(ERRSRV,ERRnosupport));
+  /*
+   * Allocate the data we will point this at.
+   */
+
+  data = *ppdata = Realloc(*ppdata, sec_desc_size);
+  if(data == NULL) {
+    free_sec_desc(psd);
+    safe_free(psd);
+    return(ERROR(ERRDOS,ERRnomem));
+  }
+
+  memset(data, '\0', sec_desc_size);
+
+  /*
+   * Init the parse struct we will marshall into.
+   */
+
+  prs_init(&pd, sec_desc_size, 4, MARSHALL);
+
+  /*
+   * Finally, linearize into the outgoing buffer.
+   */
+
+  if(!sec_io_desc( "sd data", psd, &pd, 1))
+  {
+    free_sec_desc(psd);
+    safe_free(psd);
+    prs_mem_free(&pd);
+    DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
+security descriptor.\n"));
+    /*
+     * Return access denied for want of a better error message..
+     */ 
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
+
+  /*
+   * copy the data out of the marshalled structure
+   */
+
+  prs_link(NULL, &pd, NULL);
+  prs_buf_copy(data, &pd, 0, sec_desc_size);
+
+  /*
+   * Now we can delete the security descriptor.
+   */
+
+  prs_mem_free(&pd);
+  free_sec_desc(psd);
+  safe_free(psd);
+
+  send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
+  return -1;
+}
+
+/****************************************************************************
+ Map NT perms to UNIX.
+****************************************************************************/
+
+#define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES)
+#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
+#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
+
+static mode_t map_nt_perms( SEC_ACCESS sec_access, int type)
+{
+  mode_t mode = 0;
+
+  switch(type) {
+  case S_IRUSR:
+    if(sec_access.mask & GENERIC_ALL_ACCESS)
+      mode = S_IRUSR|S_IWUSR|S_IXUSR;
+    else {
+      mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
+      mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
+      mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
+    }
+    break;
+  case S_IRGRP:
+    if(sec_access.mask & GENERIC_ALL_ACCESS)
+      mode = S_IRGRP|S_IWGRP|S_IXGRP;
+    else {
+      mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
+      mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
+      mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
+    }
+    break;
+  case S_IROTH:
+    if(sec_access.mask & GENERIC_ALL_ACCESS)
+      mode = S_IROTH|S_IWOTH|S_IXOTH;
+    else {
+      mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
+      mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
+      mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
+    }
+    break;
+  }
+
+  return mode;
 }
+
+/****************************************************************************
+ Unpack a SEC_DESC into a owner, group and set of UNIX permissions.
+****************************************************************************/
+
+static BOOL unpack_nt_permissions(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, mode_t *pmode,
+                                  uint32 security_info_sent, SEC_DESC *psd, BOOL is_directory)
+{
+  DOM_SID file_owner_sid;
+  DOM_SID file_grp_sid;
+  SEC_ACL *dacl = psd->dacl;
+  BOOL all_aces_are_inherit_only = (is_directory ? True : False);
+  int i;
+  POSIX_ID id;
+
+  *pmode = 0;
+  *puser = (uid_t)-1;
+  *pgrp = (gid_t)-1;
+
+  if(security_info_sent == 0) {
+    DEBUG(0,("unpack_nt_permissions: no security info sent !\n"));
+    return False;
+  }
+
+  /*
+   * Windows 2000 sends the owner and group SIDs as the logged in
+   * user, not the connected user. But it still sends the file
+   * owner SIDs on an ACL set. So we need to check for the file
+   * owner and group SIDs as well as the owner SIDs. JRA.
+   */
+    if (!create_file_sids(psbuf, &file_owner_sid, &file_grp_sid))
+    {
+           DEBUG(3,("create_file_sids: uid or gid not mapped to SIDS\n"));
+               return 0;
+    }
+
+  /*
+   * Don't immediately fail if the owner sid cannot be validated.
+   * This may be a group chown only set.
+   */
+
+  DEBUG(0,("TODO: LsaLookupSids to find type of owner_sid\n"));
+
+  if (security_info_sent & OWNER_SECURITY_INFORMATION &&
+     surs_sam_sid_to_unixid( psd->owner_sid, &id, False) &&
+     id.type == SURS_POSIX_UID_AS_USR)
+  {
+    *puser = (uid_t)id.id;
+  }
+
+  /*
+   * Don't immediately fail if the group sid cannot be validated.
+   * This may be an owner chown only set.
+   */
+
+  /*
+   * assume support for RID_TYPE_ALIAS and RID_TYPE_GROUP only.
+   * also assume that calls to sur_sam_sid_to_unixid are exclusive
+   * and one will fail where the other succeeds
+   */
    
+  if (security_info_sent & GROUP_SECURITY_INFORMATION &&
+      surs_sam_sid_to_unixid( psd->grp_sid, &id, False) &&
+      (id.type == SURS_POSIX_GID_AS_GRP || id.type == SURS_POSIX_GID_AS_ALS))
+  {
+    *pgrp = (gid_t)id.id;
+  }
+
+  /*
+   * If no DACL then this is a chown only security descriptor.
+   */
+
+  if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !dacl) {
+    *pmode = 0;
+    return True;
+  }
+
+  /*
+   * Now go through the DACL and ensure that
+   * any owner/group sids match.
+   */
+
+  for(i = 0; i < dacl->num_aces; i++) {
+    DOM_SID ace_sid;
+    SEC_ACE *psa = &dacl->ace[i];
+
+    if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) &&
+       (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
+      DEBUG(3,("unpack_nt_permissions: unable to set anything but an ALLOW or DENY ACE.\n"));
+      return False;
+    }
+
+    /*
+     * Ignore or remove bits we don't care about on a directory ACE.
+     */
+
+    if(is_directory) {
+      if(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+        DEBUG(3,("unpack_nt_permissions: ignoring inherit only ACE.\n"));
+        continue;
+      }
+
+      /*
+       * At least one of the ACE entries wasn't inherit only.
+       * Flag this so we know the returned mode is valid.
+       */
+
+      all_aces_are_inherit_only = False;
+    }
+
+    /*
+     * Windows 2000 sets these flags even on *file* ACE's. This is wrong
+     * but we can ignore them for now. Revisit this when we go to POSIX
+     * ACLs on directories.
+     */
+
+    psa->flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+    if(psa->flags != 0) {
+      DEBUG(1,("unpack_nt_permissions: unable to set ACE flags (%x).\n", 
+            (unsigned int)psa->flags));
+      return False;
+    }
+
+    /*
+     * The security mask may be UNIX_ACCESS_NONE which should map into
+     * no permissions (we overload the WRITE_OWNER bit for this) or it
+     * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
+     * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
+     */
+
+    psa->info.mask &= (GENERIC_ALL_ACCESS|GENERIC_EXECUTE_ACCESS|GENERIC_WRITE_ACCESS|
+                     GENERIC_READ_ACCESS|UNIX_ACCESS_NONE|FILE_ALL_ATTRIBUTES);
+
+    if(psa->info.mask != UNIX_ACCESS_NONE)
+      psa->info.mask &= ~UNIX_ACCESS_NONE;
+
+    sid_copy(&ace_sid, &psa->sid);
+
+    if(sid_equal(&ace_sid, &file_owner_sid)) {
+      /*
+       * Map the desired permissions into owner perms.
+       */
+
+      if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+        *pmode |= map_nt_perms( psa->info, S_IRUSR);
+      else
+        *pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
+
+    } else if( sid_equal(&ace_sid, &file_grp_sid)) {
+      /*
+       * Map the desired permissions into group perms.
+       */
+
+      if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+        *pmode |= map_nt_perms( psa->info, S_IRGRP);
+      else
+        *pmode &= ~(map_nt_perms( psa->info, S_IRGRP));
+
+    } else if( sid_equal(&ace_sid, global_sid_everyone)) {
+      /*
+       * Map the desired permissions into other perms.
+       */
+
+      if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+        *pmode |= map_nt_perms( psa->info, S_IROTH);
+      else
+        *pmode &= ~(map_nt_perms( psa->info, S_IROTH));
+
+    } else {
+      DEBUG(0,("unpack_nt_permissions: unknown SID used in ACL.\n"));
+      return False;
+    }
+  }
+
+  if (is_directory && all_aces_are_inherit_only) {
+    /*
+     * Windows 2000 is doing one of these weird 'inherit acl'
+     * traverses to conserve NTFS ACL resources. Just pretend
+     * there was no DACL sent. JRA.
+     */
+
+    DEBUG(10,("unpack_nt_permissions: Win2k inherit acl traverse. Ignoring DACL.\n"));
+    free_sec_acl(psd->dacl);
+    safe_free(psd->dacl);
+    psd->dacl = NULL;
+  }
+
+  return True;
+}
+
 /****************************************************************************
- Reply to set a security descriptor - currently this is not implemented (it
- is planned to be though).
+ Reply to set a security descriptor. Map to UNIX perms.
 ****************************************************************************/
+
 static int call_nt_transact_set_security_desc(connection_struct *conn,
-                                             char *inbuf, char *outbuf, 
-                                             int length,
-                                              int bufsize, 
-                                              char **ppsetup, 
-                                             char **ppparams, char **ppdata)
+                                                                       char *inbuf, char *outbuf, int length,
+                                                                       int bufsize, char **ppsetup, 
+                                                                       char **ppparams, char **ppdata)
 {
-  static BOOL logged_message = False;
+  uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
+  char *params= *ppparams;
+  char *data = *ppdata;
+  prs_struct pd;
+  SEC_DESC psd;
+  uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
+  uid_t user = (uid_t)-1;
+  gid_t grp = (gid_t)-1;
+  mode_t perms = 0;
+  SMB_STRUCT_STAT sbuf;
+  files_struct *fsp = NULL;
+  uint32 security_info_sent = 0;
+  BOOL got_dacl = False;
 
-  if(!logged_message) {
-    DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
-    logged_message = True; /* Only print this once... */
+  if(!lp_nt_acl_support())
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+  if(total_parameter_count < 8)
+    return(ERROR(ERRDOS,ERRbadfunc));
+
+  if((fsp = file_fsp(params,0)) == NULL)
+    return(ERROR(ERRDOS,ERRbadfid));
+
+  security_info_sent = IVAL(params,4);
+
+  DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
+       (unsigned int)security_info_sent ));
+
+  /*
+   * Init the parse struct we will unmarshall from.
+   */
+
+  prs_init(&pd, 0, 4, UNMARSHALL);
+
+  /*
+   * Setup the prs_struct with a copy of the memory we just
+   * allocated.  unmarshall from the beginning.
+   */
+       
+  prs_append_data(&pd, data, total_data_count);
+
+  /*
+   * Finally, unmarshall from the data buffer.
+   */
+
+  if(!sec_io_desc( "sd data", &psd, &pd, 1))
+  {
+    free_sec_desc(&psd);
+    prs_mem_free(&pd);
+    DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
+security descriptor.\n"));
+    /*
+     * Return access denied for want of a better error message..
+     */ 
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
-  return(ERROR(ERRSRV,ERRnosupport));
+
+  /*
+   * finished with the marshalling structure, already
+   */
+
+  prs_mem_free(&pd);
+
+  /*
+   * Get the current state of the file.
+   */
+
+  if(fsp->is_directory) {
+    if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+      free_sec_desc(&psd);
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+  } else {
+
+    int ret;
+
+    if(fsp->fd_ptr == NULL)
+      ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
+    else
+      ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
+
+    if(ret != 0) {
+      free_sec_desc(&psd);
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+  }
+
+  /*
+   * Unpack the user/group/world id's and permissions.
+   */
+
+  if(!unpack_nt_permissions( &sbuf, &user, &grp, &perms, security_info_sent, &psd, fsp->is_directory)) {
+    free_sec_desc(&psd);
+    return(UNIXERROR(ERRDOS,ERRnoaccess));
+  }
+
+  if (psd.dacl != NULL)
+    got_dacl = True;
+
+  free_sec_desc(&psd);
+
+  /*
+   * Do we need to chown ?
+   */
+
+  if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) {
+
+    DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
+          fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
+
+    if(dos_chown( fsp->fsp_name, user, grp) == -1) {
+      DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
+            fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+
+    /*
+     * Recheck the current state of the file, which may have changed.
+     * (suid/sgid bits, for instance)
+     */
+
+    if(fsp->is_directory) {
+      if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+        return(UNIXERROR(ERRDOS,ERRnoaccess));
+      }
+    } else {
+
+      int ret;
+    
+      if(fsp->fd_ptr == NULL)
+        ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
+      else
+        ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
+  
+      if(ret != 0)
+        return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+  }
+
+  /*
+   * Only change security if we got a DACL.
+   */
+
+  if((security_info_sent & DACL_SECURITY_INFORMATION) && got_dacl) {
+
+    /*
+     * Check to see if we need to change anything.
+     * Enforce limits on modified bits *only*. Don't enforce masks
+        * on bits not changed by the user.
+     */
+
+    if(fsp->is_directory) {
+
+      perms &= (lp_dir_security_mask(SNUM(conn)) | sbuf.st_mode);
+      perms |= (lp_force_dir_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
+
+    } else {
+
+      perms &= (lp_security_mask(SNUM(conn)) | sbuf.st_mode); 
+      perms |= (lp_force_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
+
+    }
+
+    /*
+     * Preserve special bits.
+     */
+
+    perms |= (sbuf.st_mode & ~0777);
+
+    /*
+     * Do we need to chmod ?
+     */
+
+    if(sbuf.st_mode != perms) {
+
+      DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
+            fsp->fsp_name, (unsigned int)perms ));
+
+      if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
+        DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
+              fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
+        return(UNIXERROR(ERRDOS,ERRnoaccess));
+      }
+    }
+  }
+
+  send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
+  return -1;
 }
    
 /****************************************************************************
@@ -1678,7 +2781,6 @@ due to being in oplock break state.\n" ));
                                                     length, bufsize, 
                                                      &setup, &params, &data);
       break;
-
   default:
          /* Error in request */
          DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
index d63de45c7e0109aaf6490e4db2b3262790aa4c6c..ec092badc1d8465d5d58a0f13ccbafac61d35bec 100644 (file)
@@ -25,7 +25,7 @@ extern int DEBUGLEVEL;
 
 extern pstring sesssetup_user;
 extern uint16 global_oplock_port;
-
+extern BOOL global_client_failed_oplock_break;
 
 /****************************************************************************
 fd support routines - attempt to do a dos_open
@@ -71,8 +71,7 @@ static int fd_attempt_open(struct connection_struct *conn, char *fname,
           char tmp = p[max_len];
 
           p[max_len] = '\0';
-          if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode))
-              == -1)
+          if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode)) == -1)
             p[max_len] = tmp;
         }
     }
@@ -84,6 +83,7 @@ static int fd_attempt_open(struct connection_struct *conn, char *fname,
 Cache a uid_t currently with this file open. This is an optimization only
 used when multiple sessionsetup's have been done to one smbd.
 ****************************************************************************/
+
 void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 {
   if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
@@ -95,6 +95,7 @@ void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 Remove a uid_t that currently has this file open. This is an optimization only
 used when multiple sessionsetup's have been done to one smbd.
 ****************************************************************************/
+
 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 {
   int i;
@@ -112,6 +113,7 @@ static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 Check if a uid_t that currently has this file open is present. This is an
 optimization only used when multiple sessionsetup's have been done to one smbd.
 ****************************************************************************/
+
 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
 {
   int i;
@@ -121,14 +123,15 @@ static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
   return False;
 }
 
-
 /****************************************************************************
 fd support routines - attempt to re-open an already open fd as O_RDWR.
 Save the already open fd (we cannot close due to POSIX file locking braindamage.
 ****************************************************************************/
-static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr)
+
+static void fd_attempt_reopen(char *fname, mode_t mode, files_struct *fsp)
 {
-  int fd = dos_open( fname, O_RDWR, mode);
+  int fd = fsp->conn->vfs_ops.open(dos_to_unix(fname, False), O_RDWR, mode);
+  file_fd_struct *fd_ptr = fsp->fd_ptr;
 
   if(fd == -1)
     return;
@@ -146,18 +149,21 @@ static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr)
 fd support routines - attempt to close the file referenced by this fd.
 Decrements the ref_count and returns it.
 ****************************************************************************/
-uint16 fd_attempt_close(files_struct *fsp)
+uint16 fd_attempt_close(files_struct *fsp, int *err_ret)
 {
   extern struct current_user current_user;
-  file_fd_struct *fd_ptr = fsp->fd_ptr;
+  file_fd_struct *fd_ptr;
   uint16 ret_ref;
 
-  if (fd_ptr != NULL) {
-      ret_ref = fd_ptr->ref_count;
-  } else {
+  *err_ret = 0;
+
+  if ((fsp == NULL) || (fsp->fd_ptr == NULL)) {
       return 0;
   }
 
+  fd_ptr = fsp->fd_ptr;
+  ret_ref = fd_ptr->ref_count;
+
   DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
           fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode,
           fd_ptr->real_open_flags,
@@ -169,12 +175,26 @@ uint16 fd_attempt_close(files_struct *fsp)
   ret_ref = fd_ptr->ref_count;
 
   if(fd_ptr->ref_count == 0) {
-    if(fd_ptr->fd != -1)
-      fsp->conn->vfs_ops.close(fd_ptr->fd);
-    if(fd_ptr->fd_readonly != -1)
-      fsp->conn->vfs_ops.close(fd_ptr->fd_readonly);
-    if(fd_ptr->fd_writeonly != -1)
-      fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly);
+
+    if(fd_ptr->fd != -1) {
+      if(fsp->conn->vfs_ops.close(fd_ptr->fd) < 0)
+        *err_ret = errno;
+       }
+
+    if(fd_ptr->fd_readonly != -1) {
+      if(fsp->conn->vfs_ops.close(fd_ptr->fd_readonly) < 0) {
+        if(*err_ret == 0)
+          *err_ret = errno;
+      }
+       }
+
+    if(fd_ptr->fd_writeonly != -1) {
+      if(fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly) < 0) {
+        if(*err_ret == 0)
+          *err_ret = errno;
+      }
+       }
+
     /*
      * Delete this fd_ptr.
      */
@@ -183,7 +203,7 @@ uint16 fd_attempt_close(files_struct *fsp)
     fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
   }
 
- return ret_ref;
 return ret_ref;
 }
 
 /****************************************************************************
@@ -199,8 +219,16 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
 {
   pid_t child_pid;
 
+  /*
+   * We need to temporarily stop CatchChild from eating 
+   * SIGCLD signals as it also eats the exit status code. JRA.
+   */
+
+  CatchChildLeaveStatus();
+
   if((child_pid = fork()) < 0) {
     DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
+    CatchChild();
     return False;
   }
 
@@ -210,11 +238,23 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
      */
     pid_t wpid;
     int status_code;
-    if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
-      DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
+
+    while ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
+      if(errno == EINTR) {
+        errno = 0;
+        continue;
+      }
+      DEBUG(0,("check_access_allowed_for_current_user: The process \
+is no longer waiting ! Error = %s\n", strerror(errno) ));
+      CatchChild();
       return(False);
     }
 
+       /*
+        * Go back to ignoring children.
+        */
+       CatchChild();
+
     if (child_pid != wpid) {
       DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
       return(False);
@@ -250,7 +290,7 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
       /* Access denied. */
       _exit(EACCES);
     }
-    close(fd);
+    conn->vfs_ops.close(fd);
     DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
     _exit(0);
   }
@@ -261,11 +301,12 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
 /****************************************************************************
 check a filename for the pipe string
 ****************************************************************************/
+
 static void check_for_pipe(char *fname)
 {
        /* special case of pipe opens */
        char s[10];
-       StrnCpy(s,fname,9);
+       StrnCpy(s,fname,sizeof(s)-1);
        strlower(s);
        if (strstr(s,"pipe/")) {
                DEBUG(3,("Rejecting named pipe open for %s\n",fname));
@@ -277,6 +318,7 @@ static void check_for_pipe(char *fname)
 /****************************************************************************
 open a file
 ****************************************************************************/
+
 static void open_file(files_struct *fsp,connection_struct *conn,
                      char *fname1,int flags,mode_t mode, SMB_STRUCT_STAT *sbuf)
 {
@@ -288,7 +330,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
 
   fsp->open = False;
   fsp->fd_ptr = 0;
-  fsp->granted_oplock = False;
+  fsp->oplock_type = NO_OPLOCK;
   errno = EPERM;
 
   pstrcpy(fname,fname1);
@@ -305,7 +347,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
    * JRA.
    */
 
-  if (conn->read_only && !conn->printer) {
+  if (!CAN_WRITE(conn) && !conn->printer) {
     /* It's a read-only share - fail if we wanted to write. */
     if(accmode != O_RDONLY) {
       DEBUG(3,("Permission denied opening %s\n",fname));
@@ -397,7 +439,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
      * between the last open and now. 
      */
     if(fd_ptr->real_open_flags != O_RDWR)
-      fd_attempt_reopen(fname, mode, fd_ptr);
+      fd_attempt_reopen(fname, mode, fsp);
 
     /*
      * Ensure that if we wanted write access
@@ -459,10 +501,11 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     pstrcpy(dname,fname);
     p = strrchr(dname,'/');
     if (p) *p = 0;
-    if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),&dum1,&dum2,&dum3) < 
+    if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),False,&dum1,&dum2,&dum3) < 
        (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
-      if(fd_attempt_close(fsp) == 0)
-        conn->vfs_ops.unlink(dos_to_unix(fname,False));
+      int err;
+      if(fd_attempt_close(fsp, &err) == 0)
+        conn->vfs_ops.unlink(dos_to_unix(fname, False));
       fsp->fd_ptr = 0;
       errno = ENOSPC;
       return;
@@ -471,10 +514,11 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     
   if (fd_ptr->fd < 0)
   {
+    int err;
     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
       fname,strerror(errno),flags));
     /* Ensure the ref_count is decremented. */
-    fd_attempt_close(fsp);
+    fd_attempt_close(fsp,&err);
     check_for_pipe(fname);
     return;
   }
@@ -484,11 +528,12 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     if(sbuf == 0) {
       /* Do the fstat */
       if(conn->vfs_ops.fstat(fd_ptr->fd, &statbuf) == -1) {
+         int err;
         /* Error - backout !! */
         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
                  fd_ptr->fd, fname,strerror(errno)));
         /* Ensure the ref_count is decremented. */
-        fd_attempt_close(fsp);
+        fd_attempt_close(fsp,&err);
         return;
       }
       sbuf = &statbuf;
@@ -506,17 +551,17 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     fsp->size = 0;
     fsp->pos = -1;
     fsp->open = True;
-    fsp->mmap_ptr = NULL;
-    fsp->mmap_size = 0;
     fsp->can_lock = True;
     fsp->can_read = ((flags & O_WRONLY)==0);
     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
     fsp->share_mode = 0;
     fsp->print_file = conn->printer;
     fsp->modified = False;
-    fsp->granted_oplock = False;
-    fsp->sent_oplock_break = False;
+    fsp->oplock_type = NO_OPLOCK;
+    fsp->sent_oplock_break = NO_BREAK_SENT;
     fsp->is_directory = False;
+    fsp->stat_open = False;
+    fsp->directory_delete_on_close = False;
     fsp->conn = conn;
     /*
      * Note that the file name here is the *untranslated* name
@@ -527,6 +572,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
      */
     string_set(&fsp->fsp_name,fname);
     fsp->wbmpx_ptr = NULL;      
+    fsp->wcp = NULL; /* Write cache pointer. */
 
     /*
      * If the printer is marked as postscript output a leading
@@ -548,48 +594,20 @@ static void open_file(files_struct *fsp,connection_struct *conn,
   }
 }
 
-/****************************************************************************
- If it's a read-only file, and we were compiled with mmap enabled,
- try and mmap the file. This is split out from open_file() above
- as mmap'ing the file can cause the kernel reference count to
- be incremented, which can cause kernel oplocks to be refused.
- Splitting this call off allows the kernel oplock to be granted, then
- the file mmap'ed.
-****************************************************************************/
-
-static void mmap_open_file(files_struct *fsp)
-{
-#if WITH_MMAP
-  /* mmap it if read-only */
-  if (!fsp->can_write) {
-         fsp->mmap_size = dos_file_size(fsp->fsp_name);
-         if (fsp->mmap_size < MAX_MMAP_SIZE) {
-                 fsp->mmap_ptr = (char *)sys_mmap(NULL,fsp->mmap_size,
-                                              PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,(SMB_OFF_T)0);
-
-                 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
-                         DEBUG(3,("Failed to mmap() %s - %s\n",
-                                  fsp->fsp_name,strerror(errno)));
-                         fsp->mmap_ptr = NULL;
-                 }
-         }
-  }
-#endif
-}
-
 /****************************************************************************
   C. Hoch 11/22/95
   Helper for open_file_shared. 
   Truncate a file after checking locking; close file if locked.
   **************************************************************************/
-static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, 
+
+static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token, 
                                   BOOL *share_locked)
 {
        if (fsp->can_write){
                SMB_OFF_T mask2 = ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
                SMB_OFF_T mask = (mask2<<2);
                
-               if (is_locked(fsp,conn,~mask,0,F_WRLCK)){
+               if (is_locked(fsp,conn,~mask,0,WRITE_LOCK)){
                        /* If share modes are in force for this connection we
                           have the share entry locked. Unlock it before closing. */
                        if (*share_locked && lp_share_modes(SNUM(conn)))
@@ -608,63 +626,121 @@ static void truncate_unless_locked(files_struct *fsp, connection_struct *conn,
 }
 
 
+/*******************************************************************
+return True if the filename is one of the special executable types
+********************************************************************/
+static BOOL is_executable(char *fname)
+{
+       if ((fname = strrchr(fname,'.'))) {
+               if (strequal(fname,".com") ||
+                   strequal(fname,".dll") ||
+                   strequal(fname,".exe") ||
+                   strequal(fname,".sym")) {
+                       return True;
+               }
+       }
+       return False;
+}
+
 enum {AFAIL,AREAD,AWRITE,AALL};
 
 /*******************************************************************
 reproduce the share mode access table
+this is horrendoously complex, and really can't be justified on any
+rational grounds except that this is _exactly_ what NT does. See
+the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
+test routines.
 ********************************************************************/
 static int access_table(int new_deny,int old_deny,int old_mode,
-                       int share_pid,char *fname)
+                       BOOL same_pid, BOOL isexe)
 {
-  if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
-
-  if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
-    int pid = getpid();
-    if (old_deny == new_deny && share_pid == pid) 
-       return(AALL);    
-
-    if (old_mode == 0) return(AREAD);
-
-    /* the new smbpub.zip spec says that if the file extension is
-       .com, .dll, .exe or .sym then allow the open. I will force
-       it to read-only as this seems sensible although the spec is
-       a little unclear on this. */
-    if ((fname = strrchr(fname,'.'))) {
-      if (strequal(fname,".com") ||
-         strequal(fname,".dll") ||
-         strequal(fname,".exe") ||
-         strequal(fname,".sym"))
-       return(AREAD);
-    }
+         if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
 
-    return(AFAIL);
-  }
+         if (same_pid) {
+                 if (isexe && old_mode == DOS_OPEN_RDONLY && 
+                     old_deny == DENY_DOS && new_deny == DENY_READ) {
+                         return AFAIL;
+                 }
+                 if (!isexe && old_mode == DOS_OPEN_RDONLY && 
+                     old_deny == DENY_DOS && new_deny == DENY_DOS) {
+                         return AREAD;
+                 }
+                 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
+                         if (isexe) return AFAIL;
+                         if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
+                         return AALL;
+                 }
+                 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
+                         if (new_deny == DENY_FCB || new_deny == DENY_READ) {
+                                 if (isexe) return AREAD;
+                                 return AFAIL;
+                         }
+                 }
+                 if (old_deny == DENY_FCB) {
+                         if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
+                         return AFAIL;
+                 }
+         }
 
-  switch (new_deny) 
-    {
-    case DENY_WRITE:
-      if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
-      if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
-      if (old_deny==DENY_NONE && old_mode==0) return(AALL);
-      return(AFAIL);
-    case DENY_READ:
-      if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
-      if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
-      if (old_deny==DENY_NONE && old_mode==1) return(AALL);
-      return(AFAIL);
-    case DENY_NONE:
-      if (old_deny==DENY_WRITE) return(AREAD);
-      if (old_deny==DENY_READ) return(AWRITE);
-      if (old_deny==DENY_NONE) return(AALL);
-      return(AFAIL);      
-    }
-  return(AFAIL);      
+         if (old_deny == DENY_DOS || new_deny == DENY_DOS || 
+             old_deny == DENY_FCB || new_deny == DENY_FCB) {
+                 if (isexe) {
+                         if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
+                                 return AFAIL;
+                         }
+                         if (old_deny == DENY_DOS) {
+                                 if (new_deny == DENY_READ && 
+                                     (old_mode == DOS_OPEN_RDONLY || 
+                                      old_mode == DOS_OPEN_RDWR)) {
+                                         return AFAIL;
+                                 }
+                                 if (new_deny == DENY_WRITE && 
+                                     (old_mode == DOS_OPEN_WRONLY || 
+                                      old_mode == DOS_OPEN_RDWR)) {
+                                         return AFAIL;
+                                 }
+                                 return AALL;
+                         }
+                         if (old_deny == DENY_NONE) return AALL;
+                         if (old_deny == DENY_READ) return AWRITE;
+                         if (old_deny == DENY_WRITE) return AREAD;
+                 }
+                 /* it isn't a exe, dll, sym or com file */
+                 if (old_deny == new_deny && same_pid)
+                         return(AALL);    
+
+                 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
+                 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
+                 
+                 return(AFAIL);
+         }
+         
+         switch (new_deny) 
+                 {
+                 case DENY_WRITE:
+                         if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
+                         if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
+                         if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
+                         return(AFAIL);
+                 case DENY_READ:
+                         if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
+                         if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
+                         if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
+                         return(AFAIL);
+                 case DENY_NONE:
+                         if (old_deny==DENY_WRITE) return(AREAD);
+                         if (old_deny==DENY_READ) return(AWRITE);
+                         if (old_deny==DENY_NONE) return(AALL);
+                         return(AFAIL);      
+                 }
+         return(AFAIL);      
 }
 
 
 /****************************************************************************
 check if we can open a file with a share mode
 ****************************************************************************/
+
 static int check_share_mode( share_mode_entry *share, int deny_mode, 
                             char *fname,
                             BOOL fcbopen, int *flags)
@@ -686,29 +762,18 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
     return False;
   }
 
-  if (old_deny_mode > 4 || old_open_mode > 2)
-  {
-    DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
-               deny_mode,old_deny_mode,old_open_mode,fname));
-
-    unix_ERR_class = ERRDOS;
-    unix_ERR_code = ERRbadshare;
-
-    return False;
-  }
-
   {
     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
-                                share->pid,fname);
+                                     (share->pid == getpid()),is_executable(fname));
 
     if ((access_allowed == AFAIL) ||
         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
-        (access_allowed == AREAD && *flags == O_WRONLY) ||
-        (access_allowed == AWRITE && *flags == O_RDONLY))
+        (access_allowed == AREAD && *flags != O_RDONLY) ||
+        (access_allowed == AWRITE && *flags != O_WRONLY))
     {
       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
                 deny_mode,old_deny_mode,old_open_mode,
-                share->pid,fname, fcbopen, *flags, access_allowed));
+                (int)share->pid,fname, fcbopen, *flags, access_allowed));
 
       unix_ERR_class = ERRDOS;
       unix_ERR_code = ERRbadshare;
@@ -727,33 +792,39 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
   return True;
 }
 
-
 /****************************************************************************
 open a file with a share mode
 ****************************************************************************/
-void open_file_shared(files_struct *fsp, connection_struct *conn,
-                          char *fname, int share_mode, int ofun, 
-                          mode_t mode, int oplock_request, int *Access,
-                          int *action)
+
+void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
+                     mode_t mode,int oplock_request, int *Access,int *action)
 {
   int flags=0;
   int flags2=0;
   int deny_mode = GET_DENY_MODE(share_mode);
   BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
   SMB_STRUCT_STAT sbuf;
-  BOOL file_existed = vfs_file_exist(conn, dos_to_unix(fname,False), &sbuf);
+  BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
   BOOL share_locked = False;
   BOOL fcbopen = False;
+  int token = 0;
   SMB_DEV_T dev = 0;
   SMB_INO_T inode = 0;
   int num_share_modes = 0;
-
+  int oplock_contention_count = 0;
+  BOOL all_current_opens_are_level_II = False;
   fsp->open = False;
   fsp->fd_ptr = 0;
 
   DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
         fname, share_mode, ofun, (int)mode,  oplock_request ));
 
+
+  /* ignore any oplock requests if oplocks are disabled */
+  if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
+         oplock_request = 0;
+  }
+
   /* this is for OS/2 EAs - try and say we don't support them */
   if (strstr(fname,".+,;=[].")) 
   {
@@ -832,9 +903,6 @@ void open_file_shared(files_struct *fsp, connection_struct *conn,
     return;
   }
 
-  if (deny_mode == DENY_FCB)
-    deny_mode = DENY_DOS;
-
   if (lp_share_modes(SNUM(conn))) 
   {
     int i;
@@ -861,6 +929,8 @@ void open_file_shared(files_struct *fsp, connection_struct *conn,
       {
 
         broke_oplock = False;
+        all_current_opens_are_level_II = True;
+
         for(i = 0; i < num_share_modes; i++)
         {
           share_mode_entry *share_entry = &old_shares[i];
@@ -872,7 +942,8 @@ void open_file_shared(files_struct *fsp, connection_struct *conn,
            * Check if someone has an oplock on this file. If so we must break 
            * it before continuing. 
            */
-          if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
+          if((oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
+             (!oplock_request && (share_entry->op_type != NO_OPLOCK)))
           {
 
             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
@@ -894,7 +965,10 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
             }
             lock_share_entry(conn, dev, inode);
             broke_oplock = True;
+            all_current_opens_are_level_II = False;
             break;
+          } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+            all_current_opens_are_level_II = False;
           }
 
           /* someone else has a share lock on it, check to see 
@@ -913,6 +987,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
         {
           free((char *)old_shares);
           num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+          oplock_contention_count++;
         }
       } while(broke_oplock);
     }
@@ -921,6 +996,18 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
       free((char *)old_shares);
   }
 
+  /*
+   * Refuse to grant an oplock in case the contention limit is
+   * reached when going through the lock list multiple times.
+   */
+
+  if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn)))
+  {
+    oplock_request = 0;
+    DEBUG(4,("open_file_shared: oplock contention = %d. Not granting oplock.\n",
+          oplock_contention_count ));
+  }
+
   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
           flags,flags2,(int)mode));
 
@@ -978,18 +1065,19 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
     {
       uint16 port = 0;
 
-      /* JRA. Currently this only services Exlcusive and batch
-         oplocks (no other opens on this file). This needs to
-         be extended to level II oplocks (multiple reader
-         oplocks). */
+      /* 
+       * Setup the oplock info in both the shared memory and
+       * file structs.
+       */
 
-      if((oplock_request) && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
-             !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp) )
-      {
+      if(oplock_request && (num_share_modes == 0) && 
+             !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
         port = global_oplock_port;
-      }
-      else
-      {
+      } else if (oplock_request && all_current_opens_are_level_II) {
+        port = global_oplock_port;
+        oplock_request = LEVEL_II_OPLOCK;
+        set_file_oplock(fsp, oplock_request);
+      } else {
         port = 0;
         oplock_request = 0;
       }
@@ -998,20 +1086,76 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
     }
 
     if ((flags2&O_TRUNC) && file_existed)
-      truncate_unless_locked(fsp,conn,&share_locked);
-
-    /*
-     * Attempt to mmap a read only file.
-     * Moved until after a kernel oplock may
-     * be granted due to reference count issues. JRA.
-     */
-    mmap_open_file(fsp);
+      truncate_unless_locked(fsp,conn,token,&share_locked);
   }
 
   if (share_locked && lp_share_modes(SNUM(conn)))
     unlock_share_entry( conn, dev, inode);
 }
 
+/****************************************************************************
+ Open a file for permissions read only. Return a pseudo file entry
+ with the 'stat_open' flag set and a fd_ptr of NULL.
+****************************************************************************/
+
+int open_file_stat(files_struct *fsp,connection_struct *conn,
+                  char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
+{
+       extern struct current_user current_user;
+
+       if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) {
+               DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
+                        fname, strerror(errno) ));
+               return -1;
+       }
+
+       if(S_ISDIR(pst->st_mode)) {
+               DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
+               return -1;
+       }
+
+       *action = FILE_WAS_OPENED;
+       
+       DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
+
+       /*
+        * Setup the files_struct for it.
+        */
+       
+       fsp->fd_ptr = NULL;
+       conn->num_files_open++;
+       fsp->mode = 0;
+       GetTimeOfDay(&fsp->open_time);
+       fsp->vuid = current_user.key.vuid;
+       fsp->size = 0;
+       fsp->pos = -1;
+       fsp->open = True;
+       fsp->can_lock = False;
+       fsp->can_read = False;
+       fsp->can_write = False;
+       fsp->share_mode = 0;
+       fsp->print_file = False;
+       fsp->modified = False;
+       fsp->oplock_type = NO_OPLOCK;
+       fsp->sent_oplock_break = NO_BREAK_SENT;
+       fsp->is_directory = False;
+       fsp->stat_open = True;
+       fsp->directory_delete_on_close = False;
+       fsp->conn = conn;
+       /*
+        * Note that the file name here is the *untranslated* name
+        * ie. it is still in the DOS codepage sent from the client.
+        * All use of this filename will pass though the sys_xxxx
+        * functions which will do the dos_to_unix translation before
+        * mapping into a UNIX filename. JRA.
+        */
+       string_set(&fsp->fsp_name,fname);
+       fsp->wbmpx_ptr = NULL;
+    fsp->wcp = NULL; /* Write cache pointer. */
+
+       return 0;
+}
+
 /****************************************************************************
  Open a directory from an NT SMB call.
 ****************************************************************************/
@@ -1021,26 +1165,56 @@ int open_directory(files_struct *fsp,connection_struct *conn,
 {
        extern struct current_user current_user;
        SMB_STRUCT_STAT st;
+       BOOL got_stat = False;
 
-       if (smb_ofun & 0x10) {
-               /*
-                * Create the directory.
-                */
+       if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) {
+               got_stat = True;
+       }
 
-               if(conn->vfs_ops.mkdir(dos_to_unix(fname,False), 
-                                      unix_mode(conn,aDIR)) < 0) {
-                       DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
-                                fname, strerror(errno) ));
-                       return -1;
-               }
+       if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
+               errno = EEXIST; /* Setup so correct error is returned to client. */
+               return -1;
+       }
+
+       if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
+
+               if (got_stat) {
+
+                       if(!S_ISDIR(st.st_mode)) {
+                               DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
+                               errno = EACCES;
+                               return -1;
+                       }
+                       *action = FILE_WAS_OPENED;
+
+               } else {
 
-               *action = FILE_WAS_CREATED;
+                       /*
+                        * Try and create the directory.
+                        */
+
+                       if(!CAN_WRITE(conn)) {
+                               DEBUG(2,("open_directory: failing create on read-only share\n"));
+                               errno = EACCES;
+                               return -1;
+                       }
+
+                       if(conn->vfs_ops.mkdir(dos_to_unix(fname, False), 
+                                               unix_mode(conn,aDIR, fname)) < 0) {
+                               DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
+                                        fname, strerror(errno) ));
+                               return -1;
+                       }
+                       *action = FILE_WAS_CREATED;
+
+               }
        } else {
+
                /*
-                * Check that it *was* a directory.
+                * Don't create - just check that it *was* a directory.
                 */
 
-               if(conn->vfs_ops.stat(dos_to_unix(fname,False), &st) < 0) {
+               if(!got_stat) {
                        DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
                                 fname, strerror(errno) ));
                        return -1;
@@ -1050,6 +1224,7 @@ int open_directory(files_struct *fsp,connection_struct *conn,
                        DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
                        return -1;
                }
+
                *action = FILE_WAS_OPENED;
        }
        
@@ -1068,17 +1243,16 @@ int open_directory(files_struct *fsp,connection_struct *conn,
        fsp->size = 0;
        fsp->pos = -1;
        fsp->open = True;
-       fsp->mmap_ptr = NULL;
-       fsp->mmap_size = 0;
        fsp->can_lock = True;
        fsp->can_read = False;
        fsp->can_write = False;
        fsp->share_mode = 0;
        fsp->print_file = False;
        fsp->modified = False;
-       fsp->granted_oplock = False;
-       fsp->sent_oplock_break = False;
+       fsp->oplock_type = NO_OPLOCK;
+       fsp->sent_oplock_break = NO_BREAK_SENT;
        fsp->is_directory = True;
+       fsp->directory_delete_on_close = False;
        fsp->conn = conn;
        /*
         * Note that the file name here is the *untranslated* name
@@ -1093,10 +1267,9 @@ int open_directory(files_struct *fsp,connection_struct *conn,
        return 0;
 }
 
-
 /*******************************************************************
-check if the share mode on a file allows it to be deleted or unlinked
-return True if sharing doesn't prevent the operation
+ Check if the share mode on a file allows it to be deleted or unlinked.
+ Return True if sharing doesn't prevent the operation.
 ********************************************************************/
 
 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
@@ -1106,7 +1279,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
   share_mode_entry *old_shares = 0;
   int num_share_modes;
   SMB_STRUCT_STAT sbuf;
-  int pid = getpid();
+  pid_t pid = getpid();
   SMB_DEV_T dev;
   SMB_INO_T inode;
 
@@ -1143,9 +1316,16 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
          * Check if someone has an oplock on this file. If so we must 
          * break it before continuing. 
          */
-        if(share_entry->op_type & BATCH_OPLOCK)
+        if(BATCH_OPLOCK_TYPE(share_entry->op_type))
         {
 
+#if 0
+
+/* JRA. Try removing this code to see if the new oplock changes
+   fix the problem. I'm dubious, but Andrew is recommending we
+   try this....
+*/
+
           /*
            * It appears that the NT redirector may have a bug, in that
            * it tries to do an SMBmv on a file that it has open with a
@@ -1175,6 +1355,7 @@ batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (do
             continue;
           }
           else
+#endif /* 0 */
           {
 
             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
@@ -1210,7 +1391,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
          * if we can too.
          */
 
-        if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || (share_entry->pid != pid))
+        if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || 
+           (share_entry->pid != pid))
           goto free_and_exit;
 
       } /* end for */
index 48d92c356996575e910af7f33dfcd9cc2f342b72..4b6e3962b8968e49ce45efbb00d523c6bafa5825 100644 (file)
@@ -26,18 +26,30 @@ extern int DEBUGLEVEL;
 /* Oplock ipc UDP socket. */
 static int oplock_sock = -1;
 uint16 global_oplock_port = 0;
-#if defined(HAVE_KERNEL_OPLOCKS)
 static int oplock_pipe_read = -1;
+
+#if defined(HAVE_KERNEL_OPLOCKS)
 static int oplock_pipe_write = -1;
-#endif /* HAVE_KERNEL_OPLOCKS */
+#endif
 
 /* Current number of oplocks we have outstanding. */
-int32 global_oplocks_open = 0;
+static int32 exclusive_oplocks_open = 0;
+static int32 level_II_oplocks_open = 0;
+BOOL global_client_failed_oplock_break = False;
 BOOL global_oplock_break = False;
 
 extern int smb_read_error;
 
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local);
+
+/****************************************************************************
+ Get the number of current exclusive oplocks.
+****************************************************************************/
+
+int32 get_number_of_exclusive_open_oplocks(void)
+{
+  return exclusive_oplocks_open;
+}
 
 /****************************************************************************
  Setup the kernel level oplock backchannel for this process.
@@ -63,8 +75,9 @@ BOOL setup_kernel_oplock_pipe(void)
 }
 
 /****************************************************************************
-  open the oplock IPC socket communication
+ Open the oplock IPC socket communication.
 ****************************************************************************/
+
 BOOL open_oplock_ipc(void)
 {
   struct sockaddr_in sock_name;
@@ -127,15 +140,13 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
     int selrtn;
     int maxfd = oplock_sock;
 
-#if defined(HAVE_KERNEL_OPLOCKS)
-    if(lp_kernel_oplocks())
+    if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
       maxfd = MAX(maxfd, oplock_pipe_read);
-#endif /* HAVE_KERNEL_OPLOCKS */
 
     to.tv_sec = timeout / 1000;
     to.tv_usec = (timeout % 1000) * 1000;
 
-    selrtn = sys_select(maxfd+1,fds,NULL, &to);
+    selrtn = sys_select(maxfd+1,fds,NULL,&to);
 
     /* Check if error */
     if(selrtn == -1) {
@@ -196,7 +207,7 @@ Error was %s.\n", strerror(errno) ));
     }
 
     dev = (SMB_DEV_T)os.os_dev;
-    inode = (SMB_DEV_T)os.os_ino;
+    inode = (SMB_INO_T)os.os_ino;
 
     DEBUG(5,("receive_local_message: kernel oplock break request received for \
 dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
@@ -212,14 +223,9 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
     buffer += OPBRK_CMD_HEADER_LEN;
 
     SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
-    SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
 
-#ifdef LARGE_SMB_INO_T
-    SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
-    SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
-#else /* LARGE_SMB_INO_T */
-    SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
-#endif /* LARGE_SMB_INO_T */
+    memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
+    memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));  
 
     return True;
   }
@@ -265,11 +271,11 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
 }
 
 /****************************************************************************
- Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
disabled (just sets flags). Returns True if oplock set.
+ Attempt to set an kernel oplock on a file. Always returns True if kernel
oplocks not available.
 ****************************************************************************/
 
-BOOL set_file_oplock(files_struct *fsp)
+static BOOL set_kernel_oplock(files_struct *fsp, int oplock_type)
 {
 #if defined(HAVE_KERNEL_OPLOCKS)
   if(lp_kernel_oplocks()) {
@@ -293,23 +299,38 @@ inode = %.0f. Another process had the file open.\n",
 
   }
 #endif /* HAVE_KERNEL_OPLOCKS */
+  return True;
+}
 
-  DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n", 
-        fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
+/****************************************************************************
+ Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
+ disabled (just sets flags). Returns True if oplock set.
+****************************************************************************/
 
-  fsp->granted_oplock = True;
-  fsp->sent_oplock_break = False;
-  global_oplocks_open++;
+BOOL set_file_oplock(files_struct *fsp, int oplock_type)
+{
+  if (!set_kernel_oplock(fsp, oplock_type))
+    return False;
+
+  fsp->oplock_type = oplock_type;
+  fsp->sent_oplock_break = NO_BREAK_SENT;
+  if ( oplock_type == LEVEL_II_OPLOCK)
+    level_II_oplocks_open++;
+  else
+    exclusive_oplocks_open++;
+
+  DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+        fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
+        (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
 
   return True;
 }
 
 /****************************************************************************
- Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just clears flags).
+ Release a kernel oplock on a file.
 ****************************************************************************/
 
-static void release_file_oplock(files_struct *fsp)
+static void release_kernel_oplock(files_struct *fsp)
 {
 #if defined(HAVE_KERNEL_OPLOCKS)
 
@@ -322,20 +343,20 @@ static void release_file_oplock(files_struct *fsp)
        * oplock state of this file.
        */
       int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
-      dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
+      dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
 oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
                         (double)fsp->fd_ptr->inode, state );
     }
 
     /*
-     * Remote the kernel oplock on this file.
+     * Remove the kernel oplock on this file.
      */
 
     if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
     {
       if( DEBUGLVL( 0 ))
       {
-        dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
+        dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
         dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
                  fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, 
                  (double)fsp->fd_ptr->inode, strerror(errno) );
@@ -343,10 +364,90 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
     }
   }
 #endif /* HAVE_KERNEL_OPLOCKS */
+}
+
+
+/****************************************************************************
+ Attempt to release an oplock on a file. Decrements oplock count.
+****************************************************************************/
+
+void release_file_oplock(files_struct *fsp)
+{
+  release_kernel_oplock(fsp);
+
+  if (fsp->oplock_type == LEVEL_II_OPLOCK)
+    level_II_oplocks_open--;
+  else
+    exclusive_oplocks_open--;
+
+  fsp->oplock_type = NO_OPLOCK;
+  fsp->sent_oplock_break = NO_BREAK_SENT;
+
+  flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
+}
+
+/****************************************************************************
+ Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
+****************************************************************************/
+
+static void downgrade_file_oplock(files_struct *fsp)
+{
+  release_kernel_oplock(fsp);
+  fsp->oplock_type = LEVEL_II_OPLOCK;
+  exclusive_oplocks_open--;
+  level_II_oplocks_open++;
+  fsp->sent_oplock_break = NO_BREAK_SENT;
+}
+
+/****************************************************************************
+ Remove a file oplock. Copes with level II and exclusive.
+ Locks then unlocks the share mode lock.
+****************************************************************************/
+
+BOOL remove_oplock(files_struct *fsp)
+{
+  SMB_DEV_T dev = fsp->fd_ptr->dev;
+  SMB_INO_T inode = fsp->fd_ptr->inode;
+  BOOL ret = True;
+
+  /* Remove the oplock flag from the sharemode. */
+  if (lock_share_entry(fsp->conn, dev, inode) == False) {
+    DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
+          fsp->fsp_name ));
+    ret = False;
+  }
+
+  if (fsp->sent_oplock_break == EXCLUSIVE_BREAK_SENT) {
+
+    /*
+     * Deal with a reply when a break-to-none was sent.
+     */
+
+    if(remove_share_oplock(fsp)==False) {
+      DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
+      ret = False;
+    }
+
+    release_file_oplock(fsp);
+
+  } else {
+
+    /*
+     * Deal with a reply when a break-to-level II was sent.
+     */
+
+    if(downgrade_share_oplock(fsp)==False) {
+      DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
+      ret = False;
+    }
 
-  fsp->granted_oplock = False;
-  fsp->sent_oplock_break = False;
-  global_oplocks_open--;
+    downgrade_file_oplock(fsp);
+  }
+
+  unlock_share_entry(fsp->conn, dev, inode);
+  return ret;
 }
 
 /****************************************************************************
@@ -358,14 +459,16 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
 int setup_oplock_select_set( fd_set *fds)
 {
   int maxfd = oplock_sock;
+
+  if(oplock_sock == -1)
+    return 0;
+
   FD_SET(oplock_sock,fds);
 
-#if defined(HAVE_KERNEL_OPLOCKS)
-  if(lp_kernel_oplocks()) {
+  if(lp_kernel_oplocks() && (oplock_pipe_read != -1)) {
     FD_SET(oplock_pipe_read,fds); 
     maxfd = MAX(maxfd,oplock_pipe_read);
   }
-#endif /* HAVE_KERNEL_OPLOCKS */
 
   return maxfd;
 }
@@ -382,9 +485,10 @@ BOOL process_local_message(char *buffer, int buf_size)
   char *msg_start;
   SMB_DEV_T dev;
   SMB_INO_T inode;
-  uint32 remotepid;
+  pid_t remotepid;
   struct timeval tval;
   struct timeval *ptval = NULL;
+  uint16 break_cmd_type;
 
   msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
   from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
@@ -398,7 +502,9 @@ BOOL process_local_message(char *buffer, int buf_size)
    * Pull the info out of the requesting packet.
    */
 
-  switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
+  break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
+
+  switch(break_cmd_type)
   {
 #if defined(HAVE_KERNEL_OPLOCKS)
     case KERNEL_OPLOCK_BREAK_CMD:
@@ -410,18 +516,8 @@ should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
         return False;
       }
       {
-        /*
-         * Warning - beware of SMB_INO_T <> 4 bytes. !!
-         */
-#ifdef LARGE_SMB_INO_T
-        SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
-        SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
-        inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
-        inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
-
-        dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
+        memcpy((char *)&inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(inode));
+        memcpy((char *)&dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(dev));
 
         ptval = NULL;
 
@@ -432,36 +528,34 @@ file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
 #endif /* HAVE_KERNEL_OPLOCKS */
 
     case OPLOCK_BREAK_CMD:
+    case LEVEL_II_OPLOCK_BREAK_CMD:
+
       /* Ensure that the msg length is correct. */
       if(msg_len != OPLOCK_BREAK_MSG_LEN)
       {
-        DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
-should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
+        DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
+              (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
         return False;
       }
       {
-        /*
-         * Warning - beware of SMB_INO_T <> 4 bytes. !!
-         */
-#ifdef LARGE_SMB_INO_T
-        SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-        SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
-        inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
-        inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
+        long usec;
+        time_t sec;
 
-        dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
-
-        tval.tv_sec = (time_t)IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
-        tval.tv_usec = (long)IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
+        memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+        memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
+        memcpy((char *)&sec, msg_start+OPLOCK_BREAK_SEC_OFFSET,sizeof(sec));
+        tval.tv_sec = sec;
+        memcpy((char *)&usec, msg_start+OPLOCK_BREAK_USEC_OFFSET, sizeof(usec));
+        tval.tv_usec = usec;
 
         ptval = &tval;
 
-        remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
+        memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
 
-        DEBUG(5,("process_local_message: oplock break request from \
-pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
+        DEBUG(5,("process_local_message: (%s) oplock break request from \
+pid %d, port %d, dev = %x, inode = %.0f\n",
+             (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
+             (int)remotepid, from_port, (unsigned int)dev, (double)inode));
       }
       break;
 
@@ -475,27 +569,17 @@ reply - dumping info.\n"));
       if(msg_len != OPLOCK_BREAK_MSG_LEN)
       {
         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
-(was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
+(was %d, should be %d).\n", (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
         return False;
       }
 
       {
-        /*
-         * Warning - beware of SMB_INO_T <> 4 bytes. !!
-         */
-#ifdef LARGE_SMB_INO_T
-        SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-        SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
-        inode = inode_low | (inode_high << 32);
-#else /* LARGE_SMB_INO_T */
-        inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-#endif /* LARGE_SMB_INO_T */
-
-        remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
-        dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
+        memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+        memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
+        memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
 
         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
+pid %d, port %d, dev = %x, inode = %.0f\n", (int)remotepid, from_port, (unsigned int)dev, (double)inode));
 
        }
        return False;
@@ -510,9 +594,9 @@ pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)
    * Now actually process the break request.
    */
 
-  if(global_oplocks_open != 0)
+  if((exclusive_oplocks_open + level_II_oplocks_open) != 0)
   {
-    if(oplock_break(dev, inode, ptval) == False)
+    if (oplock_break(dev, inode, ptval, False) == False)
     {
       DEBUG(0,("process_local_message: oplock break failed.\n"));
       return False;
@@ -531,7 +615,7 @@ oplocks. Returning success.\n"));
   }
 
   /* 
-   * Do the appropriate reply - none in the kernel case.
+   * Do the appropriate reply - none in the kernel or level II case.
    */
 
   if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
@@ -541,7 +625,7 @@ oplocks. Returning success.\n"));
     /* Send the message back after OR'ing in the 'REPLY' bit. */
     SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
 
-    ZERO_STRUCT(toaddr);
+    memset((char *)&toaddr,'\0',sizeof(toaddr));
     toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
     toaddr.sin_port = htons(from_port);
     toaddr.sin_family = AF_INET;
@@ -550,40 +634,77 @@ oplocks. Returning success.\n"));
             (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
     {
       DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
-                remotepid, strerror(errno)));
+                (int)remotepid, strerror(errno)));
       return False;
     }
 
     DEBUG(5,("process_local_message: oplock break reply sent to \
 pid %d, port %d, for file dev = %x, inode = %.0f\n",
-          remotepid, from_port, (unsigned int)dev, (double)inode));
+          (int)remotepid, from_port, (unsigned int)dev, (double)inode));
   }
 
   return True;
 }
 
 /****************************************************************************
Process an oplock break directly.
Set up an oplock break message.
 ****************************************************************************/
 
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
+static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
+{
+  memset(outbuf,'\0',smb_size);
+  set_message(outbuf,8,0,True);
+
+  SCVAL(outbuf,smb_com,SMBlockingX);
+  SSVAL(outbuf,smb_tid,fsp->conn->cnum);
+  SSVAL(outbuf,smb_pid,0xFFFF);
+  SSVAL(outbuf,smb_uid,0);
+  SSVAL(outbuf,smb_mid,0xFFFF);
+  SCVAL(outbuf,smb_vwv0,0xFF);
+  SSVAL(outbuf,smb_vwv2,fsp->fnum);
+  SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
+  SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
+}
+
+/****************************************************************************
+ Function to do the waiting before sending a local break.
+****************************************************************************/
+
+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();
+
+    GetTimeOfDay(&cur_tv);
+
+    wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
+                ((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
+
+    if(wait_left > 0) {
+      wait_left = MIN(wait_left, 1000);
+      sys_usleep(wait_left * 1000);
+    }
+  }
+}
+
+/****************************************************************************
+ Ensure that we have a valid oplock.
+****************************************************************************/
+
+static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
 {
-  extern struct current_user current_user;
-  extern int Client;
-  char *inbuf = NULL;
-  char *outbuf = NULL;
   files_struct *fsp = NULL;
-  time_t start_time;
-  BOOL shutdown_server = False;
-  connection_struct *saved_conn;
-  int saved_vuid;
-  pstring saved_dir; 
-  int break_counter = OPLOCK_BREAK_RESENDS;
 
   if( DEBUGLVL( 3 ) )
   {
-    dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
-    dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
+    dbgtext( "initial_break_processing: called for dev = %x, inode = %.0f tv_sec = %x, tv_usec = %x.\n",
+      (unsigned int)dev, (double)inode, tval ? (int)tval->tv_sec : 0,
+      tval ? (int)tval->tv_usec : 0);
+    dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
+              exclusive_oplocks_open, level_II_oplocks_open );
   }
 
   /* We need to search the file open table for the
@@ -594,13 +715,13 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
   if(fsp == NULL)
   {
     /* The file could have been closed in the meantime - return success. */
-    if( DEBUGLVL( 0 ) )
+    if( DEBUGLVL( 3 ) )
     {
-      dbgtext( "oplock_break: cannot find open file with " );
+      dbgtext( "initial_break_processing: cannot find open file with " );
       dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
       dbgtext( "allowing break to succeed.\n" );
     }
-    return True;
+    return NULL;
   }
 
   /* Ensure we have an oplock on the file */
@@ -612,18 +733,130 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
      as we may have just freed it.
    */
 
-  if(!fsp->granted_oplock)
+  if(fsp->oplock_type == NO_OPLOCK)
   {
-    if( DEBUGLVL( 0 ) )
+    if( DEBUGLVL( 3 ) )
     {
-      dbgtext( "oplock_break: file %s ", fsp->fsp_name );
+      dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
       dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
       dbgtext( "Allowing break to succeed regardless.\n" );
     }
-    return True;
+    return NULL;
   }
 
-  /* mark the oplock break as sent - we don't want to send twice! */
+  return fsp;
+}
+
+/****************************************************************************
+ Process a level II oplock break directly.
+****************************************************************************/
+
+BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
+{
+  extern int Client;
+  extern uint32 global_client_caps;
+  char outbuf[128];
+  BOOL got_lock = False;
+  SMB_DEV_T dev = fsp->fd_ptr->dev;
+  SMB_INO_T inode = fsp->fd_ptr->inode;
+
+  /*
+   * We can have a level II oplock even if the client is not
+   * level II oplock aware. In this case just remove the
+   * flags and don't send the break-to-none message to
+   * the client.
+   */
+
+  if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
+    /*
+     * If we are sending an oplock break due to an SMB sent
+     * by our own client we ensure that we wait at leat
+     * lp_oplock_break_wait_time() milliseconds before sending
+     * the packet. Sending the packet sooner can break Win9x
+     * and has reported to cause problems on NT. JRA.
+     */
+
+    wait_before_sending_break(local_request);
+
+    /* Prepare the SMBlockingX message. */
+
+    prepare_break_message( outbuf, fsp, False);
+    send_smb(Client, outbuf);
+  }
+
+  /*
+   * Now we must update the shared memory structure to tell
+   * everyone else we no longer have a level II oplock on 
+   * this open file. If local_request is true then token is
+   * the existing lock on the shared memory area.
+   */
+
+  if(!local_request && lock_share_entry(fsp->conn, dev, inode) == False) {
+      DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
+  } else {
+    got_lock = True;
+  }
+
+  if(remove_share_oplock(fsp)==False) {
+    DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
+  }
+
+  if (!local_request && got_lock)
+    unlock_share_entry(fsp->conn, dev, inode);
+
+  fsp->oplock_type = NO_OPLOCK;
+  level_II_oplocks_open--;
+
+  if(level_II_oplocks_open < 0)
+  {
+    DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
+              level_II_oplocks_open));
+    abort();
+  }
+
+  if( DEBUGLVL( 3 ) )
+  {
+    dbgtext( "oplock_break_level2: returning success for " );
+    dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+    dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
+  }
+
+  return True;
+}
+
+/****************************************************************************
+ Process an oplock break directly.
+****************************************************************************/
+
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local_request)
+{
+  extern uint32 global_client_caps;
+  extern struct current_user current_user;
+  extern int Client;
+  char *inbuf = NULL;
+  char *outbuf = NULL;
+  files_struct *fsp = NULL;
+  time_t start_time;
+  BOOL shutdown_server = False;
+  BOOL oplock_timeout = False;
+  connection_struct *saved_conn;
+  int saved_vuid;
+  pstring saved_dir; 
+  int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
+  pstring file_name;
+  BOOL using_levelII;
+
+  if((fsp = initial_break_processing(dev, inode, tval)) == NULL)
+    return True;
+
+  /*
+   * Deal with a level II oplock going break to none separately.
+   */
+
+  if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+    return oplock_break_level2(fsp, local_request, -1);
+
+  /* Mark the oplock break as sent - we don't want to send twice! */
   if (fsp->sent_oplock_break)
   {
     if( DEBUGLVL( 0 ) )
@@ -641,6 +874,11 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
     return False;
   }
 
+  if(global_oplock_break) {
+    DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
+    abort();
+  }
+
   /* Now comes the horrid part. We must send an oplock break to the client,
      and then process incoming messages until we get a close or oplock release.
      At this point we know we need a new inbuf/outbuf buffer pair.
@@ -662,25 +900,30 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
     return False;
   }
 
+  /*
+   * If we are sending an oplock break due to an SMB sent
+   * by our own client we ensure that we wait at leat
+   * lp_oplock_break_wait_time() milliseconds before sending
+   * the packet. Sending the packet sooner can break Win9x
+   * and has reported to cause problems on NT. JRA.
+   */
+
+  wait_before_sending_break(local_request);
+
   /* Prepare the SMBlockingX message. */
-  memset(outbuf, 0, smb_size);
-  set_message(outbuf,8,0,True);
 
-  SCVAL(outbuf,smb_com,SMBlockingX);
-  SSVAL(outbuf,smb_tid,fsp->conn->cnum);
-  SSVAL(outbuf,smb_pid,0xFFFF);
-  SSVAL(outbuf,smb_uid,0);
-  SSVAL(outbuf,smb_mid,0xFFFF);
-  SCVAL(outbuf,smb_vwv0,0xFF);
-  SSVAL(outbuf,smb_vwv2,fsp->fnum);
-  SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
-  /* Change this when we have level II oplocks. */
-  SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
-  send_smb(Client, outbuf);
+  if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && !lp_kernel_oplocks() && lp_level2_oplocks(SNUM(fsp->conn))) {
+         using_levelII = True;
+  } else {
+         using_levelII = False;
+  }
+
+  prepare_break_message( outbuf, fsp, using_levelII);
+  /* Remember if we just sent a break to level II on this file. */
+  fsp->sent_oplock_break = using_levelII?
+         LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
 
-  /* Remember we just sent an oplock break on this file. */
-  fsp->sent_oplock_break = True;
+  send_smb(Client, outbuf);
 
   /* We need this in case a readraw crosses on the wire. */
   global_oplock_break = True;
@@ -703,40 +946,39 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
   /* Save the chain fnum. */
   file_chain_save();
 
-  while(OPEN_FSP(fsp) && fsp->granted_oplock)
-  {
-    if(receive_smb(Client,inbuf,
-                  (OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000) == False)
-    {
+  /*
+   * From Charles Hoch <hoch@exemplary.com>. If the break processing
+   * code closes the file (as it often does), then the fsp pointer here
+   * points to free()'d memory. We *must* revalidate fsp each time
+   * around the loop.
+   */
 
-           /* Isaac suggestd that if a MS client doesn't respond to a
-              oplock break request then we might try resending
-              it. Certainly it's no worse than just dropping the
-              socket! */
-           if (smb_read_error == READ_TIMEOUT && break_counter--) {
-                   DEBUG(2, ( "oplock_break resend\n" ) );
-                   send_smb(Client, outbuf);
-                   continue;
-           }
+  pstrcpy(file_name, fsp->fsp_name);
 
+  while((fsp = initial_break_processing(dev, inode, tval)) &&
+        OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+  {
+    if(receive_smb(Client,inbuf, timeout) == False)
+    {
       /*
        * Die if we got an error.
        */
 
-      if (smb_read_error == READ_EOF)
+      if (smb_read_error == READ_EOF) {
         DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
-      if (smb_read_error == READ_ERROR)
+        shutdown_server = True;
+      } else if (smb_read_error == READ_ERROR) {
         DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
-
-      if (smb_read_error == READ_TIMEOUT)
+        shutdown_server = True;
+      } else if (smb_read_error == READ_TIMEOUT) {
         DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
                      OPLOCK_BREAK_TIMEOUT ) );
+        oplock_timeout = True;
+      }
 
-      DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
+      DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
       DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
 
-      shutdown_server = True;
       break;
     }
 
@@ -758,13 +1000,13 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
     {
       if( DEBUGLVL( 0 ) )
-        {
+      {
         dbgtext( "oplock_break: no break received from client " );
         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
         dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
-        }
-      shutdown_server = True;
+      }
+      oplock_timeout = True;
       break;
     }
   }
@@ -796,7 +1038,21 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
     global_oplock_break = False;
 
   /*
-   * If the client did not respond we must die.
+   * If the client timed out then clear the oplock (or go to level II)
+   * and continue. This seems to be what NT does and is better than dropping
+   * the connection.
+   */
+
+  if(oplock_timeout && (fsp = initial_break_processing(dev, inode, tval)) &&
+        OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+  {
+    DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
+    remove_oplock(fsp);
+    global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
+  }
+
+  /*
+   * If the client had an error we must die.
    */
 
   if(shutdown_server)
@@ -808,27 +1064,19 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
     exit_server("oplock break failure");
   }
 
-  if(OPEN_FSP(fsp))
-  {
-    /* The lockingX reply will have removed the oplock flag 
-       from the sharemode. */
-    release_file_oplock(fsp);
-  }
-
   /* Santity check - remove this later. JRA */
-  if(global_oplocks_open < 0)
+  if(exclusive_oplocks_open < 0)
   {
-    DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
-              global_oplocks_open));
-    exit_server("oplock_break: global_oplocks_open < 0");
+    DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n",
+              exclusive_oplocks_open));
+    abort();
   }
 
-
   if( DEBUGLVL( 3 ) )
   {
     dbgtext( "oplock_break: returning success for " );
     dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
-    dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
+    dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
   }
 
   return True;
@@ -844,9 +1092,11 @@ BOOL request_oplock_break(share_mode_entry *share_entry,
 {
   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
   struct sockaddr_in addr_out;
-  int pid = getpid();
+  pid_t pid = getpid();
   time_t start_time;
   int time_left;
+  long usec;
+  time_t sec;
 
   if(pid == share_entry->pid)
   {
@@ -854,36 +1104,34 @@ BOOL request_oplock_break(share_mode_entry *share_entry,
     if(share_entry->op_port != global_oplock_port)
     {
       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", pid, share_entry->op_port, global_oplock_port));
+should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
       return False;
     }
 
     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
 
     /* Call oplock break direct. */
-    return oplock_break(dev, inode, &share_entry->time);
+    return oplock_break(dev, inode, &share_entry->time, True);
   }
 
   /* We need to send a OPLOCK_BREAK_CMD message to the
      port in the share mode entry. */
 
-  SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
-  SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
-  SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
-  SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
-  SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
-  /*
-   * WARNING - beware of SMB_INO_T <> 4 bytes.
-   */
-#ifdef LARGE_SMB_INO_T
-  SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
-  SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
-#else /* LARGE_SMB_INO_T */
-  SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
-#endif /* LARGE_SMB_INO_T */
+  if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+    SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,LEVEL_II_OPLOCK_BREAK_CMD);
+  } else {
+    SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
+  }
+  memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
+  sec = (time_t)share_entry->time.tv_sec;
+  memcpy(op_break_msg+OPLOCK_BREAK_SEC_OFFSET,(char *)&sec,sizeof(sec));
+  usec = (long)share_entry->time.tv_usec;
+  memcpy(op_break_msg+OPLOCK_BREAK_USEC_OFFSET,(char *)&usec,sizeof(usec));
+  memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
+  memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
 
   /* set the address and port */
-  ZERO_STRUCT(addr_out);
+  memset((char *)&addr_out,'\0',sizeof(addr_out));
   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   addr_out.sin_port = htons( share_entry->op_port );
   addr_out.sin_family = AF_INET;
@@ -891,8 +1139,11 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
   if( DEBUGLVL( 3 ) )
   {
     dbgtext( "request_oplock_break: sending a oplock break message to " );
-    dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
-    dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+    dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
+    dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+            (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+            (int)share_entry->time.tv_usec );
+
   }
 
   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
@@ -901,14 +1152,26 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
     if( DEBUGLVL( 0 ) )
     {
       dbgtext( "request_oplock_break: failed when sending a oplock " );
-      dbgtext( "break message to pid %d ", share_entry->pid );
+      dbgtext( "break message to pid %d ", (int)share_entry->pid );
       dbgtext( "on port %d ", share_entry->op_port );
-      dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+      dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+          (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+          (int)share_entry->time.tv_usec );
       dbgtext( "Error was %s\n", strerror(errno) );
     }
     return False;
   }
 
+  /*
+   * If we just sent a message to a level II oplock share entry then
+   * we are done and may return.
+   */
+
+  if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+    DEBUG(3,("request_oplock_break: sent break message to level II entry.\n"));
+    return True;
+  }
+
   /*
    * Now we must await the oplock broken message coming back
    * from the target smbd process. Timeout if it fails to
@@ -929,10 +1192,8 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
 
     FD_ZERO(&fds);
     FD_SET(oplock_sock,&fds);
-#if defined(HAVE_KERNEL_OPLOCKS)
-    if(lp_kernel_oplocks())
+    if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
       FD_SET(oplock_pipe_read,&fds);
-#endif /* HAVE_KERNEL_OPLOCKS */
 
     if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
                time_left ? time_left * 1000 : 1) == False)
@@ -942,9 +1203,12 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
         if( DEBUGLVL( 0 ) )
         {
           dbgtext( "request_oplock_break: no response received to oplock " );
-          dbgtext( "break request to pid %d ", share_entry->pid );
+          dbgtext( "break request to pid %d ", (int)share_entry->pid );
           dbgtext( "on port %d ", share_entry->op_port );
           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+          dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+             (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+             (int)share_entry->time.tv_usec );
         }
 
         /*
@@ -960,9 +1224,11 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
         if( DEBUGLVL( 0 ) )
         {
           dbgtext( "request_oplock_break: error in response received " );
-          dbgtext( "to oplock break request to pid %d ", share_entry->pid );
+          dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
           dbgtext( "on port %d ", share_entry->op_port );
-          dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
+          dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
+               (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+               (int)share_entry->time.tv_usec );
           dbgtext( "Error was (%s).\n", strerror(errno) );
         }
       return False;
@@ -1036,16 +1302,17 @@ should be %d\n", pid, share_entry->op_port, global_oplock_port));
   Used as a last ditch attempt to free a space in the 
   file table when we have run out.
 ****************************************************************************/
+
 BOOL attempt_close_oplocked_file(files_struct *fsp)
 {
 
   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
 
-  if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
+  if (fsp->open && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
 
     /* Try and break the oplock. */
     file_fd_struct *fd_ptr = fsp->fd_ptr;
-    if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
+    if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time, True)) {
       if(!fsp->open) /* Did the oplock break close the file ? */
         return True;
     }
index a4229242b3d19f0bce3ca338c8275bd2042fbb3a..e75f304c47510e0a3b212902226d33daa01ec5ea 100644 (file)
@@ -25,7 +25,7 @@ extern int DEBUGLEVEL;
 extern int Protocol;
 
 /* users from session setup */
-static pstring session_users="";
+static pstring session_users = "";
 
 extern pstring scope;
 extern pstring global_myname;
@@ -37,21 +37,23 @@ add a name to the session users list
 ****************************************************************************/
 void add_session_user(char *user)
 {
-  fstring suser;
-  StrnCpy(suser,user,sizeof(suser)-1);
+       fstring suser;
+       StrnCpy(suser, user, sizeof(suser) - 1);
 
-  if (!Get_Pwnam(suser,True)) return;
+       if (!Get_Pwnam(suser, True))
+               return;
 
-  if (suser && *suser && !in_list(suser,session_users,False))
-    {
-      if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
-       DEBUG(1,("Too many session users??\n"));
-      else
+       if (suser && *suser && !in_list(suser, session_users, False))
        {
-         pstrcat(session_users," ");
-         pstrcat(session_users,suser);
+               if (strlen(suser) + strlen(session_users) + 2 >=
+                   sizeof(pstring))
+                       DEBUG(1, ("Too many session users??\n"));
+               else
+               {
+                       pstrcat(session_users, " ");
+                       pstrcat(session_users, suser);
+               }
        }
-    }
 }
 
 /****************************************************************************
@@ -60,10 +62,9 @@ database or the encrypted SMB password database
 return True if the password is correct, False otherwise
 ****************************************************************************/
 BOOL password_ok(const char *orig_user, const char *domain,
-                               const char *smb_apasswd, int smb_apasslen,
-                               const char *smb_ntpasswd, int smb_ntpasslen,
-                               struct passwd *pwd,
-                               NET_USER_INFO_3 *info3)
+                const char *smb_apasswd, int smb_apasslen,
+                const char *smb_ntpasswd, int smb_ntpasslen,
+                struct passwd *pwd, NET_USER_INFO_3 * info3)
 {
        uchar last_chal[8];
        BOOL cleartext = smb_apasslen != 24 && smb_ntpasslen == 0;
@@ -71,7 +72,7 @@ BOOL password_ok(const char *orig_user, const char *domain,
 
        if (info3 == NULL)
        {
-               DEBUG(0,("password_ok: no NET_USER_INFO_3 parameter!\n"));
+               DEBUG(0, ("password_ok: no NET_USER_INFO_3 parameter!\n"));
                return False;
        }
 
@@ -83,7 +84,7 @@ BOOL password_ok(const char *orig_user, const char *domain,
            (lp_encrypted_passwords() && smb_apasslen == 0 &&
             lp_null_passwords()))
        {
-               DEBUG(10,("password_ok: check SMB auth\n"));
+               DEBUG(10, ("password_ok: check SMB auth\n"));
 
                /* check security = user / domain */
                if ((!cleartext) && last_challenge(last_chal))
@@ -97,21 +98,22 @@ BOOL password_ok(const char *orig_user, const char *domain,
                                          smb_ntpasswd, smb_ntpasslen,
                                          info3) == 0x0)
                {
-                       DEBUG(10,("password_ok: domain auth succeeded\n"));
+                       DEBUG(10, ("password_ok: domain auth succeeded\n"));
                        return True;
                }
        }
 
-       DEBUG(10,("password_ok: check Unix auth\n"));
+       DEBUG(10, ("password_ok: check Unix auth\n"));
        /*
         * unix password check
         */
 
        if (!lp_update_encrypted())
        {
-               if (pass_check(orig_user, smb_apasswd, smb_apasslen, pwd, NULL))
+               if (pass_check
+                   (orig_user, smb_apasswd, smb_apasslen, pwd, NULL))
                {
-                       DEBUG(10,("password_ok: Unix auth succeeded\n"));
+                       DEBUG(10, ("password_ok: Unix auth succeeded\n"));
                        return True;
                }
        }
@@ -119,126 +121,171 @@ BOOL password_ok(const char *orig_user, const char *domain,
 }
 
 
-
-
 /****************************************************************************
 validate a group username entry. Return the username or NULL
 ****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum,
-                               NET_USER_INFO_3 *info3)
+static char *validate_group(char *group, char *password, int pwlen, int snum,
+               NET_USER_INFO_3 *info3)
 {
-#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT)
-  {
-    char *host, *user, *domain;
-    setnetgrent(group);
-    while (getnetgrent(&host, &user, &domain)) {
-      if (user) {
-       if (user_ok(user, snum) && 
-           password_ok(user,NULL,password,pwlen,NULL,0,NULL,info3))
+#ifdef HAVE_NETGROUP
+       char *host, *user, *domain;
+#endif
+#ifdef HAVE_GETGRENT
+       struct group *gptr;
+       pstring member_list;
+       char *member;
+       size_t copied_len = 0;
+       int i;
+#endif
+
+#ifdef HAVE_NETGROUP
+
+       setnetgrent(group);
+       while (getnetgrent(&host, &user, &domain))
        {
-         endnetgrent();
-         return(user);
+               if (user)
+               {
+                       if (user_ok(user, snum) &&
+                           password_ok(user, NULL, password, pwlen,
+                                       NULL, 0, NULL, info3))
+                       {
+                               endnetgrent();
+                               return (user);
+                       }
+               }
        }
-      }
-    }
-    endnetgrent();
-  }
+       endnetgrent();
 #endif
-  
-#ifdef HAVE_GETGRNAM 
-  {
-    struct group *gptr = (struct group *)getgrnam(group);
-    char **member;
-    if (gptr)
-      {
-       member = gptr->gr_mem;
-       while (member && *member)
-         {
-           static fstring name;
-           fstrcpy(name,*member);
-           if (user_ok(name,snum) &&
-       password_ok(name,NULL,password,pwlen,NULL,0,NULL, info3))
-             return(&name[0]);
-           member++;
-         }
-#ifdef GROUP_CHECK_PWENT
+
+#ifdef HAVE_GETGRENT
+
+       setgrent();
+       while ((gptr = (struct group *)getgrent()))
+       {
+               if (strequal(gptr->gr_name, group))
+                       break;
+       }
+
+       /*
+        * As user_ok can recurse doing a getgrent(), we must
+        * copy the member list into a pstring on the stack before
+        * use. Bug pointed out by leon@eatworms.swmed.edu.
+        */
+
+       if (gptr == NULL)
+       {
+               endgrent();
+               return NULL;
+       }
+
+       *member_list = '\0';
+       member = member_list;
+
+       for (i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++)
+       {
+               size_t member_len = strlen(gptr->gr_mem[i]) + 1;
+               if (copied_len + member_len < sizeof(pstring))
+               {
+
+                       DEBUG(10,
+                             ("validate_group: = gr_mem = %s\n",
+                              gptr->gr_mem[i]));
+
+                       safe_strcpy(member, gptr->gr_mem[i],
+                                   sizeof(pstring) - copied_len - 1);
+                       copied_len += member_len;
+                       member += copied_len;
+               }
+               else
+               {
+                       *member = '\0';
+               }
+       }
+
+       endgrent();
+
+       member = member_list;
+       while (*member)
        {
-         struct passwd *pwd;
-         static fstring tm;
-         
-         setpwent ();
-         while (pwd = getpwent ()) {
-           if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
-             /* This Entry have PASSWORD and same GID then check pwd */
-             if (password_ok(NULL, NULL, password, pwlen, NULL, 0, pwd, user_sess_key)) {
-               fstrcpy(tm, pwd->pw_name);
-               endpwent ();
-               return tm;
-             }
-           }
-         }
-         endpwent ();
+               static fstring name;
+               fstrcpy(name, member);
+               if (user_ok(name, snum) &&
+                   password_ok(name, NULL, password, pwlen,
+                               NULL, 0, NULL, info3))
+               {
+                       endgrent();
+                       return (&name[0]);
+               }
+
+               DEBUG(10, ("validate_group = member = %s\n", member));
+
+               member += strlen(member) + 1;
        }
-#endif /* GROUP_CHECK_PWENT */
-      }
-  }      
 #endif
-  return(NULL);
+       return (NULL);
 }
 
 
-
 /****************************************************************************
 check for authority to login to a service with a given username/password
 ****************************************************************************/
 BOOL authorise_login(int snum, char *user, char *domain,
-                               char *password, int pwlen, 
-                               BOOL *guest,BOOL *force,
-                               const vuser_key *key)
+                    char *password, int pwlen,
+                    BOOL *guest, BOOL *force, const vuser_key * key)
 {
        BOOL ok = False;
 
-       DEBUG(0,("authorise_login: TODO. split function, it's 6 levels!\n"));
+       DEBUG(0, ("authorise_login: TODO. split function, it's 6 levels!\n"));
        *guest = False;
 
 #if DEBUG_PASSWORD
-       DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
+       DEBUG(100,
+             ("checking authorisation on user=%s pass=%s\n", user,
+              password));
 #endif
 
-  /* there are several possibilities:
-     1) login as the given user with given password
-     2) login as a previously registered username with the given password
-     3) login as a session list username with the given password
-     4) login as a previously validated user/password pair
-     5) login as the "user =" user with given password
-     6) login as the "user =" user with no password (guest connection)
-     7) login as guest user with no password
+       /* there are several possibilities:
+          1) login as the given user with given password
+          2) login as a previously registered username with the given password
+          3) login as a session list username with the given password
+          4) login as a previously validated user/password pair
+          5) login as the "user =" user with given password
+          6) login as the "user =" user with no password (guest connection)
+          7) login as guest user with no password
 
-     if the service is guest_only then steps 1 to 5 are skipped
-  */
+          if the service is guest_only then steps 1 to 5 are skipped
+        */
 
-       if (GUEST_ONLY(snum)) *force = True;
+       if (GUEST_ONLY(snum))
+               *force = True;
 
        if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
        {
                user_struct *vuser = get_valid_user_struct(key);
 
                /* check the given username and password */
-               if (!ok && (*user) && user_ok(user,snum))
+               if (!ok && (*user) && user_ok(user, snum))
                {
-                       ok = password_ok(user,domain, password, pwlen, NULL, 0, NULL, &vuser->usr);
-                       if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
+                       ok =
+                               password_ok(user, domain, password, pwlen,
+                                           NULL, 0, NULL, &vuser->usr);
+                       if (ok)
+                               DEBUG(3,
+                                     ("ACCEPTED: given username password ok\n"));
                }
 
                /* check for a previously registered guest username */
                if (!ok && (vuser != 0) && vuser->guest)
-               {         
-                       if (user_ok(vuser->name,snum) &&
-                           password_ok(vuser->name, domain, password, pwlen, NULL, 0, NULL, &vuser->usr))
+               {
+                       if (user_ok(vuser->name, snum) &&
+                           password_ok(vuser->name, domain, password, pwlen,
+                                       NULL, 0, NULL, &vuser->usr))
                        {
                                fstrcpy(user, vuser->name);
                                vuser->guest = False;
-                               DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
+                               DEBUG(3,
+                                     ("ACCEPTED: given password with registered user %s\n",
+                                      user));
                                ok = True;
                        }
                }
@@ -255,41 +302,44 @@ BOOL authorise_login(int snum, char *user, char *domain,
                                return False;
                        }
 
-                       for (auser=strtok(user_list,LIST_SEP); 
-                       !ok && auser; 
-                       auser = strtok(NULL,LIST_SEP))
+                       for (auser = strtok(user_list, LIST_SEP);
+                            !ok && auser; auser = strtok(NULL, LIST_SEP))
                        {
                                fstring user2;
-                               fstrcpy(user2,auser);
-                               if (!user_ok(user2,snum)) continue;
+                               fstrcpy(user2, auser);
+                               if (!user_ok(user2, snum))
+                                       continue;
 
-                               if (password_ok(user2, domain, password, pwlen, NULL, 0, NULL,
-                               &vuser->usr))
+                               if (password_ok
+                                   (user2, domain, password, pwlen, NULL, 0,
+                                    NULL, &vuser->usr))
                                {
                                        ok = True;
-                                       fstrcpy(user,user2);
-                                       DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
+                                       fstrcpy(user, user2);
+                                       DEBUG(3,
+                                             ("ACCEPTED: session list username and given password ok\n"));
                                }
                        }
                        free(user_list);
                }
 
                /* check for a previously validated username/password pair */
-               if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
-                       (vuser != 0) && !vuser->guest &&
-                       user_ok(vuser->name,snum))
+               if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE)
+                   && (vuser != 0) && !vuser->guest
+                   && user_ok(vuser->name, snum))
                {
-                       fstrcpy(user,vuser->name);
+                       fstrcpy(user, vuser->name);
                        *guest = False;
-                       DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
+                       DEBUG(3,
+                             ("ACCEPTED: validated uid ok as non-guest\n"));
                        ok = True;
                }
 
                /* check for a rhosts entry */
-               if (!ok && user_ok(user,snum) && check_hosts_equiv(user))
+               if (!ok && user_ok(user, snum) && check_hosts_equiv(user))
                {
                        ok = True;
-                       DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
+                       DEBUG(3, ("ACCEPTED: hosts equiv or rhosts entry\n"));
                }
 
                /* check the user= fields and the given password */
@@ -297,39 +347,46 @@ BOOL authorise_login(int snum, char *user, char *domain,
                {
                        char *auser;
                        pstring user_list;
-                       StrnCpy(user_list,lp_username(snum),sizeof(pstring));
+                       StrnCpy(user_list, lp_username(snum),
+                               sizeof(pstring));
 
-                       string_sub(user_list,"%S",lp_servicename(snum));
+                       pstring_sub(user_list, "%S", lp_servicename(snum));
 
-                       for (auser=strtok(user_list,LIST_SEP);
-                               auser && !ok;
-                               auser = strtok(NULL,LIST_SEP))
+                       for (auser = strtok(user_list, LIST_SEP);
+                            auser && !ok; auser = strtok(NULL, LIST_SEP))
                        {
                                if (*auser == '@')
                                {
-                                       auser = validate_group(auser+1,password,pwlen,snum, &vuser->usr);
+                                       auser =
+                                               validate_group(auser + 1,
+                                                              password,
+                                                              pwlen, snum,
+                                                              &vuser->usr);
                                        if (auser)
                                        {
                                                ok = True;
-                                               fstrcpy(user,auser);
-                                               DEBUG(3,("ACCEPTED: group username and given password ok\n"));
+                                               fstrcpy(user, auser);
+                                               DEBUG(3,
+                                                     ("ACCEPTED: group username and given password ok\n"));
                                        }
                                }
                                else
                                {
                                        fstring user2;
-                                       fstrcpy(user2,auser);
-                                       if (user_ok(user2,snum) && 
-                                       password_ok(user2,domain,password,pwlen,NULL, 0,
-                                       NULL, &vuser->usr))
+                                       fstrcpy(user2, auser);
+                                       if (user_ok(user2, snum) &&
+                                           password_ok(user2, domain,
+                                                       password, pwlen, NULL,
+                                                       0, NULL, &vuser->usr))
                                        {
                                                ok = True;
-                                               fstrcpy(user,user2);
-                                               DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
+                                               fstrcpy(user, user2);
+                                               DEBUG(3,
+                                                     ("ACCEPTED: user list username and given password ok\n"));
                                        }
                                }
                        }
-               }      
+               }
 
                if (vuser != NULL)
                {
@@ -337,137 +394,156 @@ BOOL authorise_login(int snum, char *user, char *domain,
                }
                vuid_free_user_struct(vuser);
 
-       } /* not guest only */
+       }                       /* not guest only */
 
        /* check for a normal guest connection */
        if (!ok && GUEST_OK(snum))
        {
                fstring guestname;
-               StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
-               if (Get_Pwnam(guestname,True))
+               StrnCpy(guestname, lp_guestaccount(snum),
+                       sizeof(guestname) - 1);
+               if (Get_Pwnam(guestname, True))
                {
-                       fstrcpy(user,guestname);
+                       fstrcpy(user, guestname);
                        ok = True;
-                       DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+                       DEBUG(3, ("ACCEPTED: guest account and guest ok\n"));
                }
                else
-                       DEBUG(0,("Invalid guest account %s??\n",guestname));
+                       DEBUG(0, ("Invalid guest account %s??\n", guestname));
                *guest = True;
                *force = True;
        }
 
-       if (ok && !user_ok(user,snum))
+       if (ok && !user_ok(user, snum))
        {
-               DEBUG(0,("rejected invalid user %s\n",user));
+               DEBUG(0, ("rejected invalid user %s\n", user));
                ok = False;
        }
 
-       return(ok);
+       return (ok);
 }
 
-
-/****************************************************************************
-read the a hosts.equiv or .rhosts file and check if it
-allows this user from this machine
-****************************************************************************/
-static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
+BOOL check_user_equiv_line(char *buf, const char *user, const char *remote,
+                          BOOL *plus_allowed, BOOL *ret)
 {
-  pstring buf;
-  int plus_allowed = 1;
-  char *file_host;
-  char *file_user;
-  FILE *fp = sys_fopen(equiv_file, "r");
-  DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
-  if (! fp) return False;
-  while(fgets(buf, sizeof(buf), fp)) 
-  {
-    trim_string(buf," "," ");
-
-    if (buf[0] != '#' && buf[0] != '\n') 
-    {
-      BOOL is_group = False;
-      int plus = 1;
-      char *bp = buf;
-      if (strcmp(buf, "NO_PLUS\n") == 0)
-      {
-       DEBUG(6, ("check_user_equiv NO_PLUS\n"));
-       plus_allowed = 0;
-      }
-      else {
-       if (buf[0] == '+') 
+       BOOL is_group = False;
+       int plus = 1;
+       char *bp = buf;
+       char *file_host;
+       char *file_user;
+
+       if (strcmp(buf, "NO_PLUS\n") == 0)
        {
-         bp++;
-         if (*bp == '\n' && plus_allowed) 
-         {
-           /* a bare plus means everbody allowed */
-           DEBUG(6, ("check_user_equiv everybody allowed\n"));
-           fclose(fp);
-           return True;
-         }
+               DEBUG(6, ("check_user_equiv NO_PLUS\n"));
+               (*plus_allowed) = 0;
+               return False;
+       }
+
+       if (buf[0] == '+')
+       {
+               bp++;
+               if (*bp == '\n' && (*plus_allowed))
+               {
+                       /* a bare plus means everbody allowed */
+                       DEBUG(6, ("check_user_equiv everybody allowed\n"));
+                       *ret = True;
+                       return True;
+               }
        }
        else if (buf[0] == '-')
        {
-         bp++;
-         plus = 0;
+               bp++;
+               plus = 0;
        }
-       if (*bp == '@') 
+       if (*bp == '@')
        {
-         is_group = True;
-         bp++;
+               is_group = True;
+               bp++;
        }
+
        file_host = strtok(bp, " \t\n");
        file_user = strtok(NULL, " \t\n");
-       DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", 
-                 file_user ? file_user : "(null)" ));
-       if (file_host && *file_host) 
-       {
-         BOOL host_ok = False;
+       DEBUG(7, ("check_user_equiv %s %s\n",
+                 file_host ? file_host : "(null)",
+                 file_user ? file_user : "(null)"));
 
+       if (file_host && *file_host)
+       {
+               BOOL host_ok = False;
 #if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN)
-         if (is_group)
-           {
-             static char *mydomain = NULL;
-             if (!mydomain)
-               yp_get_default_domain(&mydomain);
-             if (mydomain && innetgr(file_host,remote,user,mydomain))
-               host_ok = True;
-           }
+               if (is_group)
+               {
+                       static char *mydomain = NULL;
+                       if (!mydomain)
+                               yp_get_default_domain(&mydomain);
+                       if (mydomain && innetgr(file_host, remote, user,
+                                               mydomain)) host_ok = True;
+               }
 #else
-         if (is_group)
-           {
-             DEBUG(1,("Netgroups not configured\n"));
-             continue;
-           }
+               if (is_group)
+               {
+                       DEBUG(1, ("Netgroups not configured\n"));
+                       return False;
+               }
 #endif
+               /* is it this host */
+               /* the fact that remote has come from a call of
+                * gethostbyaddr means that it may have the fully
+                * qualified domain name so we could look up the
+                * file version to get it into a canonical form,
+                * but I would rather just type it in full in the
+                * equiv file */
+               if (!host_ok && !is_group && strequal(remote, file_host))
+               {
+                       host_ok = True;
+               }
+               if (!host_ok)
+               {
+                       return False;
+               }
+               /* is it this user */
+               if (file_user == 0 || strequal(user, file_user))
+               {
+                       DEBUG(5, ("check_user_equiv matched %s%s %s\n",
+                                 (plus ? "+" : "-"), file_host,
+                                 (file_user ? file_user : "")));
+                       *ret = (plus ? True : False);
+                       return True;
+               }
+       }
+
+       return False;
+}
+
+/****************************************************************************
+read the a hosts.equiv or .rhosts file and check if it
+allows this user from this machine
+****************************************************************************/
+static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
+{
+       pstring buf;
+       int plus_allowed = 1;
+       FILE *fp = sys_fopen(equiv_file, "r");
+       DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
+       if (!fp)
+               return False;
+       while (fgets(buf, sizeof(buf), fp))
+       {
+               trim_string(buf, " ", " ");
 
-         /* is it this host */
-         /* the fact that remote has come from a call of gethostbyaddr
-          * means that it may have the fully qualified domain name
-          * so we could look up the file version to get it into
-          * a canonical form, but I would rather just type it
-          * in full in the equiv file
-          */
-         if (!host_ok && !is_group && strequal(remote, file_host))
-           host_ok = True;
-
-         if (!host_ok)
-           continue;
-
-         /* is it this user */
-         if (file_user == 0 || strequal(user, file_user)) 
-           {
-             fclose(fp);
-             DEBUG(5, ("check_user_equiv matched %s%s %s\n",
-                       (plus ? "+" : "-"), file_host,
-                       (file_user ? file_user : "")));
-             return (plus ? True : False);
-           }
+               if (buf[0] != '#' && buf[0] != '\n')
+               {
+                       BOOL ret;
+                       if (check_user_equiv_line(buf, user, remote,
+                                                 &plus_allowed, &ret))
+                       {
+                               fclose(fp);
+                               return ret;
+                       }
+               }
        }
-      }
-    }
-  }
-  fclose(fp);
-  return False;
+       fclose(fp);
+       return False;
 }
 
 
@@ -476,32 +552,34 @@ check for a possible hosts equiv or rhosts entry for the user
 ****************************************************************************/
 BOOL check_hosts_equiv(char *user)
 {
-  char *fname = NULL;
-  pstring rhostsfile;
-  const struct passwd *pass = Get_Pwnam(user,True);
-
-  if (!pass) 
-    return False;
-
-  fname = lp_hosts_equiv();
-
-  /* note: don't allow hosts.equiv on root */
-  if (fname && *fname && (pass->pw_uid != 0)) {
-         if (check_user_equiv(user,client_connection_name(),fname))
-                 return(True);
-  }
-  
-  if (lp_use_rhosts())
-    {
-      char *home = get_unixhome_dir(user);
-      if (home) {
-             slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
-             if (check_user_equiv(user,client_connection_name(),rhostsfile))
-                     return(True);
-      }
-    }
-
-  return False;
-}
+       char *fname = NULL;
+       pstring rhostsfile;
+       const struct passwd *pass = Get_Pwnam(user, True);
+
+       if (!pass)
+               return False;
 
+       fname = lp_hosts_equiv();
 
+       /* note: don't allow hosts.equiv on root */
+       if (fname && *fname && (pass->pw_uid != 0))
+       {
+               if (check_user_equiv(user, client_connection_name(), fname))
+                       return (True);
+       }
+
+       if (lp_use_rhosts())
+       {
+               char *home = get_unixhome_dir(user);
+               if (home)
+               {
+                       slprintf(rhostsfile, sizeof(rhostsfile) - 1,
+                                "%s/.rhosts", home);
+                       if (check_user_equiv
+                           (user, client_connection_name(), rhostsfile))
+                               return (True);
+               }
+       }
+
+       return False;
+}
index b4e3e3a0d173ce27d5f2faef75a53938ea74b63d..71376b8a0a995e44ff9c046ed006b5bfe1407abc 100644 (file)
@@ -42,69 +42,71 @@ extern struct pipe_id_info pipe_names[];
   This code is basically stolen from reply_open_and_X with some
   wrinkles to handle pipes.
 ****************************************************************************/
-int reply_open_pipe_and_X(connection_struct *conn,
-                         char *inbuf,char *outbuf,int length,int bufsize)
+int reply_open_pipe_and_X(connection_struct * conn,
+                         char *inbuf, char *outbuf, int length, int bufsize)
 {
        pstring fname;
        uint16 vuid = SVAL(inbuf, smb_uid);
        pipes_struct *p;
-       int smb_ofun = SVAL(inbuf,smb_vwv8);
-       int size=0,fmode=0,mtime=0,rmode=0;
+       int smb_ofun = SVAL(inbuf, smb_vwv8);
+       int size = 0, fmode = 0, mtime = 0, rmode = 0;
        int i;
        vuser_key key;
 
        /* XXXX we need to handle passed times, sattr and flags */
-       pstrcpy(fname,smb_buf(inbuf));
+       pstrcpy(fname, smb_buf(inbuf));
 
        /* If the name doesn't start \PIPE\ then this is directed */
        /* at a mailslot or something we really, really don't understand, */
        /* not just something we really don't understand. */
-       if ( strncmp(fname,PIPE,PIPELEN) != 0 )
-               return(ERROR(ERRSRV,ERRaccess));
+       if (strncmp(fname, PIPE, PIPELEN) != 0)
+               return (ERROR(ERRSRV, ERRaccess));
 
-       DEBUG(4,("Opening pipe %s.\n", fname));
+       DEBUG(4, ("Opening pipe %s.\n", fname));
 
        /* See if it is one we want to handle. */
-       for( i = 0; pipe_names[i].client_pipe ; i++ )
-               if( strequal(fname,pipe_names[i].client_pipe) )
+       for (i = 0; pipe_names[i].client_pipe; i++)
+               if (strequal(fname, pipe_names[i].client_pipe))
                        break;
 
        if (pipe_names[i].client_pipe == NULL)
-               return(ERROR(ERRSRV,ERRaccess));
+               return (ERROR(ERRSRV, ERRaccess));
 
        /* Strip \PIPE\ off the name. */
-       pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
+       pstrcpy(fname, smb_buf(inbuf) + PIPELEN);
 
        /* Known pipes arrive with DIR attribs. Remove it so a regular file */
        /* can be opened and add it in after the open. */
-       DEBUG(3,("Known pipe %s opening.\n",fname));
-       smb_ofun |= 0x10;               /* Add Create it not exists flag */
+       DEBUG(3, ("Known pipe %s opening.\n", fname));
+       smb_ofun |= 0x10;       /* Add Create it not exists flag */
 
        key.pid = getpid();
        key.vuid = vuid;
        p = open_rpc_pipe_p(fname, &key, NULL);
-       if (!p) return(ERROR(ERRSRV,ERRnofids));
+       if (!p)
+               return (ERROR(ERRSRV, ERRnofids));
 
        /* Prepare the reply */
-       set_message(outbuf,15,0,True);
+       set_message(outbuf, 15, 0, True);
 
        /* Mark the opened file as an existing named pipe in message mode. */
-       SSVAL(outbuf,smb_vwv9,2);
-       SSVAL(outbuf,smb_vwv10,0xc700);
+       SSVAL(outbuf, smb_vwv9, 2);
+       SSVAL(outbuf, smb_vwv10, 0xc700);
 
-       if (rmode == 2) {
-               DEBUG(4,("Resetting open result to open from create.\n"));
+       if (rmode == 2)
+       {
+               DEBUG(4, ("Resetting open result to open from create.\n"));
                rmode = 1;
        }
 
-       SSVAL(outbuf,smb_vwv2, p->pnum);
-       SSVAL(outbuf,smb_vwv3,fmode);
-       put_dos_date3(outbuf,smb_vwv4,mtime);
-       SIVAL(outbuf,smb_vwv6,size);
-       SSVAL(outbuf,smb_vwv8,rmode);
-       SSVAL(outbuf,smb_vwv11,0x0001);
+       SSVAL(outbuf, smb_vwv2, p->pnum);
+       SSVAL(outbuf, smb_vwv3, fmode);
+       put_dos_date3(outbuf, smb_vwv4, mtime);
+       SIVAL(outbuf, smb_vwv6, size);
+       SSVAL(outbuf, smb_vwv8, rmode);
+       SSVAL(outbuf, smb_vwv11, 0x0001);
 
-       return chain_reply(inbuf,outbuf,length,bufsize);
+       return chain_reply(inbuf, outbuf, length, bufsize);
 }
 
 /****************************************************************************
@@ -113,15 +115,16 @@ int reply_open_pipe_and_X(connection_struct *conn,
   This code is basically stolen from reply_write with some
   wrinkles to handle pipes.
 ****************************************************************************/
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_write(char *inbuf, char *outbuf, int length, int bufsize)
 {
-       pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
-       size_t numtowrite = SVAL(inbuf,smb_vwv1);
+       pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv0);
+       size_t numtowrite = SVAL(inbuf, smb_vwv1);
        int nwritten = -1;
        char *data;
        size_t outsize;
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return (ERROR(ERRDOS, ERRbadfid));
 
        data = smb_buf(inbuf) + 3;
 
@@ -136,17 +139,16 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
 
        if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
        {
-               DEBUG(3,("reply_write_pipe: nwritten: %d numtowrite:%d\n",
-                           nwritten, numtowrite));
-               return (UNIXERROR(ERRDOS,ERRnoaccess));
+               DEBUG(3, ("reply_write_pipe: nwritten: %d numtowrite:%d\n",
+                         nwritten, numtowrite));
+               return (UNIXERROR(ERRDOS, ERRnoaccess));
        }
-  
-       outsize = set_message(outbuf,1,0,True);
 
-       SSVAL(outbuf,smb_vwv0,nwritten);
+       outsize = set_message(outbuf, 1, 0, True);
+
+       SSVAL(outbuf, smb_vwv0, nwritten);
 
-       DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
-                p->pnum, nwritten));
+       DEBUG(3, ("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
 
        return outsize;
 }
@@ -157,16 +159,24 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
   This code is basically stolen from reply_write_and_X with some
   wrinkles to handle pipes.
 ****************************************************************************/
-int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_write_and_X(char *inbuf, char *outbuf, int length, int bufsize)
 {
-       pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
-       size_t numtowrite = SVAL(inbuf,smb_vwv10);
+       pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv2);
+       size_t numtowrite = SVAL(inbuf, smb_vwv10);
        int nwritten = -1;
        int smb_doff = SVAL(inbuf, smb_vwv11);
        int write_mode = SVAL(inbuf, smb_vwv7);
        char *data;
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       /* 
+        * start of message mode pipe: indicates start of dce/rpc pdu.
+        */
+
+       BOOL msg;
+       msg = IS_BITS_SET_ALL(write_mode, PIPE_START_MESSAGE | PIPE_RAW_MODE);
+
+       if (!p)
+               return (ERROR(ERRDOS, ERRbadfid));
 
        data = smb_base(inbuf) + smb_doff;
 
@@ -176,33 +186,37 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
        }
        else
        {
-               if (write_mode == 0x000c)
+               if (msg)
                {
-                       nwritten = write_pipe(p, data+2, numtowrite-2);
-                       if (nwritten != 0)
-                       {
-                               nwritten += 2;
-                       }
+                       /*
+                        * skip the length-of-pdu, the client could be
+                        * a nasty bitch and lie to us, e.g
+                        * an nt-smb-writepipe-DoS attack.
+                        */
+
+                       data += 2;
+                       numtowrite -= 2;
                }
-               else
+
+               nwritten = write_pipe(p, data, numtowrite);
+
+               if (msg && nwritten != 0)
                {
-                       nwritten = write_pipe(p, data, numtowrite);
+                       nwritten += 2;
                }
        }
 
        if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
        {
-               return (UNIXERROR(ERRDOS,ERRnoaccess));
+               return (UNIXERROR(ERRDOS, ERRnoaccess));
        }
-  
-       set_message(outbuf,6,0,True);
 
-       SSVAL(outbuf,smb_vwv2,nwritten);
-  
-       DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n",
-                p->pnum, nwritten));
+       set_message(outbuf, 6, 0, True);
+       SSVAL(outbuf, smb_vwv2, nwritten);
+
+       DEBUG(3, ("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
 
-       return chain_reply(inbuf,outbuf,length,bufsize);
+       return chain_reply(inbuf, outbuf, length, bufsize);
 }
 
 /****************************************************************************
@@ -211,48 +225,50 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   This code is basically stolen from reply_read_and_X with some
   wrinkles to handle pipes.
 ****************************************************************************/
-int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_read_and_X(char *inbuf, char *outbuf, int length, int bufsize)
 {
-       pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
-       int smb_maxcnt = SVAL(inbuf,smb_vwv5);
-       int smb_mincnt = SVAL(inbuf,smb_vwv6);
+       pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv2);
+       int smb_maxcnt = SVAL(inbuf, smb_vwv5);
+       int smb_mincnt = SVAL(inbuf, smb_vwv6);
        int nread = -1;
        char *data;
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return (ERROR(ERRDOS, ERRbadfid));
 
-       set_message(outbuf,12,0,True);
+       set_message(outbuf, 12, 0, True);
        data = smb_buf(outbuf);
 
        nread = read_pipe(p, data, smb_maxcnt);
 
        if (nread < 0)
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
-  
-       SSVAL(outbuf,smb_vwv5,nread);
-       SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
-       SSVAL(smb_buf(outbuf),-2,nread);
-  
-       DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
-                p->pnum, smb_mincnt, smb_maxcnt, nread));
-
-       return chain_reply(inbuf,outbuf,length,bufsize);
+               return (UNIXERROR(ERRDOS, ERRnoaccess));
+
+       SSVAL(outbuf, smb_vwv5, nread);
+       SSVAL(outbuf, smb_vwv6, smb_offset(data, outbuf));
+       SSVAL(smb_buf(outbuf), -2, nread);
+
+       DEBUG(3, ("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
+                 p->pnum, smb_mincnt, smb_maxcnt, nread));
+
+       return chain_reply(inbuf, outbuf, length, bufsize);
 }
 
 /****************************************************************************
   reply to a close
 ****************************************************************************/
-int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
+int reply_pipe_close(connection_struct * conn, char *inbuf, char *outbuf)
 {
-       pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
-       int outsize = set_message(outbuf,0,0,True);
+       pipes_struct *p = get_rpc_pipe_p(inbuf, smb_vwv0);
+       int outsize = set_message(outbuf, 0, 0, True);
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return (ERROR(ERRDOS, ERRbadfid));
 
-       DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
+       DEBUG(5, ("reply_pipe_close: pnum:%x\n", p->pnum));
 
-       if (!close_rpc_pipe_hnd(p)) return(ERROR(ERRDOS,ERRbadfid));
+       if (!close_rpc_pipe_hnd(p))
+               return (ERROR(ERRDOS, ERRbadfid));
 
-       return(outsize);
+       return (outsize);
 }
-
index f51e54a568c3dda94a6da366c2f025eb649b08ed..34044b82f224fa4a5708707c7ab9eea18df6adfc 100644 (file)
@@ -37,7 +37,7 @@ static int rp_timeout = 5;
 static time_t rp_time = 0;
 static char *rp_buffer = NULL;
 static BOOL predict_skip=False;
-extern time_t smb_last_time;
+extern struct timeval smb_last_time;
 
 /****************************************************************************
 handle read prediction on a file
@@ -53,7 +53,7 @@ ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char *
   if (fd == rp_fd && 
       offset >= rp_offset && 
       possible>0 &&
-      smb_last_time-rp_time < rp_timeout)
+      smb_last_time.tv_secs - rp_time < rp_timeout)
   {
     ret = possible;
     if (buf)
index bba218a73e83ab3ebd23362d29638cb43dd96ab5..4a5f3eb03b8888866e86fce1ff5abda456c078d5 100644 (file)
@@ -23,9 +23,9 @@
 
 extern int DEBUGLEVEL;
 
-time_t smb_last_time=(time_t)0;
+struct timeval smb_last_time;
 
-char *InBuffer = NULL;
+static char *InBuffer = NULL;
 char *OutBuffer = NULL;
 char *last_inbuf = NULL;
 
@@ -48,7 +48,7 @@ extern char *last_inbuf;
 extern char *InBuffer;
 extern char *OutBuffer;
 extern int smb_read_error;
-extern BOOL reload_after_sighup;
+extern VOLATILE SIG_ATOMIC_T reload_after_sighup;
 extern fstring global_myworkgroup;
 extern pstring global_myname;
 extern int max_send;
@@ -230,6 +230,52 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
   return ret;
 }
 
+/****************************************************************************
+ We're terminating and have closed all our files/connections etc.
+ If there are any pending local messages we need to respond to them
+ before termination so that other smbds don't think we just died whilst
+ holding oplocks.
+****************************************************************************/
+
+void respond_to_all_remaining_local_messages(void)
+{
+  char buffer[1024];
+  fd_set fds;
+
+  /*
+   * Assert we have no exclusive open oplocks.
+   */
+
+  if(get_number_of_exclusive_open_oplocks()) {
+    DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
+          get_number_of_exclusive_open_oplocks() ));
+    return;
+  }
+
+  /*
+   * Setup the select read fd set.
+   */
+
+  FD_ZERO(&fds);
+  if(!setup_oplock_select_set(&fds))
+    return;
+
+  /*
+   * Keep doing receive_local_message with a 1 ms timeout until
+   * we have no more messages.
+   */
+
+  while(receive_local_message(&fds, buffer, sizeof(buffer), 1)) {
+    /* Deal with oplock break requests from other smbd's. */
+    process_local_message(buffer, sizeof(buffer));
+
+    FD_ZERO(&fds);
+    (void)setup_oplock_select_set(&fds);
+  }
+
+  return;
+}
+
 
 /*
 These flags determine some of the permissions required to do an operation 
@@ -282,8 +328,8 @@ struct smb_message_struct
 
    {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
    {SMBread,"SMBread",reply_read,AS_USER},
-   {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC},
-   {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
+   {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC },
+   {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC },
    {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
    {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
    {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
@@ -318,9 +364,9 @@ struct smb_message_struct
    {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
    {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
    {SMBwritec,"SMBwritec",NULL,AS_USER},
-   {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
-   {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
-   {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
+   {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
+   {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER },
+   {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
    {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
    {SMBioctls,"SMBioctls",NULL,AS_USER},
    {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
@@ -329,7 +375,7 @@ struct smb_message_struct
    {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
    {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
    {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
-   {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
+   {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER },
    
    {SMBffirst,"SMBffirst",reply_search,AS_USER},
    {SMBfunique,"SMBfunique",reply_search,AS_USER},
@@ -338,14 +384,14 @@ struct smb_message_struct
    /* LANMAN2.0 PROTOCOL FOLLOWS */
    {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
    {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
-   {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | CAN_IPC},
+   {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK | CAN_IPC },
    {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
 
    /* NT PROTOCOL FOLLOWS */
    {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
-   {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
+   {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
    {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
-   {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
+   {SMBntcancel, "SMBntcancel", reply_ntcancel, 0 },
 
    /* messaging routines */
    {SMBsends,"SMBsends",reply_sends,AS_GUEST},
@@ -367,14 +413,15 @@ do a switch on the message type, and return the response size
 ****************************************************************************/
 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
 {
-  static int pid= -1;
+  static pid_t pid= (pid_t)-1;
   int outsize = 0;
   static int num_smb_messages = 
     sizeof(smb_messages) / sizeof(struct smb_message_struct);
   int match;
   extern int Client;
+  extern int global_smbpid;
 
-  if (pid == -1)
+  if (pid == (pid_t)-1)
     pid = getpid();
 
   errno = 0;
@@ -391,6 +438,10 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
     if (smb_messages[match].code == type)
       break;
 
+  /* yuck! this is an interim measure before we get rid of our
+     current inbuf/outbuf system */
+  global_smbpid = SVAL(inbuf,smb_pid);
+
   if (match == num_smb_messages)
   {
     DEBUG(0,("Unknown message type %d!\n",type));
@@ -398,21 +449,25 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
   }
   else
   {
-    DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
+    DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,(int)pid));
 
-    if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
+    if(global_oplock_break)
     {
-      /* 
-       * Queue this message as we are the process of an oplock break.
-       */
+      int flags = smb_messages[match].flags;
 
-      DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
-      DEBUGADD( 2, ( "oplock break state.\n" ) );
+      if(flags & QUEUE_IN_OPLOCK)
+      {
+        /* 
+         * Queue this message as we are the process of an oplock break.
+         */
 
-      push_oplock_pending_smb_message( inbuf, size );
-      return -1;
-    }          
+        DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
+        DEBUGADD( 2, ( "oplock break state.\n" ) );
 
+        push_oplock_pending_smb_message( inbuf, size );
+        return -1;
+      }          
+    }
     if (smb_messages[match].fn)
     {
       int flags = smb_messages[match].flags;
@@ -434,8 +489,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
        * move it unless you know what you're doing... :-).
        * JRA.
        */
-      if (session_tag != last_session_tag)
-      {
+      if (session_tag != last_session_tag) {
         user_struct *vuser = NULL;
         vuser_key key;
        key.pid = pid;
@@ -460,7 +514,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
         if (flags & AS_GUEST) 
           flags &= ~AS_USER;
         else
-          return(ERROR(ERRSRV,ERRinvnid));
+          return(ERROR(ERRSRV,ERRaccess));
       }
       /* this code is to work around a bug is MS client 3 without
          introducing a security hole - it needs to be able to do
@@ -512,9 +566,8 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
   int type = CVAL(inbuf,smb_com);
   int outsize = 0;
   int msg_type = CVAL(inbuf,0);
-  extern int chain_size;
 
-  smb_last_time = time(NULL);
+  GetTimeOfDay(&smb_last_time);
 
   chain_size = 0;
   file_chain_reset();
@@ -565,7 +618,7 @@ void process_smb(char *inbuf, char *outbuf)
                   name" */
                  static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
                  DEBUG( 1, ( "Connection denied from %s\n",
-                             client_connection_addr() ) );
+                             client_addr(Client) ) );
                  send_smb(Client,(char *)buf);
                  exit_server("connection denied");
          }
@@ -646,7 +699,7 @@ char *smb_fn_name(int type)
 
 void construct_reply_common(char *inbuf,char *outbuf)
 {
-  memset(outbuf, 0, smb_size);
+  memset(outbuf,'\0',smb_size);
 
   set_message(outbuf,0,0,True);
   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
@@ -656,7 +709,9 @@ void construct_reply_common(char *inbuf,char *outbuf)
   CVAL(outbuf,smb_reh) = 0;
   SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
                                  means a reply */
-  SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS); /* say we support long filenames */
+  SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS);
+       /* say we support long filenames */
+
   SSVAL(outbuf,smb_err,SMB_SUCCESS);
   SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
   SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
@@ -677,7 +732,6 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
   int outsize2;
   char inbuf_saved[smb_wct];
   char outbuf_saved[smb_wct];
-  extern int chain_size;
   int wct = CVAL(outbuf,smb_wct);
   int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
 
@@ -693,6 +747,14 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
     orig_outbuf = outbuf;
   }
 
+  /*
+   * The original Win95 redirector dies on a reply to
+   * a lockingX and read chain unless the chain reply is
+   * 4 byte aligned. JRA.
+   */
+
+  outsize = (outsize + 3) & ~3;
+
   /* we need to tell the client where the next part of the reply will be */
   SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
   CVAL(outbuf,smb_vwv0) = smb_com2;
@@ -747,71 +809,164 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
 }
 
 /****************************************************************************
-  process commands from the client
+ Setup the needed select timeout.
 ****************************************************************************/
-void smbd_process(void)
+
+static int setup_select_timeout(void)
 {
-  extern int Client;
-  extern int ClientPort;
+  int change_notify_timeout = lp_change_notify_timeout() * 1000;
+  int select_timeout;
 
-  InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  if ((InBuffer == NULL) || (OutBuffer == NULL)) 
-    return;
+  /*
+   * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we
+   * have removed any blocking locks. JRA.
+   */
 
-  InBuffer += SMB_ALIGNMENT;
-  OutBuffer += SMB_ALIGNMENT;
+  select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 :
+                                              SMBD_SELECT_TIMEOUT*1000;
+
+  if (change_notifies_pending())
+    select_timeout = MIN(select_timeout, change_notify_timeout);
+
+  return select_timeout;
+}
+
+/****************************************************************************
+ Check if services need reloading.
+****************************************************************************/
+
+void check_reload(int t)
+{
+  static time_t last_smb_conf_reload_time = 0;
+
+  if(last_smb_conf_reload_time == 0)
+    last_smb_conf_reload_time = t;
 
-#if PRIME_NMBD
-  DEBUG(3,("priming nmbd\n"));
+  if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK))
   {
-    struct in_addr ip;
-    ip = *interpret_addr2("localhost");
-    if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
-    *OutBuffer = 0;
-    send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
+    reload_services(True);
+    reload_after_sighup = False;
+    last_smb_conf_reload_time = t;
   }
-#endif    
+}
 
+/****************************************************************************
+ Process any timeout housekeeping. Return False if the caller should exit.
+****************************************************************************/
 
-  max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
+{
+  extern int Client;
+  static time_t last_keepalive_sent_time = 0;
+  static time_t last_idle_closed_check = 0;
+  time_t t;
+  BOOL allidle = True;
+  extern int keepalive;
 
-  /* re-initialise the timezone */
-  TimeInit();
+  if (smb_read_error == READ_EOF) 
+  {
+    DEBUG(3,("end of file from client\n"));
+    return False;
+  }
 
-  /* if connection on port 445, fake session setup... */
-  if(ClientPort == 445)
+  if (smb_read_error == READ_ERROR) 
   {
-    extern fstring remote_machine;
-    extern fstring local_machine;
+    DEBUG(3,("receive_smb error (%s) exiting\n",
+              strerror(errno)));
+    return False;
+  }
 
-    fstrcpy(remote_machine, dns_to_netbios_name(client_connection_name()));
-    fstrcpy(local_machine, global_myname);
-    remote_machine[15] = 0;
-    local_machine[15] = 0;
-    strlower(remote_machine);
-    strlower(local_machine);
+  *last_timeout_processing_time = t = time(NULL);
 
-    DEBUG(2, ("smbd_process(): faking session setup\n"
-              "client_name: %s my_name: %s\n", remote_machine, local_machine));
+  if(last_keepalive_sent_time == 0)
+    last_keepalive_sent_time = t;
 
-    add_session_user(remote_machine);
+  if(last_idle_closed_check == 0)
+    last_idle_closed_check = t;
 
-    reload_services(True);
-    reopen_logs();
+  /* become root again if waiting */
+  unbecome_user();
 
-    if(lp_status(-1)) {
-      claim_connection(NULL,"STATUS.",MAXSTATUS,True);
-    }
+  /* check if we need to reload services */
+  check_reload(t);
+
+  /* automatic timeout if all connections are closed */      
+  if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) 
+  {
+    DEBUG( 2, ( "Closing idle connection\n" ) );
+    return False;
   }
+  else
+    last_idle_closed_check = t;
+
+  if (keepalive && (t - last_keepalive_sent_time)>keepalive) 
+  {
+    if (!send_keepalive(Client)) {
+      DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+      return False;
+    }      
+    DEBUG(0,("TODO: send keepalive to all smbd client-side SMB connections\n"));
+    last_keepalive_sent_time = t;
+  }
+
+  /* check for connection timeouts */
+  allidle = conn_idle_all(t, deadtime);
+
+  if (allidle && conn_num_open()>0) {
+    DEBUG(2,("Closing idle connection 2.\n"));
+    return False;
+  }
+
+  /*
+   * Check to see if we have any blocking locks
+   * outstanding on the queue.
+   */
+  process_blocking_lock_queue(t);
+
+  /*
+   * Check to see if we have any change notifies 
+   * outstanding on the queue.
+   */
+  process_pending_change_notify_queue(t);
+
+  /*
+   * Modify the select timeout depending upon
+   * what we have remaining in our queues.
+   */
+
+  *select_timeout = setup_select_timeout();
+
+  return True;
+}
+
+/****************************************************************************
+  process commands from the client
+****************************************************************************/
+
+void smbd_process(void)
+{
+  extern int smb_echo_count;
+  time_t last_timeout_processing_time = time(NULL);
+  unsigned int num_smbs = 0;
+
+  InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+  OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+  if ((InBuffer == NULL) || (OutBuffer == NULL)) 
+    return;
+
+  InBuffer += SMB_ALIGNMENT;
+  OutBuffer += SMB_ALIGNMENT;
+
+  max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
+
+  /* re-initialise the timezone */
+  TimeInit();
 
   while (True)
   {
     int deadtime = lp_deadtime()*60;
-    int counter;
-    int last_keepalive=0;
-    int service_load_counter = 0;
     BOOL got_smb = False;
+    int select_timeout = setup_select_timeout();
 
     if (deadtime <= 0)
       deadtime = DEFAULT_SMBD_TIMEOUT;
@@ -823,106 +978,55 @@ void smbd_process(void)
 
     errno = 0;      
 
-    for (counter=SMBD_SELECT_LOOP; 
-          !receive_message_or_smb(InBuffer,BUFFER_SIZE,
-                                  SMBD_SELECT_LOOP*1000,&got_smb); 
-          counter += SMBD_SELECT_LOOP)
-    {
-      time_t t;
-      BOOL allidle = True;
-      extern int keepalive;
-
-      if (counter > 365 * 3600) /* big number of seconds. */
-      {
-        counter = 0;
-        service_load_counter = 0;
-      }
-
-      if (smb_read_error == READ_EOF) 
-      {
-        DEBUG(3,("end of file from client\n"));
-        return;
-      }
+    /* free up temporary memory */
+    lp_talloc_free();
 
-      if (smb_read_error == READ_ERROR) 
-      {
-        DEBUG(3,("receive_smb error (%s) exiting\n",
-                  strerror(errno)));
+    while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
+    {
+      if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
         return;
-      }
-
-      t = time(NULL);
-
-      /* become root again if waiting */
-      unbecome_user();
-
-      /* check for smb.conf reload */
-      if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
-      {
-        service_load_counter = counter;
-
-        /* reload services, if files have changed. */
-        reload_services(True);
-      }
+      num_smbs = 0; /* Reset smb counter. */
+    }
 
+    if(got_smb) {
       /*
-       * If reload_after_sighup == True then we got a SIGHUP
-       * and are being asked to reload. Fix from <branko.cibej@hermes.si>
-       */
+       * Ensure we do timeout processing if the SMB we just got was
+       * only an echo request. This allows us to set the select
+       * timeout in 'receive_message_or_smb()' to any value we like
+       * without worrying that the client will send echo requests
+       * faster than the select timeout, thus starving out the
+       * essential processing (change notify, blocking locks) that
+       * the timeout code does. JRA.
+       */ 
+      int num_echos = smb_echo_count;
 
-      if (reload_after_sighup)
-      {
-        DEBUG(0,("Reloading services after SIGHUP\n"));
-        reload_services(False);
-        reload_after_sighup = False;
-        /*
-         * Use this as an excuse to print some stats.
-         */
-        print_stat_cache_statistics();
-      }
-
-      /* automatic timeout if all connections are closed */      
-      if (conn_num_open()==0 && counter >= IDLE_CLOSED_TIMEOUT) 
-      {
-        DEBUG( 2, ( "Closing idle connection\n" ) );
-        return;
-      }
+      process_smb(InBuffer, OutBuffer);
 
-      if (keepalive && (counter-last_keepalive)>keepalive) 
-      {
-             if (!send_keepalive(Client)) {
-                     DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
-                     return;
-             }     
-             last_keepalive = counter;
+      if(smb_echo_count != num_echos) {
+        if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+          return;
+        num_smbs = 0; /* Reset smb counter. */
       }
 
-       /* close down all idle client-side MSRPC connections */
-       free_connections();
-
-      /* check for connection timeouts */
-      allidle = conn_idle_all(t, deadtime);
-
-      if (allidle && conn_num_open()>0) {
-             DEBUG(2,("Closing idle connection 2.\n"));
-             return;
-      }
+      num_smbs++;
 
       /*
-       * Check to see if we have any blocking locks
-       * outstanding on the queue.
+       * If we are getting smb requests in a constant stream
+       * with no echos, make sure we attempt timeout processing
+       * every select_timeout milliseconds - but only check for this
+       * every 200 smb requests.
        */
-      process_blocking_lock_queue(t);
 
-      /*
-       * Check to see if we have any change notifies 
-       * outstanding on the queue.
-       */
-      process_pending_change_notify_queue(t);
+      if((num_smbs % 200) == 0) {
+        time_t new_check_time = time(NULL);
+        if(last_timeout_processing_time - new_check_time >= (select_timeout/1000)) {
+          if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+            return;
+          num_smbs = 0; /* Reset smb counter. */
+          last_timeout_processing_time = new_check_time; /* Reset time. */
+        }
+      }
     }
-
-    if(got_smb)
-      process_smb(InBuffer, OutBuffer);
     else
       process_local_message(InBuffer, BUFFER_SIZE);
   }
index 508f76a2a6546c5a7f9ddf10cf62f9e6f396e0af..f0bffec69a34421011e7413780cf26940e1453ef 100644 (file)
@@ -38,12 +38,12 @@ extern BOOL case_sensitive;
 extern BOOL case_preserve;
 extern BOOL short_case_preserve;
 extern pstring sesssetup_user;
+extern pstring global_myname;
 extern fstring global_myworkgroup;
-extern fstring global_myname;
 extern int Client;
 extern int global_oplock_break;
 uint32 global_client_caps = 0;
-
+unsigned int smb_echo_count = 0;
 
 /****************************************************************************
 report a possible attack via the password buffer overflow bug
@@ -78,7 +78,7 @@ int reply_special(char *inbuf, char *outbuf)
 
        *name1 = *name2 = 0;
 
-       memset(outbuf, 0,  smb_size);
+       memset(outbuf, '\0', smb_size);
 
        smb_setlen(outbuf, 0);
 
@@ -132,8 +132,7 @@ int reply_special(char *inbuf, char *outbuf)
 
                        if (lp_status(-1))
                        {
-                               claim_connection(NULL, "STATUS.", MAXSTATUS,
-                                                True);
+                               claim_connection(NULL, "", MAXSTATUS, True);
                        }
 
                        break;
@@ -168,9 +167,7 @@ work out what error to give to a failed connection
 static int connection_error(char *inbuf, char *outbuf, int ecode)
 {
        if (ecode == ERRnoipc)
-       {
                return (ERROR(ERRDOS, ERRnoipc));
-       }
 
        return (ERROR(ERRSRV, ecode));
 }
@@ -215,11 +212,12 @@ static void parse_connect(char *p, char *service, char *user,
 
 
 /****************************************************************************
-  reply to a tcon
+ Reply to a tcon.
 ****************************************************************************/
 int reply_tcon(connection_struct * conn,
               char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
+       BOOL doencrypt = SMBENCRYPT();
        pstring service;
        pstring user;
        pstring password;
@@ -234,10 +232,19 @@ int reply_tcon(connection_struct * conn,
        parse_connect(smb_buf(inbuf) + 1, service, user, password, &pwlen,
                      dev);
 
+       /*
+        * map from DOS codepage format to Unix
+        */
+
+       dos_to_unix(user, True);
+       if (!doencrypt)
+       {
+               dos_to_unix(password, True);
+       }
+
        map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
 
-       conn =
-               make_connection(service, user, global_myworkgroup, password,
+       conn = make_connection(service, user, global_myworkgroup, password,
                                pwlen, dev, vuid, &ecode);
 
        if (!conn)
@@ -318,10 +325,19 @@ int reply_tcon_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        StrnCpy(devicename, path + strlen(path) + 1, 6);
        DEBUG(4, ("Got device type %s\n", devicename));
 
+       /*
+        * map from DOS codepage format to Unix
+        */
+
+       dos_to_unix(user, True);
+       if (!doencrypt)
+       {
+               dos_to_unix(password, True);
+       }
+
        map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
 
-       conn =
-               make_connection(service, user, global_myworkgroup, password,
+       conn = make_connection(service, user, global_myworkgroup, password,
                                passlen, devicename, vuid, &ecode);
 
        if (!conn)
@@ -349,6 +365,8 @@ int reply_tcon_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                /* what does setting this bit do? It is set by NT4 and
                   may affect the ability to autorun mounted cdroms */
                SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS);
+
+               init_dfsroot(conn, inbuf, outbuf);
        }
 
        DEBUG(3, ("tconX service=%s user=%s\n", service, user));
@@ -382,14 +400,39 @@ int reply_unknown(char *inbuf, char *outbuf)
 int reply_ioctl(connection_struct * conn,
                char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
-       DEBUG(3, ("ignoring ioctl\n"));
-#if 0
-       /* we just say it succeeds and hope its all OK. 
-          some day it would be nice to interpret them individually */
-       return set_message(outbuf, 1, 0, True);
-#else
-       return (ERROR(ERRSRV, ERRnosupport));
-#endif
+       uint16 device = SVAL(inbuf, smb_vwv1);
+       uint16 function = SVAL(inbuf, smb_vwv2);
+       uint32 ioctl_code = (device << 16) + function;
+       int replysize, outsize;
+       char *p;
+
+       DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
+
+       switch (ioctl_code)
+       {
+               case IOCTL_QUERY_JOB_INFO:
+                       replysize = 32;
+                       break;
+               default:
+                       return (ERROR(ERRSRV, ERRnosupport));
+       }
+
+       outsize = set_message(outbuf, 8, replysize + 1, True);
+       SSVAL(outbuf, smb_vwv1, replysize);     /* Total data bytes returned */
+       SSVAL(outbuf, smb_vwv5, replysize);     /* Data bytes this buffer */
+       SSVAL(outbuf, smb_vwv6, 52);    /* Offset to data */
+       p = smb_buf(outbuf) + 1;        /* Allow for alignment */
+
+       switch (ioctl_code)
+       {
+               case IOCTL_QUERY_JOB_INFO:
+                       SSVAL(p, 0, 1); /* Job number */
+                       StrnCpy(p + 2, global_myname, 15);      /* Our NetBIOS name */
+                       StrnCpy(p + 18, lp_servicename(SNUM(conn)), 13);        /* Service name */
+                       break;
+       }
+
+       return outsize;
 }
 
 /****************************************************************************
@@ -501,22 +544,23 @@ user %s attempted down-level SMB connection\n",
                enum remote_arch_types ra_type = get_remote_arch();
                char *p = smb_buf(inbuf);
 
-               DEBUG(10,
-                     ("passlen1: %d passlen2: %d\n", passlen1, passlen2));
-
-               global_client_caps = IVAL(inbuf, smb_vwv11);
+               if (global_client_caps == 0)
+                       global_client_caps = IVAL(inbuf, smb_vwv11);
 
                /* client_caps is used as final determination if client is NT or Win95. 
                   This is needed to return the correct error codes in some
                   circumstances.
                 */
 
-               if (ra_type == RA_WINNT || ra_type == RA_WIN95)
+               if (ra_type == RA_WINNT || ra_type == RA_WIN2K
+                   || ra_type == RA_WIN95)
                {
-                       if (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
-                               set_remote_arch(RA_WINNT);
-                       else
+                       if (!
+                           (global_client_caps &
+                            (CAP_NT_SMBS | CAP_STATUS32)))
+                       {
                                set_remote_arch(RA_WIN95);
+                       }
                }
 
                if (passlen1 != 24 && passlen2 <= 24)
@@ -564,12 +608,26 @@ user %s attempted down-level SMB connection\n",
                        smb_ntpasslen = passlen2;
                        memcpy(smb_ntpasswd, p + passlen1, smb_ntpasslen);
                        smb_ntpasswd[smb_ntpasslen] = 0;
+
+                       /*
+                        * Ensure the plaintext passwords are in UNIX format.
+                        */
+                       if (!doencrypt)
+                       {
+                               dos_to_unix(smb_apasswd, True);
+                               dos_to_unix(smb_ntpasswd, True);
+                       }
+
                }
                else
                {
                        /* we use the first password that they gave */
                        smb_apasslen = passlen1;
                        StrnCpy(smb_apasswd, p, smb_apasslen);
+                       /*
+                        * Ensure the plaintext password is in UNIX format.
+                        */
+                       dos_to_unix(smb_apasswd, True);
 
                        /* trim the password */
                        smb_apasslen = strlen(smb_apasswd);
@@ -595,6 +653,11 @@ user %s attempted down-level SMB connection\n",
 
                fstrcpy(user, p);
                p = skip_string(p, 1);
+               /*
+                * Incoming user is in DOS codepage format. Convert
+                * to UNIX.
+                */
+               dos_to_unix(user, True);
                domain = p;
 
                DEBUG(3,
@@ -627,6 +690,13 @@ user %s attempted down-level SMB connection\n",
        }
 
        strlower(user);
+
+       /*
+        * map from DOS codepage format to Unix
+        */
+
+       dos_to_unix(user, True);
+
        /*
         * In share level security, only overwrite sesssetup_use if
         * it's a non null-session share. Helps keep %U and %G
@@ -796,11 +866,10 @@ int reply_chkpth(connection_struct * conn, char *inbuf, char *outbuf,
        SMB_STRUCT_STAT st;
 
        pstrcpy(name, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(name, conn, 0, &bad_path, &st))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+
+       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
+       unix_convert(name, conn, 0, &bad_path, &st);
 
        mode = SVAL(inbuf, smb_vwv0);
 
@@ -809,7 +878,7 @@ int reply_chkpth(connection_struct * conn, char *inbuf, char *outbuf,
                if (VALID_STAT(st))
                        ok = S_ISDIR(st.st_mode);
                else
-                       ok = dos_directory_exist(name, NULL);
+                       ok = vfs_directory_exist(conn, name, NULL);
        }
 
        if (!ok)
@@ -863,6 +932,10 @@ int reply_getatr(connection_struct * conn, char *inbuf, char *outbuf,
 
        pstrcpy(fname, smb_buf(inbuf) + 1);
 
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       /* if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && dfs_redirect(fname,conn)) return(dfs_path_error(inbuf,outbuf)); 
+        */
        /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
           under WfWg - weird! */
        if (!(*fname))
@@ -876,17 +949,10 @@ int reply_getatr(connection_struct * conn, char *inbuf, char *outbuf,
        }
        else
        {
-               if (!unix_dfs_convert(fname, conn, 0, &bad_path, &sbuf))
-               {
-                       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-                       return (ERROR
-                               (0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-               }
+               unix_convert(fname, conn, 0, &bad_path, &sbuf);
                if (check_name(fname, conn))
                {
-                       if (VALID_STAT(sbuf)
-                           || conn->vfs_ops.stat(dos_to_unix(fname, False),
-                                                 &sbuf) == 0)
+                       if (VALID_STAT(sbuf) || dos_stat(fname, &sbuf) == 0)
                        {
                                mode = dos_mode(conn, fname, &sbuf);
                                size = sbuf.st_size;
@@ -920,7 +986,7 @@ int reply_getatr(connection_struct * conn, char *inbuf, char *outbuf,
                put_dos_date3(outbuf, smb_vwv1, mtime & ~1);
        else
                put_dos_date3(outbuf, smb_vwv1, mtime);
-       SIVAL(outbuf, smb_vwv3, (uint32) size);
+       SIVAL(outbuf, smb_vwv3, (uint32)size);
 
        if (Protocol >= PROTOCOL_NT1)
        {
@@ -934,7 +1000,7 @@ int reply_getatr(connection_struct * conn, char *inbuf, char *outbuf,
 
        DEBUG(3,
              ("getatr name=%s mode=%d size=%d\n", fname, mode,
-              (uint32) size));
+              (uint32)size));
 
        return (outsize);
 }
@@ -955,16 +1021,12 @@ int reply_setatr(connection_struct * conn, char *inbuf, char *outbuf,
        BOOL bad_path = False;
 
        pstrcpy(fname, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(fname, conn, 0, &bad_path, &st))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+       unix_convert(fname, conn, 0, &bad_path, &st);
 
        mode = SVAL(inbuf, smb_vwv0);
        mtime = make_unix_date3(inbuf + smb_vwv1);
 
-       if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname, NULL))
+       if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, fname, NULL))
                mode |= aDIR;
        if (check_name(fname, conn))
                ok = (file_chmod(conn, fname, mode, NULL) == 0);
@@ -999,7 +1061,7 @@ int reply_dskattr(connection_struct * conn, char *inbuf, char *outbuf,
        int outsize = 0;
        SMB_BIG_UINT dfree, dsize, bsize;
 
-       conn->vfs_ops.disk_free(".", &bsize, &dfree, &dsize);
+       conn->vfs_ops.disk_free(".", True, &bsize, &dfree, &dsize);
 
        outsize = set_message(outbuf, 5, 0, True);
 
@@ -1059,7 +1121,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
 
        /* dirtype &= ~aDIR; */
 
-       DEBUG(5, ("path=%s status_len=%d\n", path, status_len));
+       DEBUG(5, ("reply_search: path=%s status_len=%d\n", path, status_len));
 
 
        if (status_len == 0)
@@ -1068,12 +1130,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
 
                pstrcpy(directory, smb_buf(inbuf) + 1);
                pstrcpy(dir2, smb_buf(inbuf) + 1);
-               if (!unix_dfs_convert(directory, conn, 0, &bad_path, NULL))
-               {
-                       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-                       return (ERROR
-                               (0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-               }
+               unix_convert(directory, conn, 0, &bad_path, NULL);
                unix_format(dir2);
 
                if (!check_name(directory, conn))
@@ -1099,7 +1156,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
 
                if (strlen(directory) == 0)
                        pstrcpy(directory, "./");
-               memset(status, 0,  21);
+               memset((char *)status, '\0', 21);
                CVAL(status, 0) = dirtype;
        }
        else
@@ -1138,7 +1195,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
                p = mask;
                while (*p)
                {
-                       if ((skip = skip_multibyte_char(*p)) != 0)
+                       if ((skip = get_character_len(*p)) != 0)
                        {
                                p += skip;
                        }
@@ -1176,8 +1233,9 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
                if (status_len == 0)
                {
                        dptr_num =
-                               dptr_create(conn, directory, expect_close,
-                                           SVAL(inbuf, smb_pid));
+                               dptr_create(conn, directory, True,
+                                           expect_close, SVAL(inbuf,
+                                                              smb_pid));
                        if (dptr_num < 0)
                        {
                                if (dptr_num == -2)
@@ -1241,7 +1299,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
                                        p += DIR_STRUCT_SIZE;
                                }
                        }
-               }
+               }               /* if (ok ) */
        }
 
 
@@ -1251,6 +1309,7 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
        {
                CVAL(outbuf, smb_rcls) = ERRDOS;
                SSVAL(outbuf, smb_err, ERRnofiles);
+               dptr_close(&dptr_num);
        }
 
        /* If we were called as SMBffirst with smb_search_id == NULL
@@ -1262,12 +1321,12 @@ int reply_search(connection_struct * conn, char *inbuf, char *outbuf,
                CVAL(outbuf, smb_rcls) = ERRDOS;
                SSVAL(outbuf, smb_err, ERRnofiles);
                /* Also close the dptr - we know it's gone */
-               dptr_close(dptr_num);
+               dptr_close(&dptr_num);
        }
 
        /* If we were called as SMBfunique, then we can close the dirptr now ! */
        if (dptr_num >= 0 && CVAL(inbuf, smb_com) == SMBfunique)
-               dptr_close(dptr_num);
+               dptr_close(&dptr_num);
 
        SSVAL(outbuf, smb_vwv0, numentries);
        SSVAL(outbuf, smb_vwv1, 3 + numentries * DIR_STRUCT_SIZE);
@@ -1305,7 +1364,7 @@ int reply_fclose(connection_struct * conn, char *inbuf, char *outbuf,
        int status_len;
        char *path;
        char status[21];
-       int dptr_num = -1;
+       int dptr_num = -2;
 
        outsize = set_message(outbuf, 1, 0, True);
        path = smb_buf(inbuf) + 1;
@@ -1320,7 +1379,7 @@ int reply_fclose(connection_struct * conn, char *inbuf, char *outbuf,
        if (dptr_fetch(status + 12, &dptr_num))
        {
                /*  Close the dptr - we know it's gone */
-               dptr_close(dptr_num);
+               dptr_close(&dptr_num);
        }
 
        SSVAL(outbuf, smb_vwv0, 0);
@@ -1354,11 +1413,10 @@ int reply_open(connection_struct * conn, char *inbuf, char *outbuf,
        share_mode = SVAL(inbuf, smb_vwv0);
 
        pstrcpy(fname, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       unix_convert(fname, conn, 0, &bad_path, NULL);
 
        fsp = file_new();
        if (!fsp)
@@ -1375,7 +1433,7 @@ int reply_open(connection_struct * conn, char *inbuf, char *outbuf,
                return (UNIXERROR(ERRDOS, ERRnoaccess));
        }
 
-       unixmode = unix_mode(conn, aARCH);
+       unixmode = unix_mode(conn, aARCH, fname);
 
        open_file_shared(fsp, conn, fname, share_mode,
                         (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN),
@@ -1416,7 +1474,7 @@ int reply_open(connection_struct * conn, char *inbuf, char *outbuf,
                put_dos_date3(outbuf, smb_vwv2, mtime & ~1);
        else
                put_dos_date3(outbuf, smb_vwv2, mtime);
-       SIVAL(outbuf, smb_vwv4, (uint32) size);
+       SIVAL(outbuf, smb_vwv4, (uint32)size);
        SSVAL(outbuf, smb_vwv6, rmode);
 
        if (oplock_request && lp_fake_oplocks(SNUM(conn)))
@@ -1424,7 +1482,7 @@ int reply_open(connection_struct * conn, char *inbuf, char *outbuf,
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        }
 
-       if (fsp->granted_oplock)
+       if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        return (outsize);
 }
@@ -1459,21 +1517,17 @@ int reply_open_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        files_struct *fsp;
 
        /* If it's an IPC, pass off the pipe handler. */
-       if (IS_IPC(conn) && lp_nt_pipe_support()
-           && lp_security() != SEC_SHARE)
-       {
+       if (IS_IPC(conn) && lp_nt_pipe_support())
                return reply_open_pipe_and_X(conn, inbuf, outbuf, length,
                                             bufsize);
-       }
 
        /* XXXX we need to handle passed times, sattr and flags */
 
        pstrcpy(fname, smb_buf(inbuf));
-       if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       unix_convert(fname, conn, 0, &bad_path, NULL);
 
        fsp = file_new();
        if (!fsp)
@@ -1490,7 +1544,7 @@ int reply_open_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                return (UNIXERROR(ERRDOS, ERRnoaccess));
        }
 
-       unixmode = unix_mode(conn, smb_attr | aARCH);
+       unixmode = unix_mode(conn, smb_attr | aARCH, fname);
 
        open_file_shared(fsp, conn, fname, smb_mode, smb_ofun, unixmode,
                         oplock_request, &rmode, &smb_action);
@@ -1531,7 +1585,7 @@ int reply_open_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                smb_action |= EXTENDED_OPLOCK_GRANTED;
        }
 
-       if (ex_oplock_request && fsp->granted_oplock)
+       if (ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
        {
                smb_action |= EXTENDED_OPLOCK_GRANTED;
        }
@@ -1546,7 +1600,7 @@ int reply_open_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        }
 
-       if (core_oplock_request && fsp->granted_oplock)
+       if (core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
        {
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        }
@@ -1558,7 +1612,7 @@ int reply_open_and_X(connection_struct * conn, char *inbuf, char *outbuf,
                put_dos_date3(outbuf, smb_vwv4, mtime & ~1);
        else
                put_dos_date3(outbuf, smb_vwv4, mtime);
-       SIVAL(outbuf, smb_vwv6, (uint32) size);
+       SIVAL(outbuf, smb_vwv6, (uint32)size);
        SSVAL(outbuf, smb_vwv8, rmode);
        SSVAL(outbuf, smb_vwv11, smb_action);
 
@@ -1622,11 +1676,10 @@ int reply_mknew(connection_struct * conn, char *inbuf, char *outbuf,
 
        createmode = SVAL(inbuf, smb_vwv0);
        pstrcpy(fname, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       unix_convert(fname, conn, 0, &bad_path, NULL);
 
        if (createmode & aVOLID)
        {
@@ -1635,7 +1688,7 @@ int reply_mknew(connection_struct * conn, char *inbuf, char *outbuf,
                       fname));
        }
 
-       unixmode = unix_mode(conn, createmode);
+       unixmode = unix_mode(conn, createmode, fname);
 
        fsp = file_new();
        if (!fsp)
@@ -1655,12 +1708,12 @@ int reply_mknew(connection_struct * conn, char *inbuf, char *outbuf,
        if (com == SMBmknew)
        {
                /* We should fail if file exists. */
-               ofun = 0x10;
+               ofun = FILE_CREATE_IF_NOT_EXIST;
        }
        else
        {
                /* SMBcreate - Create if file doesn't exist, truncate if it does. */
-               ofun = 0x12;
+               ofun = FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_TRUNCATE;
        }
 
        /* Open file in dos compatibility share mode. */
@@ -1688,7 +1741,7 @@ int reply_mknew(connection_struct * conn, char *inbuf, char *outbuf,
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        }
 
-       if (fsp->granted_oplock)
+       if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
 
        DEBUG(2, ("new file %s\n", fname));
@@ -1717,13 +1770,12 @@ int reply_ctemp(connection_struct * conn, char *inbuf, char *outbuf,
        createmode = SVAL(inbuf, smb_vwv0);
        pstrcpy(fname, smb_buf(inbuf) + 1);
        pstrcat(fname, "/TMXXXXXX");
-       if (!unix_dfs_convert(fname, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
 
-       unixmode = unix_mode(conn, createmode);
+       RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+       unix_convert(fname, conn, 0, &bad_path, NULL);
+
+       unixmode = unix_mode(conn, createmode, fname);
 
        fsp = file_new();
        if (fsp)
@@ -1740,7 +1792,7 @@ int reply_ctemp(connection_struct * conn, char *inbuf, char *outbuf,
                return (UNIXERROR(ERRDOS, ERRnoaccess));
        }
 
-       pstrcpy(fname2, (char *)mktemp(fname));
+       pstrcpy(fname2, (char *)smbd_mktemp(fname));
 
        /* Open file in dos compatibility share mode. */
        /* We should fail if file exists. */
@@ -1771,7 +1823,7 @@ int reply_ctemp(connection_struct * conn, char *inbuf, char *outbuf,
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
        }
 
-       if (fsp->granted_oplock)
+       if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
                CVAL(outbuf, smb_flg) |= CORE_OPLOCK_GRANTED;
 
        DEBUG(2, ("created temp file %s\n", fname2));
@@ -1811,7 +1863,7 @@ static BOOL can_delete(char *fname, connection_struct * conn, int dirtype)
 }
 
 /****************************************************************************
 reply to a unlink
Reply to a unlink
 ****************************************************************************/
 int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
                 int dum_size, int dum_buffsize)
@@ -1827,6 +1879,7 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
        BOOL has_wild;
        BOOL exists = False;
        BOOL bad_path = False;
+       BOOL rc = True;
 
        *directory = *mask = 0;
 
@@ -1834,13 +1887,11 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
 
        pstrcpy(name, smb_buf(inbuf) + 1);
 
+       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+
        DEBUG(3, ("reply_unlink : %s\n", name));
 
-       if (!unix_dfs_convert(name, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+       rc = unix_convert(name, conn, 0, &bad_path, NULL);
 
        p = strrchr(name, '/');
        if (!p)
@@ -1855,7 +1906,16 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
                pstrcpy(mask, p + 1);
        }
 
-       if (is_mangled(mask))
+       /*
+        * We should only check the mangled cache
+        * here if unix_convert failed. This means
+        * that the path in 'mask' doesn't exist
+        * on the file system and so we need to look
+        * for a possible mangle. This patch from
+        * Tine Smukavec <valentin.smukavec@hermes.si>.
+        */
+
+       if (!rc && is_mangled(mask))
                check_mangled_cache(mask);
 
        has_wild = strchr(mask, '*') || strchr(mask, '?');
@@ -1864,14 +1924,11 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
        {
                pstrcat(directory, "/");
                pstrcat(directory, mask);
-               if (can_delete(directory, conn, dirtype) &&
-                   !conn->vfs_ops.unlink(dos_to_unix(directory, False)))
+               if (can_delete(directory, conn, dirtype)
+                   && !dos_unlink(directory))
                        count++;
                if (!count)
-                       exists =
-                               vfs_file_exist(conn,
-                                              dos_to_unix(directory, False),
-                                              NULL);
+                       exists = vfs_file_exist(conn, directory, NULL);
        }
        else
        {
@@ -1907,9 +1964,9 @@ int reply_unlink(connection_struct * conn, char *inbuf, char *outbuf,
                                         directory, dname);
                                if (!can_delete(fname, conn, dirtype))
                                        continue;
-                               if (!conn->vfs_ops.
-                                   unlink(dos_to_unix(fname, False)))
-                                               count++;
+                               if (!conn->
+                                   vfs_ops.unlink(dos_to_unix(fname, False)))
+                                       count++;
                                DEBUG(3,
                                      ("reply_unlink : doing unlink on %s\n",
                                       fname));
@@ -1968,14 +2025,52 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf,
 
        fsp = file_fsp(inbuf, smb_vwv0);
 
+       if (!FNUM_OK(fsp, conn) || !fsp->can_read)
+       {
+               /*
+                * fsp could be NULL here so use the value from the packet. JRA.
+                */
+               DEBUG(3,
+                     ("fnum %d not open in readbraw - cache prime?\n",
+                      (int)SVAL(inbuf, smb_vwv0)));
+               _smb_setlen(header, 0);
+               transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
+               return (-1);
+       }
+
+       CHECK_FSP(fsp, conn);
+
+       flush_write_cache(fsp, READRAW_FLUSH);
+
        startpos = IVAL(inbuf, smb_vwv1);
-#ifdef LARGE_SMB_OFF_T
        if (CVAL(inbuf, smb_wct) == 10)
        {
                /*
                 * This is a large offset (64 bit) read.
                 */
+#ifdef LARGE_SMB_OFF_T
+
                startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv8)) << 32);
+
+#else /* !LARGE_SMB_OFF_T */
+
+               /*
+                * Ensure we haven't been sent a >32 bit offset.
+                */
+
+               if (IVAL(inbuf, smb_vwv8) != 0)
+               {
+                       DEBUG(0,
+                             ("readbraw - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+                              (unsigned int)IVAL(inbuf, smb_vwv8)));
+                       _smb_setlen(header, 0);
+                       transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
+                       return (-1);
+               }
+
+#endif /* LARGE_SMB_OFF_T */
+
                if (startpos < 0)
                {
                        DEBUG(0,
@@ -1986,7 +2081,6 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf,
                        return (-1);
                }
        }
-#endif /* LARGE_SMB_OFF_T */
        maxcount = (SVAL(inbuf, smb_vwv3) & 0xFFFF);
        mincount = (SVAL(inbuf, smb_vwv4) & 0xFFFF);
 
@@ -1994,17 +2088,7 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf,
        maxcount = MIN(65535, maxcount);
        maxcount = MAX(mincount, maxcount);
 
-       if (!FNUM_OK(fsp, conn) || !fsp->can_read)
-       {
-               DEBUG(3,
-                     ("fnum %d not open in readbraw - cache prime?\n",
-                      fsp->fnum));
-               _smb_setlen(header, 0);
-               transfer_file(0, Client, (SMB_OFF_T) 0, header, 4, 0);
-               return (-1);
-       }
-
-       if (!is_locked(fsp, conn, maxcount, startpos, F_RDLCK))
+       if (!is_locked(fsp, conn, maxcount, startpos, READ_LOCK))
        {
                SMB_OFF_T size = fsp->size;
                SMB_OFF_T sizeneeded = startpos + maxcount;
@@ -2026,7 +2110,8 @@ int reply_readbraw(connection_struct * conn, char *inbuf, char *outbuf,
                nread = 0;
 
        DEBUG(3, ("readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
-                 fsp->fnum, (double)startpos, maxcount, mincount, nread));
+                 fsp->fnum, (double)startpos,
+                 (int)maxcount, (int)mincount, (int)nread));
 
 #if UNSAFE_READRAW
        {
@@ -2111,8 +2196,15 @@ int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf,
        numtoread = MIN(BUFFER_SIZE - outsize, numtoread);
        data = smb_buf(outbuf) + 3;
 
+       /*
+        * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
+        * protocol request that predates the read/write lock concept. 
+        * Thus instead of asking for a read lock here we need to ask
+        * for a write lock. JRA.
+        */
+
        if (!do_lock
-           (fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode))
+           (fsp, conn, numtoread, startpos, WRITE_LOCK, &eclass, &ecode))
        {
                if ((ecode == ERRlock) && lp_blocking_locks(SNUM(conn)))
                {
@@ -2138,7 +2230,7 @@ int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf,
        SSVAL(smb_buf(outbuf), 1, nread);
 
        DEBUG(3, ("lockread fnum=%d num=%d nread=%d\n",
-                 fsp->fnum, numtoread, nread));
+                 fsp->fnum, (int)numtoread, (int)nread));
 
        return (outsize);
 }
@@ -2147,8 +2239,9 @@ int reply_lockread(connection_struct * conn, char *inbuf, char *outbuf,
 /****************************************************************************
   reply to a read
 ****************************************************************************/
-int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
-              int dum_size, int dum_buffsize)
+
+int reply_read(connection_struct * conn, char *inbuf, char *outbuf, int size,
+              int dum_buffsize)
 {
        size_t numtoread;
        ssize_t nread = 0;
@@ -2168,13 +2261,11 @@ int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
        numtoread = MIN(BUFFER_SIZE - outsize, numtoread);
        data = smb_buf(outbuf) + 3;
 
-       if (is_locked(fsp, conn, numtoread, startpos, F_RDLCK))
+       if (is_locked(fsp, conn, numtoread, startpos, READ_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
        if (numtoread > 0)
-       {
                nread = read_file(fsp, data, startpos, numtoread);
-       }
 
        if (nread < 0)
                return (UNIXERROR(ERRDOS, ERRnoaccess));
@@ -2186,7 +2277,7 @@ int reply_read(connection_struct * conn, char *inbuf, char *outbuf,
        SSVAL(smb_buf(outbuf), 1, nread);
 
        DEBUG(3, ("read fnum=%d num=%d nread=%d\n",
-                 fsp->fnum, numtoread, nread));
+                 fsp->fnum, (int)numtoread, (int)nread));
 
        return (outsize);
 }
@@ -2216,17 +2307,33 @@ int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        set_message(outbuf, 12, 0, True);
        data = smb_buf(outbuf);
 
-#ifdef LARGE_SMB_OFF_T
        if (CVAL(inbuf, smb_wct) == 12)
        {
+#ifdef LARGE_SMB_OFF_T
                /*
                 * This is a large offset (64 bit) read.
                 */
                startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv10)) << 32);
-       }
+
+#else /* !LARGE_SMB_OFF_T */
+
+               /*
+                * Ensure we haven't been sent a >32 bit offset.
+                */
+
+               if (IVAL(inbuf, smb_vwv10) != 0)
+               {
+                       DEBUG(0,
+                             ("reply_read_and_X - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+                              (unsigned int)IVAL(inbuf, smb_vwv10)));
+                       return (ERROR(ERRDOS, ERRbadaccess));
+               }
 #endif /* LARGE_SMB_OFF_T */
 
-       if (is_locked(fsp, conn, smb_maxcnt, startpos, F_RDLCK))
+       }
+
+       if (is_locked(fsp, conn, smb_maxcnt, startpos, READ_LOCK))
                return (ERROR(ERRDOS, ERRlock));
        nread = read_file(fsp, data, startpos, smb_maxcnt);
 
@@ -2238,7 +2345,7 @@ int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        SSVAL(smb_buf(outbuf), -2, nread);
 
        DEBUG(3, ("readX fnum=%d min=%d max=%d nread=%d\n",
-                 fsp->fnum, smb_mincnt, smb_maxcnt, nread));
+                 fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread));
 
        return chain_reply(inbuf, outbuf, length, bufsize);
 }
@@ -2247,7 +2354,7 @@ int reply_read_and_X(connection_struct * conn, char *inbuf, char *outbuf,
   reply to a writebraw (core+ or LANMAN1.0 protocol)
 ****************************************************************************/
 int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
-                   int dum_size, int dum_buffsize)
+                   int size, int dum_buffsize)
 {
        ssize_t nwritten = 0;
        ssize_t total_written = 0;
@@ -2284,23 +2391,15 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
        CVAL(inbuf, smb_com) = SMBwritec;
        CVAL(outbuf, smb_com) = SMBwritec;
 
-       if (is_locked(fsp, conn, tcount, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-       {
-               DEBUG(0,
-                     ("couldn't seek to %.0f in writebraw\n",
-                      (double)startpos));
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
-       }
-
        if (numtowrite > 0)
-               nwritten = write_file(fsp, data, numtowrite);
+               nwritten = write_file(fsp, data, startpos, numtowrite);
 
        DEBUG(3, ("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
-                 fsp->fnum, (double)startpos, numtowrite, nwritten,
-                 write_through));
+                 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten,
+                 (int)write_through));
 
        if (nwritten < numtowrite)
                return (UNIXERROR(ERRHRD, ERRdiskfull));
@@ -2329,7 +2428,7 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
        if (tcount > nwritten + numtowrite)
        {
                DEBUG(3, ("Client overestimated the write %d %d %d\n",
-                         tcount, nwritten, numtowrite));
+                         (int)tcount, (int)nwritten, (int)numtowrite));
        }
 
        nwritten = vfs_transfer_file(Client, NULL, -1, fsp,
@@ -2350,10 +2449,11 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
 
        if ((lp_syncalways(SNUM(conn)) || write_through) &&
            lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        DEBUG(3, ("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
-                 fsp->fnum, (double)startpos, numtowrite, total_written));
+                 fsp->fnum, (double)startpos, (int)numtowrite,
+                 (int)total_written));
 
        /* we won't return a status if write through is not selected - this 
           follows what WfWg does */
@@ -2367,7 +2467,7 @@ int reply_writebraw(connection_struct * conn, char *inbuf, char *outbuf,
   reply to a writeunlock (core+)
 ****************************************************************************/
 int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
-                     int dum_size, int dum_buffsize)
+                     int size, int dum_buffsize)
 {
        ssize_t nwritten = -1;
        size_t numtowrite;
@@ -2386,22 +2486,19 @@ int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
        startpos = IVAL(inbuf, smb_vwv2);
        data = smb_buf(inbuf) + 3;
 
-       if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
-
        /* The special X/Open SMB protocol handling of
           zero length writes is *NOT* done for
           this call */
        if (numtowrite == 0)
                nwritten = 0;
        else
-               nwritten = write_file(fsp, data, numtowrite);
+               nwritten = write_file(fsp, data, startpos, numtowrite);
 
-       if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+       if (lp_syncalways(SNUM(conn)))
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
                return (UNIXERROR(ERRDOS, ERRnoaccess));
@@ -2414,7 +2511,7 @@ int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
        SSVAL(outbuf, smb_vwv0, nwritten);
 
        DEBUG(3, ("writeunlock fnum=%d num=%d wrote=%d\n",
-                 fsp->fnum, numtowrite, nwritten));
+                 fsp->fnum, (int)numtowrite, (int)nwritten));
 
        return (outsize);
 }
@@ -2422,8 +2519,8 @@ int reply_writeunlock(connection_struct * conn, char *inbuf, char *outbuf,
 /****************************************************************************
   reply to a write
 ****************************************************************************/
-int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize)
+int reply_write(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize)
 {
        size_t numtowrite;
        ssize_t nwritten = -1;
@@ -2434,8 +2531,7 @@ int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
 
        /* If it's an IPC, pass off the pipe handler. */
        if (IS_IPC(conn))
-               return reply_pipe_write(inbuf, outbuf, dum_size,
-                                       dum_buffsize);
+               return reply_pipe_write(inbuf, outbuf, size, dum_buffsize);
 
        CHECK_FSP(fsp, conn);
        CHECK_WRITE(fsp);
@@ -2445,22 +2541,24 @@ int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
        startpos = IVAL(inbuf, smb_vwv2);
        data = smb_buf(inbuf) + 3;
 
-       if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
-
        /* X/Open SMB protocol says that if smb_vwv1 is
           zero then the file size should be extended or
           truncated to the size given in smb_vwv[2-3] */
        if (numtowrite == 0)
-               nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T) startpos);
+       {
+               if (
+                   (nwritten =
+                    set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T) startpos)) >= 0)  /* tpot vfs */
+                       set_filelen_write_cache(fsp, startpos);
+       }
        else
-               nwritten = write_file(fsp, data, numtowrite);
+               nwritten = write_file(fsp, data, startpos, numtowrite);
 
-       if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+       if (lp_syncalways(SNUM(conn)))
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
                return (UNIXERROR(ERRDOS, ERRnoaccess));
@@ -2476,7 +2574,7 @@ int reply_write(connection_struct * conn, char *inbuf, char *outbuf,
        }
 
        DEBUG(3, ("write fnum=%d num=%d wrote=%d\n",
-                 fsp->fnum, numtowrite, nwritten));
+                 fsp->fnum, (int)numtowrite, (int)nwritten));
 
        return (outsize);
 }
@@ -2506,22 +2604,34 @@ int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
 
        data = smb_base(inbuf) + smb_doff;
 
-#ifdef LARGE_SMB_OFF_T
        if (CVAL(inbuf, smb_wct) == 14)
        {
+#ifdef LARGE_SMB_OFF_T
                /*
                 * This is a large offset (64 bit) write.
                 */
                startpos |= (((SMB_OFF_T) IVAL(inbuf, smb_vwv12)) << 32);
-       }
+
+#else /* !LARGE_SMB_OFF_T */
+
+               /*
+                * Ensure we haven't been sent a >32 bit offset.
+                */
+
+               if (IVAL(inbuf, smb_vwv12) != 0)
+               {
+                       DEBUG(0,
+                             ("reply_write_and_X - large offset (%x << 32) used and we don't support \
+64 bit offsets.\n",
+                              (unsigned int)IVAL(inbuf, smb_vwv12)));
+                       return (ERROR(ERRDOS, ERRbadaccess));
+               }
 #endif /* LARGE_SMB_OFF_T */
+       }
 
-       if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
-
        /* X/Open SMB protocol says that, unlike SMBwrite
           if the length is zero then NO truncation is
           done, just a write of zero. To truncate a file,
@@ -2529,7 +2639,7 @@ int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        if (numtowrite == 0)
                nwritten = 0;
        else
-               nwritten = write_file(fsp, data, numtowrite);
+               nwritten = write_file(fsp, data, startpos, numtowrite);
 
        if (((nwritten == 0) && (numtowrite != 0)) || (nwritten < 0))
                return (UNIXERROR(ERRDOS, ERRnoaccess));
@@ -2545,11 +2655,10 @@ int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
        }
 
        DEBUG(3, ("writeX fnum=%d num=%d wrote=%d\n",
-                 fsp->fnum, numtowrite, nwritten));
+                 fsp->fnum, (int)numtowrite, (int)nwritten));
 
-       if ((lp_syncalways(SNUM(conn)) || write_through) &&
-           lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+       if (lp_syncalways(SNUM(conn)) || write_through)
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        return chain_reply(inbuf, outbuf, length, bufsize);
 }
@@ -2558,8 +2667,9 @@ int reply_write_and_X(connection_struct * conn, char *inbuf, char *outbuf,
 /****************************************************************************
   reply to a lseek
 ****************************************************************************/
-int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize)
+
+int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize)
 {
        SMB_OFF_T startpos;
        SMB_OFF_T res = -1;
@@ -2570,10 +2680,12 @@ int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
        CHECK_FSP(fsp, conn);
        CHECK_ERROR(fsp);
 
+       flush_write_cache(fsp, SEEK_FLUSH);
+
        mode = SVAL(inbuf, smb_vwv1) & 3;
-       startpos = IVAL(inbuf, smb_vwv2);
+       startpos = IVALS(inbuf, smb_vwv2);
 
-       switch (mode & 3)
+       switch (mode)
        {
                case 0:
                        umode = SEEK_SET;
@@ -2591,15 +2703,61 @@ int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
 
        if ((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd, startpos, umode)) ==
            -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
+       {
+               /*
+                * Check for the special case where a seek before the start
+                * of the file sets the offset to zero. Added in the CIFS spec,
+                * section 4.2.7.
+                */
+
+               if (errno == EINVAL)
+               {
+                       SMB_OFF_T current_pos = startpos;
+
+                       if (umode == SEEK_CUR)
+                       {
+
+                               if (
+                                   (current_pos =
+                                    conn->vfs_ops.lseek(fsp->fd_ptr->fd, 0,
+                                                        SEEK_CUR)) == -1)
+                                       return (UNIXERROR
+                                               (ERRDOS, ERRnoaccess));
+
+                               current_pos += startpos;
+
+                       }
+                       else if (umode == SEEK_END)
+                       {
+
+                               SMB_STRUCT_STAT sbuf;
+
+                               if (conn->
+                                   vfs_ops.fstat(fsp->fd_ptr->fd,
+                                                 &sbuf) == -1)
+                                       return (UNIXERROR
+                                               (ERRDOS, ERRnoaccess));
+
+                               current_pos += sbuf.st_size;
+                       }
+
+                       if (current_pos < 0)
+                               res =
+                                       conn->vfs_ops.lseek(fsp->fd_ptr->fd,
+                                                           0, SEEK_SET);
+               }
+
+               if (res == -1)
+                       return (UNIXERROR(ERRDOS, ERRnoaccess));
+       }
 
        fsp->pos = res;
 
        outsize = set_message(outbuf, 2, 0, True);
-       SIVALS(outbuf, smb_vwv0, res);
+       SIVAL(outbuf, smb_vwv0, res);
 
-       DEBUG(3, ("lseek fnum=%d ofs=%.0f mode=%d\n",
-                 fsp->fnum, (double)startpos, mode));
+       DEBUG(3, ("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
+                 fsp->fnum, (double)startpos, (double)res, mode));
 
        return (outsize);
 }
@@ -2607,8 +2765,9 @@ int reply_lseek(connection_struct * conn, char *inbuf, char *outbuf,
 /****************************************************************************
   reply to a flush
 ****************************************************************************/
-int reply_flush(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize)
+
+int reply_flush(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize)
 {
        int outsize = set_message(outbuf, 0, 0, True);
        files_struct *fsp = file_fsp(inbuf, smb_vwv0);
@@ -2625,7 +2784,7 @@ int reply_flush(connection_struct * conn, char *inbuf, char *outbuf,
        }
        else
        {
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
        }
 
        DEBUG(3, ("flush\n"));
@@ -2649,8 +2808,8 @@ int reply_exit(connection_struct * conn,
 /****************************************************************************
  Reply to a close - has to deal with closing a directory opened by NT SMB's.
 ****************************************************************************/
-int reply_close(connection_struct * conn,
-               char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
+int reply_close(connection_struct * conn, char *inbuf, char *outbuf, int size,
+               int dum_buffsize)
 {
        int outsize = 0;
        time_t mtime;
@@ -2661,9 +2820,7 @@ int reply_close(connection_struct * conn,
 
        /* If it's an IPC, pass off to the pipe handler. */
        if (IS_IPC(conn))
-       {
                return reply_pipe_close(conn, inbuf, outbuf);
-       }
 
        fsp = file_fsp(inbuf, smb_vwv0);
 
@@ -2680,20 +2837,24 @@ int reply_close(connection_struct * conn,
                err = fsp->wbmpx_ptr->wr_error;
        }
 
-       if (fsp->is_directory)
+       if (fsp->is_directory || fsp->stat_open)
        {
                /*
-                * Special case - close NT SMB directory
+                * Special case - close NT SMB directory or stat file
                 * handle.
                 */
-               DEBUG(3, ("close directory fnum=%d\n", fsp->fnum));
-               close_directory(fsp);
+               DEBUG(3,
+                     ("close %s fnum=%d\n",
+                      fsp->is_directory ? "directory" : "stat file open",
+                      fsp->fnum));
+               close_file(fsp, True);
        }
        else
        {
                /*
                 * Close ordinary file.
                 */
+               int close_err;
 
                /*
                 * If there was a modify time outstanding,
@@ -2712,9 +2873,20 @@ int reply_close(connection_struct * conn,
                set_filetime(conn, fsp->fsp_name, mtime);
 
                DEBUG(3, ("close fd=%d fnum=%d (numopen=%d)\n",
-                         fsp->fd_ptr->fd, fsp->fnum, conn->num_files_open));
+                         fsp->fd_ptr ? fsp->fd_ptr->fd : -1, fsp->fnum,
+                         conn->num_files_open));
 
-               close_file(fsp, True);
+               /*
+                * close_file() returns the unix errno if an error
+                * was detected on close - normally this is due to
+                * a disk full error. If not then it was probably an I/O error.
+                */
+
+               if ((close_err = close_file(fsp, True)) != 0)
+               {
+                       errno = close_err;
+                       return (UNIXERROR(ERRHRD, ERRgeneral));
+               }
        }
 
        /* We have a cached error */
@@ -2729,12 +2901,12 @@ int reply_close(connection_struct * conn,
   reply to a writeclose (Core+ protocol)
 ****************************************************************************/
 int reply_writeclose(connection_struct * conn,
-                    char *inbuf, char *outbuf, int dum_size,
-                    int dum_buffsize)
+                    char *inbuf, char *outbuf, int size, int dum_buffsize)
 {
        size_t numtowrite;
        ssize_t nwritten = -1;
        int outsize = 0;
+       int close_err = 0;
        SMB_OFF_T startpos;
        char *data;
        time_t mtime;
@@ -2749,24 +2921,28 @@ int reply_writeclose(connection_struct * conn,
        mtime = make_unix_date3(inbuf + smb_vwv4);
        data = smb_buf(inbuf) + 1;
 
-       if (is_locked(fsp, conn, numtowrite, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, numtowrite, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
-
-       nwritten = write_file(fsp, data, numtowrite);
+       nwritten = write_file(fsp, data, startpos, numtowrite);
 
        set_filetime(conn, fsp->fsp_name, mtime);
 
-       close_file(fsp, True);
+       close_err = close_file(fsp, True);
 
        DEBUG(3, ("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
-                 fsp->fnum, numtowrite, nwritten, conn->num_files_open));
+                 fsp->fnum, (int)numtowrite, (int)nwritten,
+                 conn->num_files_open));
 
        if (nwritten <= 0)
                return (UNIXERROR(ERRDOS, ERRnoaccess));
 
+       if (close_err != 0)
+       {
+               errno = close_err;
+               return (UNIXERROR(ERRHRD, ERRgeneral));
+       }
+
        outsize = set_message(outbuf, 1, 0, True);
 
        SSVAL(outbuf, smb_vwv0, nwritten);
@@ -2795,7 +2971,7 @@ int reply_lock(connection_struct * conn,
        DEBUG(3, ("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
                  fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
 
-       if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode))
+       if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode))
        {
                if ((ecode == ERRlock) && lp_blocking_locks(SNUM(conn)))
                {
@@ -2818,7 +2994,7 @@ int reply_lock(connection_struct * conn,
   reply to a unlock
 ****************************************************************************/
 int reply_unlock(connection_struct * conn, char *inbuf, char *outbuf,
-                int dum_size, int dum_buffsize)
+                int size, int dum_buffsize)
 {
        int outsize = set_message(outbuf, 0, 0, True);
        SMB_OFF_T count, offset;
@@ -2901,6 +3077,8 @@ int reply_echo(connection_struct * conn,
 
        DEBUG(3, ("echo %d times\n", smb_reverb));
 
+       smb_echo_count++;
+
        return -1;
 }
 
@@ -2943,7 +3121,7 @@ int reply_printopen(connection_struct * conn,
        if (!fsp)
                return (ERROR(ERRSRV, ERRnofids));
 
-       pstrcpy(fname2, (char *)mktemp(fname));
+       pstrcpy(fname2, (char *)smbd_mktemp(fname));
 
        if (!check_name(fname2, conn))
        {
@@ -2956,7 +3134,7 @@ int reply_printopen(connection_struct * conn,
                         SET_DENY_MODE(DENY_ALL) |
                         SET_OPEN_MODE(DOS_OPEN_WRONLY),
                         (FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_FAIL),
-                        unix_mode(conn, 0), 0, NULL, NULL);
+                        unix_mode(conn, 0, fname2), 0, NULL, NULL);
 
        if (!fsp->open)
        {
@@ -2986,6 +3164,7 @@ int reply_printclose(connection_struct * conn,
 {
        int outsize = set_message(outbuf, 0, 0, True);
        files_struct *fsp = file_fsp(inbuf, smb_vwv0);
+       int close_err = 0;
 
        CHECK_FSP(fsp, conn);
        CHECK_ERROR(fsp);
@@ -2995,7 +3174,13 @@ int reply_printclose(connection_struct * conn,
 
        DEBUG(3, ("printclose fd=%d fnum=%d\n", fsp->fd_ptr->fd, fsp->fnum));
 
-       close_file(fsp, True);
+       close_err = close_file(fsp, True);
+
+       if (close_err != 0)
+       {
+               errno = close_err;
+               return (UNIXERROR(ERRHRD, ERRgeneral));
+       }
 
        return (outsize);
 }
@@ -3012,7 +3197,9 @@ int reply_printqueue(connection_struct * conn,
        int max_count = SVAL(inbuf, smb_vwv0);
        int start_index = SVAL(inbuf, smb_vwv1);
        uint16 vuid = SVAL(inbuf, smb_uid);
-       VUSER_KEY;
+       vuser_key key;
+       key.pid = conn != NULL ? conn->smbd_pid : getpid();
+       key.vuid = vuid;
 
        /* we used to allow the client to get the cnum wrong, but that
           is really quite gross and only worked when there was only
@@ -3101,7 +3288,7 @@ int reply_printwrite(connection_struct * conn, char *inbuf, char *outbuf,
        numtowrite = SVAL(smb_buf(inbuf), 1);
        data = smb_buf(inbuf) + 3;
 
-       if (write_file(fsp, data, numtowrite) != numtowrite)
+       if (write_file(fsp, data, -1, numtowrite) != numtowrite)
                return (UNIXERROR(ERRDOS, ERRnoaccess));
 
        DEBUG(3, ("printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite));
@@ -3121,15 +3308,11 @@ int reply_mkdir(connection_struct * conn, char *inbuf, char *outbuf,
        BOOL bad_path = False;
 
        pstrcpy(directory, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(directory, conn, 0, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+       unix_convert(directory, conn, 0, &bad_path, NULL);
 
        if (check_name(directory, conn))
                ret = conn->vfs_ops.mkdir(dos_to_unix(directory, False),
-                                         unix_mode(conn, aDIR));
+                                         unix_mode(conn, aDIR, directory));
 
        if (ret < 0)
        {
@@ -3156,7 +3339,7 @@ static BOOL recursive_rmdir(connection_struct * conn, char *directory)
 {
        char *dname = NULL;
        BOOL ret = False;
-       void *dirptr = OpenDir(conn, directory, False);
+       void *dirptr = OpenDir(NULL, directory, False);
 
        if (dirptr == NULL)
                return True;
@@ -3194,8 +3377,8 @@ static BOOL recursive_rmdir(connection_struct * conn, char *directory)
                                ret = True;
                                break;
                        }
-                       if (conn->vfs_ops.
-                           rmdir(dos_to_unix(fullname, False)) != 0)
+                       if (conn->
+                           vfs_ops.rmdir(dos_to_unix(fullname, False)) != 0)
                        {
                                ret = True;
                                break;
@@ -3213,129 +3396,136 @@ static BOOL recursive_rmdir(connection_struct * conn, char *directory)
 }
 
 /****************************************************************************
-  reply to a rmdir
+ The internals of the rmdir code - called elsewhere.
 ****************************************************************************/
-int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
-               int dum_size, int dum_buffsize)
+
+BOOL rmdir_internals(connection_struct * conn, char *directory)
 {
-       pstring directory;
-       int outsize = 0;
-       BOOL ok = False;
-       BOOL bad_path = False;
+       BOOL ok;
 
-       pstrcpy(directory, smb_buf(inbuf) + 1);
-       if (!unix_dfs_convert(directory, conn, NULL, &bad_path, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
-
-       if (check_name(directory, conn))
+       ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
+       if (!ok && ((errno == ENOTEMPTY) || (errno == EEXIST))
+           && lp_veto_files(SNUM(conn)))
        {
+               /* 
+                * Check to see if the only thing in this directory are
+                * vetoed files/directories. If so then delete them and
+                * retry. If we fail to delete any of them (and we *don't*
+                * do a recursive delete) then fail the rmdir.
+                */
+               BOOL all_veto_files = True;
+               char *dname;
+               void *dirptr = OpenDir(conn, directory, False);
 
-               dptr_closepath(directory, SVAL(inbuf, smb_pid));
-               ok =
-                       (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) ==
-                     0);
-               if (!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn)))
+               if (dirptr != NULL)
                {
-                       /* Check to see if the only thing in this directory are
-                          vetoed files/directories. If so then delete them and
-                          retry. If we fail to delete any of them (and we *don't*
-                          do a recursive delete) then fail the rmdir. */
-                       BOOL all_veto_files = True;
-                       char *dname;
-                       void *dirptr = OpenDir(conn, directory, False);
-
-                       if (dirptr != NULL)
+                       int dirpos = TellDir(dirptr);
+                       while ((dname = ReadDirName(dirptr)))
                        {
-                               int dirpos = TellDir(dirptr);
+                               if ((strcmp(dname, ".") == 0)
+                                   || (strcmp(dname, "..") == 0))
+                                       continue;
+                               if (!IS_VETO_PATH(conn, dname))
+                               {
+                                       all_veto_files = False;
+                                       break;
+                               }
+                       }
+                       if (all_veto_files)
+                       {
+                               SeekDir(dirptr, dirpos);
                                while ((dname = ReadDirName(dirptr)))
                                {
+                                       pstring fullname;
+                                       SMB_STRUCT_STAT st;
+
                                        if ((strcmp(dname, ".") == 0)
                                            || (strcmp(dname, "..") == 0))
                                                continue;
-                                       if (!IS_VETO_PATH(conn, dname))
+
+                                       /* Construct the full name. */
+                                       if (strlen(directory) +
+                                           strlen(dname) + 1 >=
+                                           sizeof(fullname))
                                        {
-                                               all_veto_files = False;
+                                               errno = ENOMEM;
                                                break;
                                        }
-                               }
-                               if (all_veto_files)
-                               {
-                                       SeekDir(dirptr, dirpos);
-                                       while ((dname = ReadDirName(dirptr)))
+                                       pstrcpy(fullname, directory);
+                                       pstrcat(fullname, "/");
+                                       pstrcat(fullname, dname);
+
+                                       if (conn->vfs_ops.lstat(dos_to_unix
+                                                               (fullname,
+                                                                False),
+                                                               &st) != 0)
+                                               break;
+                                       if (st.st_mode & S_IFDIR)
                                        {
-                                               pstring fullname;
-                                               SMB_STRUCT_STAT st;
-
-                                               if ((strcmp(dname, ".") == 0)
-                                                   || (strcmp(dname, "..") ==
-                                                       0))
-                                                       continue;
-
-                                               /* Construct the full name. */
-                                               if (strlen(directory) +
-                                                   strlen(dname) + 1 >=
-                                                   sizeof(fullname))
+                                               if (lp_recursive_veto_delete
+                                                   (SNUM(conn)))
                                                {
-                                                       errno = ENOMEM;
-                                                       break;
+                                                       if (recursive_rmdir
+                                                           (conn,
+                                                            fullname) != 0)
+                                                               break;
                                                }
-                                               pstrcpy(fullname, directory);
-                                               pstrcat(fullname, "/");
-                                               pstrcat(fullname, dname);
-
-                                               if (conn->vfs_ops.
-                                                   lstat(dos_to_unix
-                                                         (fullname, False),
-                                                         &st) != 0)
-                                                       break;
-                                               if (st.st_mode & S_IFDIR)
-                                               {
-                                                       if
-                                                               (lp_recursive_veto_delete
-                                                                (SNUM(conn)))
-                                                       {
-                                                               DEBUG(0,
-                                                                     ("ERROR: recursive_rmdir()\n"));
-                                                               if
-                                                                       (recursive_rmdir
-                                                                        (conn,
-                                                                         fullname)
-                                                                        != 0)
-                                                                       break;
-                                                       }
-                                                       if (conn->vfs_ops.
-                                                           rmdir(dos_to_unix
+                                               if (conn->
+                                                   vfs_ops.rmdir(dos_to_unix
                                                                  (fullname,
                                                                   False)) !=
-                                                           0)
-                                                               break;
-                                               }
-                                               else if (conn->vfs_ops.
-                                                        unlink(dos_to_unix
-                                                               (fullname,
-                                                                False)) != 0)
+                                                   0)
                                                        break;
                                        }
-                                       CloseDir(dirptr);
-                                       /* Retry the rmdir */
-                                       ok =
-                                               (conn->vfs_ops.
-                                             rmdir(dos_to_unix
-                                                   (directory, False)) == 0);
+                                       else if (conn->
+                                                vfs_ops.unlink(dos_to_unix
+                                                               (fullname,
+                                                                False)) != 0)
+                                               break;
                                }
-                               else
-                                       CloseDir(dirptr);
+                               CloseDir(dirptr);
+                               /* Retry the rmdir */
+                               ok =
+                                       (conn->
+                                     vfs_ops.rmdir(dos_to_unix
+                                                   (directory, False)) == 0);
                        }
                        else
-                               errno = ENOTEMPTY;
+                               CloseDir(dirptr);
                }
+               else
+                       errno = ENOTEMPTY;
+       }
+
+       if (!ok)
+               DEBUG(3,
+                     ("rmdir_internals: couldn't remove directory %s : %s\n",
+                      directory, strerror(errno)));
+
+       return ok;
+}
 
-               if (!ok)
-                       DEBUG(3, ("couldn't remove directory %s : %s\n",
-                                 directory, strerror(errno)));
+/****************************************************************************
+ Reply to a rmdir.
+****************************************************************************/
+
+int reply_rmdir(connection_struct * conn, char *inbuf, char *outbuf,
+               int dum_size, int dum_buffsize)
+{
+       pstring directory;
+       int outsize = 0;
+       BOOL ok = False;
+       BOOL bad_path = False;
+
+       pstrcpy(directory, smb_buf(inbuf) + 1);
+
+       RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+               unix_convert(directory, conn, NULL, &bad_path, NULL);
+
+       if (check_name(directory, conn))
+       {
+               dptr_closepath(directory, SVAL(inbuf, smb_pid));
+               ok = rmdir_internals(conn, directory);
        }
 
        if (!ok)
@@ -3474,24 +3664,17 @@ int rename_internals(connection_struct * conn,
        int count = 0;
        int error = ERRnoaccess;
        BOOL exists = False;
+       BOOL rc = True;
+       pstring zdirectory;
 
        *directory = *mask = 0;
 
-       if (!unix_dfs_convert(name, conn, 0, &bad_path1, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
-       if (!unix_dfs_convert
-           (newname, conn, newname_last_component, &bad_path2, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+       rc = unix_convert(name, conn, 0, &bad_path1, NULL);
+       unix_convert(newname, conn, newname_last_component, &bad_path2, NULL);
 
        /*
         * Split the old name into directory and last component
-        * strings. Note that if (!unix_dfs_convert may have stripped off a 
+        * strings. Note that unix_convert may have stripped off a 
         * leading ./ from both name and newname if the rename is 
         * at the root of the share. We need to make sure either both
         * name and newname contain a / character or neither of them do
@@ -3512,7 +3695,16 @@ int rename_internals(connection_struct * conn,
                *p = '/';       /* Replace needed for exceptional test below. */
        }
 
-       if (is_mangled(mask))
+       /*
+        * We should only check the mangled cache
+        * here if unix_convert failed. This means
+        * that the path in 'mask' doesn't exist
+        * on the file system and so we need to look
+        * for a possible mangle. This patch from
+        * Tine Smukavec <valentin.smukavec@hermes.si>.
+        */
+
+       if (!rc && is_mangled(mask))
                check_mangled_cache(mask);
 
        has_wild = strchr(mask, '*') || strchr(mask, '?');
@@ -3580,27 +3772,29 @@ int rename_internals(connection_struct * conn,
                        }
                }
 
+               pstrcpy(zdirectory, dos_to_unix(directory, False));
                if (replace_if_exists)
                {
                        /*
                         * NT SMB specific flag - rename can overwrite
                         * file with the same name so don't check for
-                        * dos_file_exist().
+                        * vfs_file_exist().
                         */
                        if (resolve_wildcards(directory, newname) &&
                            can_rename(directory, conn) &&
-                           !conn->vfs_ops.
-                           rename(dos_to_unix(directory, False), newname))
+                           !conn->vfs_ops.rename(zdirectory,
+                                                 dos_to_unix(newname,
+                                                             False)))
                                count++;
                }
                else
                {
                        if (resolve_wildcards(directory, newname) &&
                            can_rename(directory, conn) &&
-                           !vfs_file_exist(conn, dos_to_unix(newname, False),
-                                           NULL)
-                           && !conn->vfs_ops.
-                           rename(dos_to_unix(directory, False), newname))
+                           !vfs_file_exist(conn, newname, NULL) &&
+                           !conn->vfs_ops.rename(zdirectory,
+                                                 dos_to_unix(newname,
+                                                             False)))
                                count++;
                }
 
@@ -3610,13 +3804,8 @@ int rename_internals(connection_struct * conn,
                       newname));
 
                if (!count)
-                       exists =
-                               vfs_file_exist(conn,
-                                              dos_to_unix(directory, False),
-                                              NULL);
-               if (!count && exists
-                   && vfs_file_exist(conn, dos_to_unix(newname, False),
-                                     NULL))
+                       exists = vfs_file_exist(conn, directory, NULL);
+               if (!count && exists && vfs_file_exist(conn, newname, NULL))
                {
                        exists = True;
                        error = ERRrename;
@@ -3669,11 +3858,8 @@ int rename_internals(connection_struct * conn,
                                        continue;
                                }
 
-                               if (!replace_if_exists
-                                   && vfs_file_exist(conn,
-                                                     dos_to_unix(destname,
-                                                                 False),
-                                                     NULL))
+                               if (!replace_if_exists &&
+                                   vfs_file_exist(conn, destname, NULL))
                                {
                                        DEBUG(6,
                                              ("file_exist %s\n", destname));
@@ -3681,9 +3867,10 @@ int rename_internals(connection_struct * conn,
                                        continue;
                                }
 
-                               if (!conn->vfs_ops.
-                                   rename(dos_to_unix(fname, False),
-                                          destname))
+                               if (!conn->
+                                   vfs_ops.rename(dos_to_unix(fname, False),
+                                                  dos_to_unix(destname,
+                                                              False)))
                                        count++;
                                DEBUG(3,
                                      ("rename_internals: doing rename on %s -> %s\n",
@@ -3725,6 +3912,9 @@ int reply_mv(connection_struct * conn, char *inbuf, char *outbuf,
        pstrcpy(name, smb_buf(inbuf) + 1);
        pstrcpy(newname, smb_buf(inbuf) + 3 + strlen(name));
 
+       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
        DEBUG(3, ("reply_mv : %s -> %s\n", name, newname));
 
        outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
@@ -3739,14 +3929,17 @@ int reply_mv(connection_struct * conn, char *inbuf, char *outbuf,
   ******************************************************************/
 
 static BOOL copy_file(char *src, char *dest1, connection_struct * conn,
-                     int ofun, int count, BOOL target_is_directory)
+                     int ofun, int count, BOOL target_is_directory,
+                     int *err_ret)
 {
        int Access, action;
        SMB_STRUCT_STAT st;
-       int ret = -1;
+       SMB_OFF_T ret = -1;
        files_struct *fsp1, *fsp2;
        pstring dest;
 
+       *err_ret = 0;
+
        pstrcpy(dest, dest1);
        if (target_is_directory)
        {
@@ -3759,7 +3952,7 @@ static BOOL copy_file(char *src, char *dest1, connection_struct * conn,
                pstrcat(dest, p);
        }
 
-       if (!vfs_file_exist(conn, dos_to_unix(src, False), &st))
+       if (!vfs_file_exist(conn, src, &st))
                return (False);
 
        fsp1 = file_new();
@@ -3820,9 +4013,15 @@ static BOOL copy_file(char *src, char *dest1, connection_struct * conn,
                                          NULL, 0, 0);
 
        close_file(fsp1, False);
-       close_file(fsp2, False);
+       /*
+        * As we are opening fsp1 read-only we only expect
+        * an error on close on fsp2 if we are out of space.
+        * Thus we don't look at the error return from the
+        * close of fsp1.
+        */
+       *err_ret = close_file(fsp2, False);
 
-       return (ret == st.st_size);
+       return (ret == (SMB_OFF_T) st.st_size);
 }
 
 
@@ -3840,6 +4039,7 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
        char *p;
        int count = 0;
        int error = ERRnoaccess;
+       int err = 0;
        BOOL has_wild;
        BOOL exists = False;
        int tid2 = SVAL(inbuf, smb_vwv0);
@@ -3848,6 +4048,7 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
        BOOL target_is_directory = False;
        BOOL bad_path1 = False;
        BOOL bad_path2 = False;
+       BOOL rc = True;
 
        *directory = *mask = 0;
 
@@ -3863,18 +4064,13 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
                return (ERROR(ERRSRV, ERRinvdevice));
        }
 
-       if (!unix_dfs_convert(name, conn, 0, &bad_path1, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
-       if (!unix_dfs_convert(newname, conn, 0, &bad_path2, NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return (ERROR(0, 0xc0000000 | NT_STATUS_PATH_NOT_COVERED));
-       }
+       RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+
+       rc = unix_convert(name, conn, 0, &bad_path1, NULL);
+       unix_convert(newname, conn, 0, &bad_path2, NULL);
 
-       target_is_directory = dos_directory_exist(newname, NULL);
+       target_is_directory = vfs_directory_exist(conn, False, NULL);
 
        if ((flags & 1) && target_is_directory)
        {
@@ -3886,7 +4082,7 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
                return (ERROR(ERRDOS, ERRbadpath));
        }
 
-       if ((flags & (1 << 5)) && dos_directory_exist(name, NULL))
+       if ((flags & (1 << 5)) && vfs_directory_exist(conn, name, NULL))
        {
                /* wants a tree copy! XXXX */
                DEBUG(3, ("Rejecting tree copy\n"));
@@ -3906,7 +4102,16 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
                pstrcpy(mask, p + 1);
        }
 
-       if (is_mangled(mask))
+       /*
+        * We should only check the mangled cache
+        * here if unix_convert failed. This means
+        * that the path in 'mask' doesn't exist
+        * on the file system and so we need to look
+        * for a possible mangle. This patch from
+        * Tine Smukavec <valentin.smukavec@hermes.si>.
+        */
+
+       if (!rc && is_mangled(mask))
                check_mangled_cache(mask);
 
        has_wild = strchr(mask, '*') || strchr(mask, '?');
@@ -3917,12 +4122,15 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
                pstrcat(directory, mask);
                if (resolve_wildcards(directory, newname) &&
                    copy_file(directory, newname, conn, ofun,
-                             count, target_is_directory)) count++;
+                             count, target_is_directory, &err))
+                       count++;
+               if (!count && err)
+               {
+                       errno = err;
+                       return (UNIXERROR(ERRHRD, ERRgeneral));
+               }
                if (!count)
-                       exists =
-                               vfs_file_exist(conn,
-                                              dos_to_unix(directory, False),
-                                              NULL);
+                       exists = vfs_file_exist(conn, directory, NULL);
        }
        else
        {
@@ -3946,17 +4154,17 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
                                pstrcpy(fname, dname);
 
                                if (!mask_match
-                                   (fname, mask, case_sensitive,
-                                    False)) continue;
+                                   (fname, mask, case_sensitive, False))
+                                       continue;
 
                                error = ERRnoaccess;
                                slprintf(fname, sizeof(fname) - 1, "%s/%s",
                                         directory, dname);
                                pstrcpy(destname, newname);
                                if (resolve_wildcards(fname, destname) &&
-                                   copy_file(directory, newname, conn, ofun,
-                                             count, target_is_directory))
-                                       count++;
+                                   copy_file(fname, destname, conn, ofun,
+                                             count, target_is_directory,
+                                             &err)) count++;
                                DEBUG(3,
                                      ("reply_copy : doing copy on %s -> %s\n",
                                       fname, destname));
@@ -3967,6 +4175,13 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf,
 
        if (count == 0)
        {
+               if (err)
+               {
+                       /* Error on close... */
+                       errno = err;
+                       return (UNIXERROR(ERRHRD, ERRgeneral));
+               }
+
                if (exists)
                        return (ERROR(ERRDOS, error));
                else
@@ -4010,7 +4225,7 @@ int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf,
        }
        else
        {
-               ok = dos_directory_exist(newdir, NULL);
+               ok = vfs_directory_exist(conn, newdir, NULL);
                if (ok)
                {
                        string_set(&conn->connectpath, newdir);
@@ -4028,6 +4243,260 @@ int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf,
        return (outsize);
 }
 
+/****************************************************************************
+ Get a lock count, dealing with large count requests.
+****************************************************************************/
+
+SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format,
+                        BOOL *err)
+{
+       SMB_OFF_T count = 0;
+
+       *err = False;
+
+       if (!large_file_format)
+       {
+               count = (SMB_OFF_T) IVAL(data, SMB_LKLEN_OFFSET(data_offset));
+       }
+       else
+       {
+
+#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
+
+               count =
+                       (((SMB_OFF_T)
+                         IVAL(data,
+                              SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) <<
+                        32) | ((SMB_OFF_T) IVAL(data,
+                                                SMB_LARGE_LKLEN_OFFSET_LOW
+                                                (data_offset)));
+
+#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
+
+               /*
+                * NT4.x seems to be broken in that it sends large file
+                * lockingX calls even if the CAP_LARGE_FILES was *not*
+                * negotiated. For boxes without large file locks truncate the
+                * lock count by dropping the top 32 bits.
+                */
+
+               if (IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)
+               {
+                       DEBUG(3,
+                             ("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
+                              (unsigned int)IVAL(data,
+                                                 SMB_LARGE_LKLEN_OFFSET_HIGH
+                                                 (data_offset)),
+                              (unsigned int)IVAL(data,
+                                                 SMB_LARGE_LKLEN_OFFSET_LOW
+                                                 (data_offset))));
+                       SIVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),
+                             0);
+               }
+
+               if (IVAL(data, SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)
+               {
+                       /*
+                        * Before we error out, see if we can sensibly map the top bits
+                        * down to the lower bits - or lose the top bits if they are all 1's.
+                        * It seems that NT has this horrible bug where it will send 64 bit
+                        * lock requests even if told not to. JRA.
+                        */
+
+                       if (IVAL
+                           (data,
+                            SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ==
+                           (uint32)0xFFFFFFFF)
+                               count =
+                                       (SMB_OFF_T) IVAL(data,
+                                                        SMB_LARGE_LKLEN_OFFSET_HIGH
+                                                        (data_offset));
+                       else
+                               if (IVAL
+                                   (data,
+                                    SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))
+                                   == (uint32)0xFFFFFFFF)
+                               count =
+                                       (SMB_OFF_T) IVAL(data,
+                                                        SMB_LARGE_LKLEN_OFFSET_LOW
+                                                        (data_offset));
+                       else
+                       {
+
+                               DEBUG(0,
+                                     ("get_lock_count: Error : a large file count (%x << 32 | %x) was sent and we don't \
+support large counts.\n",
+                                      (unsigned int)IVAL(data,
+                                                         SMB_LARGE_LKLEN_OFFSET_HIGH
+                                                         (data_offset)),
+                                      (unsigned int)IVAL(data,
+                                                         SMB_LARGE_LKLEN_OFFSET_LOW
+                                                         (data_offset))));
+
+                               *err = True;
+                               return (SMB_OFF_T) - 1;
+                       }
+               }
+               else
+                       count =
+                               (SMB_OFF_T) IVAL(data,
+                                                SMB_LARGE_LKLEN_OFFSET_LOW
+                                                (data_offset));
+
+#endif /* LARGE_SMB_OFF_T */
+       }
+       return count;
+}
+
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+static uint32 map_lock_offset(uint32 high, uint32 low)
+{
+       unsigned int i;
+       uint32 mask = 0;
+       uint32 highcopy = high;
+
+       /*
+        * Try and find out how many significant bits there are in high.
+        */
+
+       for (i = 0; highcopy; i++)
+               highcopy >>= 1;
+
+       /*
+        * We use 31 bits not 32 here as POSIX
+        * lock offsets may not be negative.
+        */
+
+       mask = (~0) << (31 - i);
+
+       if (low & mask)
+               return 0;       /* Fail. */
+
+       high <<= (31 - i);
+
+       return (high | low);
+}
+
+/****************************************************************************
+ Get a lock offset, dealing with large offset requests.
+****************************************************************************/
+
+SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format,
+                         BOOL *err)
+{
+       SMB_OFF_T offset = 0;
+
+       *err = False;
+
+       if (!large_file_format)
+       {
+               offset =
+                       (SMB_OFF_T) IVAL(data, SMB_LKOFF_OFFSET(data_offset));
+       }
+       else
+       {
+
+#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
+
+               offset =
+                       (((SMB_OFF_T)
+                         IVAL(data,
+                              SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) <<
+                        32) | ((SMB_OFF_T) IVAL(data,
+                                                SMB_LARGE_LKOFF_OFFSET_LOW
+                                                (data_offset)));
+
+#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
+
+               /*
+                * NT4.x seems to be broken in that it sends large file
+                * lockingX calls even if the CAP_LARGE_FILES was *not*
+                * negotiated. For boxes without large file locks mangle the
+                * lock offset by mapping the top 32 bits onto the lower 32.
+                */
+
+               if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)
+               {
+                       uint32 low = IVAL(data,
+                                         SMB_LARGE_LKOFF_OFFSET_LOW
+                                         (data_offset));
+                       uint32 high = IVAL(data,
+                                          SMB_LARGE_LKOFF_OFFSET_HIGH
+                                          (data_offset));
+                       uint32 new_low = 0;
+
+                       if ((new_low = map_lock_offset(high, low)) == 0)
+                       {
+                               *err = True;
+                               return (SMB_OFF_T) - 1;
+                       }
+
+                       DEBUG(3,
+                             ("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
+                              (unsigned int)high, (unsigned int)low,
+                              (unsigned int)new_low));
+                       SIVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),
+                             0);
+                       SIVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),
+                             new_low);
+               }
+
+               if (IVAL(data, SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)
+               {
+                       /*
+                        * Before we error out, see if we can sensibly map the top bits
+                        * down to the lower bits - or lose the top bits if they are all 1's.
+                        * It seems that NT has this horrible bug where it will send 64 bit
+                        * lock requests even if told not to. JRA.
+                        */
+
+                       if (IVAL
+                           (data,
+                            SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) ==
+                           (uint32)0xFFFFFFFF)
+                               offset =
+                                       (SMB_OFF_T) IVAL(data,
+                                                        SMB_LARGE_LKOFF_OFFSET_HIGH
+                                                        (data_offset));
+                       else
+                               if (IVAL
+                                   (data,
+                                    SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))
+                                   == (uint32)0xFFFFFFFF)
+                               offset =
+                                       (SMB_OFF_T) IVAL(data,
+                                                        SMB_LARGE_LKOFF_OFFSET_LOW
+                                                        (data_offset));
+                       else
+                       {
+
+                               DEBUG(0,
+                                     ("get_lock_count: Error : a large file offset (%x << 32 | %x) was sent and we don't \
+support large offsets.\n",
+                                      (unsigned int)IVAL(data,
+                                                         SMB_LARGE_LKOFF_OFFSET_HIGH
+                                                         (data_offset)),
+                                      (unsigned int)IVAL(data,
+                                                         SMB_LARGE_LKOFF_OFFSET_LOW
+                                                         (data_offset))));
+
+                               *err = True;
+                               return (SMB_OFF_T) - 1;
+                       }
+               }
+               else
+                       offset =
+                               (SMB_OFF_T) IVAL(data,
+                                                SMB_LARGE_LKOFF_OFFSET_LOW
+                                                (data_offset));
+
+#endif /* LARGE_SMB_OFF_T */
+       }
+       return offset;
+}
+
 /****************************************************************************
   reply to a lockingX request
 ****************************************************************************/
@@ -4035,9 +4504,9 @@ int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
                   int length, int bufsize)
 {
        files_struct *fsp = file_fsp(inbuf, smb_vwv2);
-       uchar locktype = CVAL(inbuf, smb_vwv3);
+       unsigned char locktype = CVAL(inbuf, smb_vwv3);
 #if 0
-       uchar oplocklevel = CVAL(inbuf, smb_vwv3 + 1);
+       unsigned char oplocklevel = CVAL(inbuf, smb_vwv3 + 1);
 #endif
        uint16 num_ulocks = SVAL(inbuf, smb_vwv6);
        uint16 num_locks = SVAL(inbuf, smb_vwv7);
@@ -4048,6 +4517,8 @@ int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
        uint32 ecode = 0, dummy2;
        int eclass = 0, dummy1;
        BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
+       BOOL err1, err2;
+
        CHECK_FSP(fsp, conn);
        CHECK_ERROR(fsp);
 
@@ -4058,42 +4529,33 @@ int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf,
         */
        if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
        {
-               SMB_DEV_T dev = fsp->fd_ptr->dev;
-               SMB_INO_T inode = fsp->fd_ptr->inode;
-
                DEBUG(5,
                      ("reply_lockingX: oplock break reply from client for fnum = %d\n",
                       fsp->fnum));
                /*
-                * Make sure we have granted an oplock on this file.
+                * Make sure we have granted an exclusive or batch oplock on this file.
                 */
-               if (!fsp->granted_oplock)
+
+               if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
                {
                        DEBUG(0,
                              ("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file.\n",
-                              fsp->fnum));
-                       return ERROR(ERRDOS, ERRlock);
+no oplock granted on this file (%s).\n",
+                              fsp->fnum, fsp->fsp_name));
+
+                       /* if this is a pure oplock break request then don't send a reply */
+                       if (num_locks == 0 && num_ulocks == 0)
+                               return -1;
+                       else
+                               return ERROR(ERRDOS, ERRlock);
                }
 
-               /* Remove the oplock flag from the sharemode. */
-               lock_share_entry(fsp->conn, dev, inode);
-               if (remove_share_oplock(fsp) == False)
+               if (remove_oplock(fsp) == False)
                {
 
                        DEBUG(0,
-                             ("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %.0f\n",
-                              fsp->fnum, (unsigned int)dev, (double)inode));
-
-                       unlock_share_entry(fsp->conn, dev, inode);
-               }
-               else
-               {
-                       unlock_share_entry(fsp->conn, dev, inode);
-
-                       /* Clear the granted flag and return. */
-                       fsp->granted_oplock = False;
+                             ("reply_lockingX: error in removing oplock on file %s\n",
+                              fsp->fsp_name));
                }
 
                /* if this is a pure oplock break request then don't send a reply */
@@ -4113,28 +4575,14 @@ dev = %x, inode = %.0f\n",
           of smb_unlkrng structs */
        for (i = 0; i < (int)num_ulocks; i++)
        {
-               if (!large_file_format)
-               {
-                       count = IVAL(data, SMB_LKLEN_OFFSET(i));
-                       offset = IVAL(data, SMB_LKOFF_OFFSET(i));
-               }
-#ifdef LARGE_SMB_OFF_T
-               else
-               {
-                       count =
-                               (((SMB_OFF_T)
-                                 IVAL(data,
-                                      SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32)
-                               | ((SMB_OFF_T)
-                                  IVAL(data, SMB_LARGE_LKLEN_OFFSET_LOW(i)));
-                       offset =
-                               (((SMB_OFF_T)
-                                 IVAL(data,
-                                      SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32)
-                               | ((SMB_OFF_T)
-                                  IVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(i)));
-               }
-#endif /* LARGE_SMB_OFF_T */
+               count = get_lock_count(data, i, large_file_format, &err1);
+               offset = get_lock_offset(data, i, large_file_format, &err2);
+
+               /*
+                * There is no error code marked "stupid client bug".... :-).
+                */
+               if (err1 || err2)
+                       return ERROR(ERRDOS, ERRnoaccess);
 
                DEBUG(10,
                      ("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
@@ -4155,28 +4603,14 @@ dev = %x, inode = %.0f\n",
 
        for (i = 0; i < (int)num_locks; i++)
        {
-               if (!large_file_format)
-               {
-                       count = IVAL(data, SMB_LKLEN_OFFSET(i));
-                       offset = IVAL(data, SMB_LKOFF_OFFSET(i));
-               }
-#ifdef LARGE_SMB_OFF_T
-               else
-               {
-                       count =
-                               (((SMB_OFF_T)
-                                 IVAL(data,
-                                      SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32)
-                               | ((SMB_OFF_T)
-                                  IVAL(data, SMB_LARGE_LKLEN_OFFSET_LOW(i)));
-                       offset =
-                               (((SMB_OFF_T)
-                                 IVAL(data,
-                                      SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32)
-                               | ((SMB_OFF_T)
-                                  IVAL(data, SMB_LARGE_LKOFF_OFFSET_LOW(i)));
-               }
-#endif /* LARGE_SMB_OFF_T */
+               count = get_lock_count(data, i, large_file_format, &err1);
+               offset = get_lock_offset(data, i, large_file_format, &err2);
+
+               /*
+                * There is no error code marked "stupid client bug".... :-).
+                */
+               if (err1 || err2)
+                       return ERROR(ERRDOS, ERRnoaccess);
 
                DEBUG(10,
                      ("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
@@ -4184,7 +4618,8 @@ dev = %x, inode = %.0f\n",
 
                if (!do_lock
                    (fsp, conn, count, offset,
-                    ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode))
+                    ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &eclass,
+                    &ecode))
                {
                        if ((ecode == ERRlock) && (lock_timeout != 0)
                            && lp_blocking_locks(SNUM(conn)))
@@ -4206,34 +4641,25 @@ dev = %x, inode = %.0f\n",
           all of the previous locks (X/Open spec). */
        if (i != num_locks && num_locks != 0)
        {
-               for (; i >= 0; i--)
+               /*
+                * Ensure we don't do a remove on the lock that just failed,
+                * as under POSIX rules, if we have a lock already there, we
+                * will delete it (and we shouldn't) .....
+                */
+               for (i--; i >= 0; i--)
                {
-                       if (!large_file_format)
-                       {
-                               count = IVAL(data, SMB_LKLEN_OFFSET(i));
-                               offset = IVAL(data, SMB_LKOFF_OFFSET(i));
-                       }
-#ifdef LARGE_SMB_OFF_T
-                       else
-                       {
-                               count =
-                                       (((SMB_OFF_T)
-                                         IVAL(data,
-                                              SMB_LARGE_LKLEN_OFFSET_HIGH
-                                              (i))) << 32) | ((SMB_OFF_T)
-                                                              IVAL(data,
-                                                                   SMB_LARGE_LKLEN_OFFSET_LOW
-                                                                   (i)));
-                               offset =
-                                       (((SMB_OFF_T)
-                                         IVAL(data,
-                                              SMB_LARGE_LKOFF_OFFSET_HIGH
-                                              (i))) << 32) | ((SMB_OFF_T)
-                                                              IVAL(data,
-                                                                   SMB_LARGE_LKOFF_OFFSET_LOW
-                                                                   (i)));
-                       }
-#endif /* LARGE_SMB_OFF_T */
+                       count =
+                               get_lock_count(data, i, large_file_format,
+                                              &err1);
+                       offset =
+                               get_lock_offset(data, i, large_file_format,
+                                               &err2);
+
+                       /*
+                        * There is no error code marked "stupid client bug".... :-).
+                        */
+                       if (err1 || err2)
+                               return ERROR(ERRDOS, ERRnoaccess);
 
                        do_unlock(fsp, conn, count, offset, &dummy1, &dummy2);
                }
@@ -4289,7 +4715,7 @@ int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf,
        tcount = maxcount;
        total_read = 0;
 
-       if (is_locked(fsp, conn, maxcount, startpos, F_RDLCK))
+       if (is_locked(fsp, conn, maxcount, startpos, READ_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
        do
@@ -4324,7 +4750,7 @@ int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf,
   reply to a SMBwritebmpx (write block multiplex primary) request
 ****************************************************************************/
 int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
-                   int dum_size, int dum_buffsize)
+                   int size, int dum_buffsize)
 {
        size_t numtowrite;
        ssize_t nwritten = -1;
@@ -4352,17 +4778,13 @@ int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
           not an SMBwritebmpx - set this up now so we don't forget */
        CVAL(outbuf, smb_com) = SMBwritec;
 
-       if (is_locked(fsp, conn, tcount, startpos, F_WRLCK))
+       if (is_locked(fsp, conn, tcount, startpos, WRITE_LOCK))
                return (ERROR(ERRDOS, ERRlock));
 
-       if (seek_file(fsp, startpos) == -1)
-               return (UNIXERROR(ERRDOS, ERRnoaccess));
+       nwritten = write_file(fsp, data, startpos, numtowrite);
 
-       nwritten = write_file(fsp, data, numtowrite);
-
-       if ((lp_syncalways(SNUM(conn)) || write_through) &&
-           lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+       if (lp_syncalways(SNUM(conn)) || write_through)
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        if (nwritten < (ssize_t) numtowrite)
                return (UNIXERROR(ERRHRD, ERRdiskfull));
@@ -4402,7 +4824,7 @@ int reply_writebmpx(connection_struct * conn, char *inbuf, char *outbuf,
        SSVALS(outbuf, smb_vwv0, -1);   /* We don't support smb_remaining */
 
        DEBUG(3, ("writebmpx fnum=%d num=%d wrote=%d\n",
-                 fsp->fnum, numtowrite, nwritten));
+                 fsp->fnum, (int)numtowrite, (int)nwritten));
 
        if (write_through && tcount == nwritten)
        {
@@ -4465,24 +4887,10 @@ int reply_writebs(connection_struct * conn, char *inbuf, char *outbuf,
        if (wbms->wr_discard)
                return -1;      /* Just discard the packet */
 
-       if (seek_file(fsp, startpos) == -1)
-       {
-               if (write_through)
-               {
-                       /* We are returning an error - we can delete the aux struct */
-                       if (wbms)
-                               free((char *)wbms);
-                       fsp->wbmpx_ptr = NULL;
-                       return (UNIXERROR(ERRDOS, ERRnoaccess));
-               }
-               return (CACHE_ERROR(wbms, ERRDOS, ERRnoaccess));
-       }
-
-       nwritten = write_file(fsp, data, numtowrite);
+       nwritten = write_file(fsp, data, startpos, numtowrite);
 
-       if ((lp_syncalways(SNUM(conn)) || write_through) &&
-           lp_strict_sync(SNUM(conn)))
-               conn->vfs_ops.sync(fsp->fd_ptr->fd);
+       if (lp_syncalways(SNUM(conn)) || write_through)
+               conn->vfs_ops.fsync(fsp->fd_ptr->fd);
 
        if (nwritten < (ssize_t) numtowrite)
        {
@@ -4524,7 +4932,7 @@ int reply_writebs(connection_struct * conn, char *inbuf, char *outbuf,
   reply to a SMBsetattrE
 ****************************************************************************/
 int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf,
-                  int dum_size, int dum_buffsize)
+                  int size, int dum_buffsize)
 {
        struct utimbuf unix_times;
        int outsize = 0;
@@ -4579,7 +4987,7 @@ int reply_setattrE(connection_struct * conn, char *inbuf, char *outbuf,
   reply to a SMBgetattrE
 ****************************************************************************/
 int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf,
-                  int dum_size, int dum_buffsize)
+                  int size, int dum_buffsize)
 {
        SMB_STRUCT_STAT sbuf;
        int outsize = 0;
@@ -4612,7 +5020,7 @@ int reply_getattrE(connection_struct * conn, char *inbuf, char *outbuf,
        }
        else
        {
-               SIVAL(outbuf, smb_vwv6, (uint32) sbuf.st_size);
+               SIVAL(outbuf, smb_vwv6, (uint32)sbuf.st_size);
                SIVAL(outbuf, smb_vwv8, SMB_ROUNDUP(sbuf.st_size, 1024));
        }
        SSVAL(outbuf, smb_vwv10, mode);
index 8d27541e336a37f69677cf469477bc427c67eae8..f36df3d020cd35d8a63435917486ebe53167ac4c 100644 (file)
@@ -27,7 +27,6 @@ extern pstring debugf;
 extern fstring global_myworkgroup;
 extern fstring global_sam_name;
 extern pstring global_myname;
-extern dfs_internal dfs_struct;
 
 int am_parent = 1;
 
@@ -37,7 +36,6 @@ int last_message = -1;
 /* a useful macro to debug the last message processed */
 #define LAST_MESSAGE() smb_fn_name(last_message)
 
-extern pstring scope;
 extern int DEBUGLEVEL;
 
 extern pstring user_socket_options;
@@ -114,7 +112,7 @@ static int open_server_socket(int port, uint32 ipaddr)
 /****************************************************************************
   open the socket communication
 ****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port,int port445)
+static BOOL open_sockets(BOOL is_daemon,int port, int port445)
 {
        extern int Client;
        extern int ClientPort;
@@ -183,7 +181,8 @@ max can be %d\n",
                num_interfaces = 1;
                
                /* open an incoming socket */
-               s = open_server_socket(port, interpret_addr(lp_socket_address()));
+               s = open_server_socket(port,
+                                  interpret_addr(lp_socket_address()));
                if (s == -1)
                        return(False);
                fd_listenset[0] = s;
@@ -207,11 +206,14 @@ max can be %d\n",
                memcpy((char *)&lfds, (char *)&listen_set, 
                       sizeof(listen_set));
                
-               num = sys_select(256,&lfds,NULL, NULL);
+               num = sys_select(FD_SETSIZE,&lfds,NULL,NULL);
                
                if (num == -1 && errno == EINTR)
                        continue;
                
+               /* check if we need to reload services */
+               check_reload(time(NULL));
+
                /* Find the sockets that are read-ready -
                   accept on these. */
                for( ; num > 0; num--) {
@@ -332,6 +334,14 @@ BOOL reload_services(BOOL test)
 
        ret = lp_load(servicesf,False,False,True);
 
+#ifdef MS_DFS
+       /* load the dfs maps of all the services having 
+          a dfs_map parameter 
+          we don't want to do this in lp_load because we want just the smbd
+          server to load up the dfs maps into msdfs.tdb. not nmbd, swat etc*/
+       load_dfsmaps();
+#endif
+
        load_printers();
 
        /* perhaps the config filename is now set */
@@ -351,6 +361,7 @@ BOOL reload_services(BOOL test)
        }
 
        reset_mangled_cache();
+    reset_stat_cache();
 
        /* this forces service parameters to be flushed */
        become_service(NULL,True);
@@ -361,9 +372,10 @@ BOOL reload_services(BOOL test)
 
 
 /****************************************************************************
-this prevents zombie child processes
+ Catch a sighup.
 ****************************************************************************/
-BOOL reload_after_sighup = False;
+
+VOLATILE SIG_ATOMIC_T reload_after_sighup = False;
 
 static void sig_hup(int sig)
 {
@@ -438,6 +450,8 @@ void exit_server(char *reason)
 
        conn_close_all();
 
+    respond_to_all_remaining_local_messages();
+
 #ifdef WITH_DFS
        if (dcelogin_atmost_once) {
                dfs_unlogin();
@@ -458,15 +472,11 @@ void exit_server(char *reason)
        }    
 
        locking_end();
+#ifdef MS_DFS
+       msdfs_end();
+#endif
 
        DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
-#ifdef MEM_MAN
-       {
-               extern FILE *dbf;
-               smb_mem_write_verbose(dbf);
-               dbgflush();
-       }
-#endif
        exit(0);
 }
 
@@ -477,11 +487,25 @@ void exit_server(char *reason)
 ****************************************************************************/
 static void init_structs(void)
 {
+       /*
+        * Set the machine NETBIOS name if not already
+        * set from the config file.
+        */
+
+       if (!*global_myname) {
+               char *p;
+               fstrcpy( global_myname, myhostname() );
+               p = strchr( global_myname, '.' );
+               if (p) 
+                       *p = 0;
+       }
+
+       strupper( global_myname );
+
        conn_init();
        file_init();
        init_rpc_pipe_hnd(); /* for RPC pipes */
        init_dptrs();
-       init_dfs_table();
 }
 
 /****************************************************************************
@@ -489,20 +513,21 @@ usage on the program
 ****************************************************************************/
 static void usage(char *pname)
 {
-       DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
-
-       printf("Usage: %s [-D] [-p port] [-d debuglevel] ", pname);
-        printf("[-l log basename] [-s services file]\n" );
-       printf("Version %s\n",VERSION);
-       printf("\t-D                    become a daemon\n");
-       printf("\t-p port               listen on the specified port\n");
-       printf("\t-d debuglevel         set the debuglevel\n");
+
+       printf("Usage: %s [-DaoPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+       printf("       [-O socket options] [-s services file]\n");
+       printf("\t-D                    Become a daemon\n");
+       printf("\t-a                    Append to log file (default)\n");
+       printf("\t-o                    Overwrite log file, don't append\n");
+       printf("\t-P                    Passive only\n");
+       printf("\t-h                    Print usage\n");
+       printf("\t-?                    Print usage\n");
+       printf("\t-V                    Print version\n");
+       printf("\t-d debuglevel         Set the debuglevel\n");
        printf("\t-l log basename.      Basename for log/debug files\n");
+       printf("\t-p port               Listen on the specified port\n");
+       printf("\t-O socket options     Socket options\n");
        printf("\t-s services file.     Filename of services file\n");
-       printf("\t-P                    passive only\n");
-       printf("\t-a                    append to log file (default)\n");
-       printf("\t-o                    overwrite log file, don't append\n");
-       printf("\t-i scope              NetBIOS scope to use (default none)\n");
        printf("\n");
 }
 
@@ -515,6 +540,7 @@ static void usage(char *pname)
        extern BOOL append_log;
        /* shall I run as a daemon */
        BOOL is_daemon = False;
+       BOOL specified_logfile = False;
        int port = SMB_PORT;
        int port445 = SMB_PORT2;
        int opt;
@@ -524,58 +550,18 @@ static void usage(char *pname)
        set_auth_parameters(argc,argv);
 #endif
 
-#ifdef HAVE_SETLUID
-       /* needed for SecureWare on SCO */
-       setluid(0);
-#endif
-
-       append_log = True;
-
-       TimeInit();
-
-       pstrcpy(debugf,SMBLOGFILE);  
-
-       pstrcpy(remote_machine, "smb");
-
-       setup_logging(argv[0],False);
-
-       charset_initialise();
-
-       /* make absolutely sure we run as root - to handle cases where people
-          are crazy enough to have it setuid */
-       gain_root_privilege();
-       gain_root_group_privilege();
-
-       fault_setup((void (*)(void *))exit_server);
-       CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
-
-       /* we are never interested in SIGPIPE */
-       BlockSignals(True,SIGPIPE);
-
-       /* we want total control over the permissions on created files,
-          so set our umask to 0 */
-       umask(0);
-
-       dos_GetWd(OriginalDir);
-
-       init_uid();
-
        /* this is for people who can't start the program correctly */
        while (argc > 1 && (*argv[1] != '-')) {
                argv++;
                argc--;
        }
 
-       while ( EOF != (opt = getopt(argc, argv, "O:i:l:s:d:Dp:h?Paof:")) )
+       while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?VPaof:")) )
                switch (opt)  {
                case 'O':
                        pstrcpy(user_socket_options,optarg);
                        break;
 
-               case 'i':
-                       pstrcpy(scope,optarg);
-                       break;
-
                case 'P':
                        {
                                extern BOOL passive;
@@ -588,6 +574,7 @@ static void usage(char *pname)
                        break;
 
                case 'l':
+                       specified_logfile = True;
                        pstrcpy(debugf,optarg);
                        break;
 
@@ -620,11 +607,73 @@ static void usage(char *pname)
                        exit(0);
                        break;
 
+               case 'V':
+                       printf("Version %s\n",VERSION);
+                       exit(0);
+                       break;
                default:
+                       DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
                        usage(argv[0]);
                        exit(1);
                }
 
+#ifdef HAVE_SETLUID
+       /* needed for SecureWare on SCO */
+       setluid(0);
+#endif
+
+       /*
+        * gain_root_privilege uses an assert than will cause a core
+        * dump if euid != 0. Ensure this is the case.
+        */
+
+       if(geteuid() != (uid_t)0) {
+               fprintf(stderr, "%s: Version %s : Must have effective user id of zero to run.\n", argv[0], VERSION);
+               exit(1);
+       }
+
+       append_log = True;
+
+       TimeInit();
+
+       if(!specified_logfile)
+               pstrcpy(debugf,SMBLOGFILE);  
+
+       pstrcpy(remote_machine, "smb");
+
+       setup_logging(argv[0],False);
+
+       charset_initialise();
+
+       /* we want to re-seed early to prevent time delays causing
+           client problems at a later date. (tridge) */
+       generate_random_buffer(NULL, 0, False);
+
+       /* make absolutely sure we run as root - to handle cases where people
+          are crazy enough to have it setuid */
+
+       gain_root_privilege();
+       gain_root_group_privilege();
+
+       fault_setup((void (*)(void *))exit_server);
+       CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
+
+       /* we are never interested in SIGPIPE */
+       BlockSignals(True,SIGPIPE);
+
+#if defined(SIGFPE)
+       /* we are never interested in SIGFPE */
+       BlockSignals(True,SIGFPE);
+#endif
+
+       /* we want total control over the permissions on created files,
+          so set our umask to 0 */
+       umask(0);
+
+       dos_GetWd(OriginalDir);
+
+       init_uid();
+
        reopen_logs();
 
        DEBUG(1,( "smbd version %s started.\n", VERSION));
@@ -638,6 +687,10 @@ static void usage(char *pname)
                exit(1);
        }
 
+       /*
+        * Do this before reload_services.
+        */
+
        if (!reload_services(False))
                return(-1);     
 
@@ -650,16 +703,6 @@ static void usage(char *pname)
        }
 #endif
 
-       /*
-        * Set the machine NETBIOS name if not already
-        * set from the config file.
-        */
-       if (!*global_myname)
-       {
-               fstrcpy(global_myname, dns_to_netbios_name(myhostname()));
-       }
-       strupper(global_myname);
-
 #ifdef WITH_SSL
        {
                extern BOOL sslEnabled;
@@ -671,10 +714,7 @@ static void usage(char *pname)
 
        codepage_initialise(lp_client_code_page());
 
-       if (!pwdb_initialise(True))
-       {
-               exit(1);
-       }
+       fstrcpy(global_myworkgroup, lp_workgroup());
 
        CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
        
@@ -684,7 +724,6 @@ static void usage(char *pname)
        /* If we are using the malloc debug code we can't use
           SIGUSR1 and SIGUSR2 to do debug level changes. */
        
-#ifndef MEM_MAN
 #if defined(SIGUSR1)
        CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
 #endif /* SIGUSR1 */
@@ -692,7 +731,6 @@ static void usage(char *pname)
 #if defined(SIGUSR2)
        CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
 #endif /* SIGUSR2 */
-#endif /* MEM_MAN */
 
        DEBUG(3,( "loaded services\n"));
 
@@ -719,9 +757,18 @@ static void usage(char *pname)
        if (!open_sockets(is_daemon,port,port445))
                exit(1);
 
+       /*
+        * Note that this call should be done after the fork() call
+        * in open_sockets(), as some versions of the locking shared
+        * memory code register openers in a flat file.
+        */ 
+
        if (!locking_init(0))
                exit(1);
 
+       if(!pwdb_initialise(True))
+               exit(1);
+
        /* possibly reload the services file. */
        reload_services(True);
        
index 58543ff32745e0e072e1aea02ff3c9845d344c01..3cb36e05941ad7d9d580f8cee4825e8114cd37e0 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    service (connection) opening and closing
-   Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Andrew Tridgell 1992-2000
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 extern int DEBUGLEVEL;
 
-extern time_t smb_last_time;
+extern struct timeval smb_last_time;
 extern int case_default;
 extern BOOL case_preserve;
 extern BOOL short_case_preserve;
@@ -54,7 +54,7 @@ BOOL become_service(connection_struct *conn,BOOL do_chdir)
                return(False);
        }
 
-       conn->lastused = smb_last_time;
+       conn->lastused = smb_last_time.tv_sec;
 
        snum = SNUM(conn);
   
@@ -89,7 +89,7 @@ int find_service(char *service)
 {
    int iService;
 
-   string_sub(service,"\\","/");
+   all_string_sub(service,"\\","/",0);
 
    iService = lp_servicenumber(service);
 
@@ -99,7 +99,7 @@ int find_service(char *service)
       char *phome_dir = get_unixhome_dir(service);
        pstring home_dir;
 
-      if(phome_dir == NULL)
+      if(!phome_dir)
       {
         /*
          * Try mapping the servicename, it may
@@ -173,7 +173,7 @@ int find_service(char *service)
        iService = find_service(defservice);
        if (iService >= 0)
        {
-         string_sub(service,"_","/");
+         all_string_sub(service,"_","/",0);
          iService = lp_add_service(service,iService);
        }
      }
@@ -315,13 +315,13 @@ connection_struct *make_connection(char *service,char *user,
        {
                pstring list;
                StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
-               string_sub(list,"%S",service);
+               pstring_sub(list,"%S",service);
 
                if (user_in_list(user,list))
                        conn->read_only = True;
                
                StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
-               string_sub(list,"%S",service);
+               pstring_sub(list,"%S",service);
                
                if (user_in_list(user,list))
                        conn->read_only = False;    
@@ -362,6 +362,36 @@ connection_struct *make_connection(char *service,char *user,
        string_set(&conn->dirpath,"");
        string_set(&conn->user,user);
 
+        conn->vfs_conn = (struct vfs_connection_struct *)
+            malloc(sizeof(struct vfs_connection_struct));
+
+        if (conn->vfs_conn == NULL) {
+            DEBUG(0, ("No memory to create vfs_connection_struct"));
+            return NULL;
+        }
+        
+        ZERO_STRUCTP(conn->vfs_conn);
+
+        /* Copy across relevant data from connection struct */
+        
+        conn->vfs_conn->printer = conn->printer;
+        conn->vfs_conn->ipc = conn->ipc;
+        conn->vfs_conn->read_only = conn->read_only;
+        conn->vfs_conn->admin_user = conn->admin_user;
+
+        pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
+        pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
+        pstrcpy(conn->vfs_conn->origpath, conn->origpath);
+        
+        pstrcpy(conn->vfs_conn->service, service);
+        pstrcpy(conn->vfs_conn->user, conn->user);
+        
+        conn->vfs_conn->uid = conn->uid;
+        conn->vfs_conn->gid = conn->gid;
+        conn->vfs_conn->ngroups = conn->ngroups;
+        conn->vfs_conn->groups = (gid_t *)memdup(conn->groups, 
+                                                 conn->ngroups * sizeof(gid_t));
+
        /* Initialise VFS function pointers */
 
        if (*lp_vfsobj(SNUM(conn))) {
@@ -386,40 +416,83 @@ connection_struct *make_connection(char *service,char *user,
            vfs_init_default(conn);
        }
 
+       /*
+        * If force user is true, then store the
+        * given userid and also the primary groupid
+        * of the user we're forcing.
+        */
+       
+       if (*lp_force_user(snum))
+       {
+               const struct passwd *pass2;
+               pstring fuser;
+               pstrcpy(fuser,lp_force_user(snum));
+
+               /* Allow %S to be used by force user. */
+               pstring_sub(fuser,"%S",service);
+
+               pass2 = Get_Pwnam(fuser,True);
+               if (pass2) {
+                       conn->uid = pass2->pw_uid;
+                       conn->gid = pass2->pw_gid;
+                       string_set(&conn->user,fuser);
+                       fstrcpy(user,fuser);
+                       conn->force_user = True;
+                       DEBUG(3,("Forced user %s\n",fuser));      
+               } else {
+                       DEBUG(1,("Couldn't find user %s\n",fuser));
+               }
+       }
+
 #ifdef HAVE_GETGRNAM 
+       /*
+        * If force group is true, then override
+        * any groupid stored for the connecting user.
+        */
+       
        if (*lp_force_group(snum)) {
                struct group *gptr;
                pstring gname;
+               pstring tmp_gname;
+               BOOL user_must_be_member = False;
                
-               StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
+               StrnCpy(tmp_gname,lp_force_group(snum),sizeof(pstring)-1);
+
+               if (tmp_gname[0] == '+') {
+                       user_must_be_member = True;
+                       StrnCpy(gname,&tmp_gname[1],sizeof(pstring)-2);
+               } else {
+                       StrnCpy(gname,tmp_gname,sizeof(pstring)-1);
+               }
                /* default service may be a group name          */
-               string_sub(gname,"%S",service);
+               pstring_sub(gname,"%S",service);
                gptr = (struct group *)getgrnam(gname);
                
                if (gptr) {
+                       /*
+                        * If the user has been forced and the forced group starts
+                        * with a '+', then we only set the group to be the forced
+                        * group if the forced user is a member of that group.
+                        * Otherwise, the meaning of the '+' would be ignored.
+                        */
+                       if (conn->force_user && user_must_be_member) {
+                               int i;
+                               for (i = 0; gptr->gr_mem[i] != NULL; i++) {
+                                       if (strcmp(user,gptr->gr_mem[i]) == 0) {
                        conn->gid = gptr->gr_gid;
-                       DEBUG(3,("Forced group %s\n",gname));
-               } else {
-                       DEBUG(1,("Couldn't find group %s\n",gname));
+                                               DEBUG(3,("Forced group %s for member %s\n",gname,user));
+                                               break;
                }
        }
-#endif
-       
-       if (*lp_force_user(snum)) {
-               const struct passwd *pass2;
-               fstring fuser;
-               fstrcpy(fuser,lp_force_user(snum));
-               pass2 = (const struct passwd *)Get_Pwnam(fuser,True);
-               if (pass2) {
-                       conn->uid = pass2->pw_uid;
-                       string_set(&conn->user,fuser);
-                       fstrcpy(user,fuser);
-                       conn->force_user = True;
-                       DEBUG(3,("Forced user %s\n",fuser));      
                } else {
-                       DEBUG(1,("Couldn't find user %s\n",fuser));
+                               conn->gid = gptr->gr_gid;
+                               DEBUG(3,("Forced group %s\n",gname));
+                       }
+               } else {
+                       DEBUG(1,("Couldn't find group %s\n",gname));
                }
        }
+#endif /* HAVE_GETGRNAM */
 
        {
                pstring s;
@@ -453,20 +526,27 @@ connection_struct *make_connection(char *service,char *user,
                }  
                
                if (lp_status(SNUM(conn)))
-                       claim_connection(conn,"STATUS.",
+                       claim_connection(conn,"",
                                         MAXSTATUS,False);
        } /* IS_IPC */
        
        /* execute any "root preexec = " line */
        if (*lp_rootpreexec(SNUM(conn)))
        {
+               BOOL ret;
                pstring cmd;
                user_struct *vuser = get_valid_user_struct(&key);
                pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
                standard_sub(conn,vuser, cmd);
                vuid_free_user_struct(vuser);
                DEBUG(5,("cmd=%s\n",cmd));
-               smbrun(cmd,NULL,False);
+               ret = smbrun(cmd,NULL,False);
+               if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
+                       DEBUG(1,("preexec gave %d - failing connection\n", ret));
+                       conn_free(conn);
+                       *ecode = ERRsrverror;
+                       return NULL;
+               }
        }
        
        if (!become_user(conn, conn->vuid)) {
@@ -476,7 +556,7 @@ connection_struct *make_connection(char *service,char *user,
                                         lp_servicename(SNUM(conn)),
                                         lp_max_connections(SNUM(conn)));
                        if (lp_status(SNUM(conn))) {
-                               yield_connection(conn,"STATUS.",MAXSTATUS);
+                               yield_connection(conn,"",MAXSTATUS);
                        }
                }
                conn_free(conn);
@@ -493,7 +573,7 @@ connection_struct *make_connection(char *service,char *user,
                                         lp_servicename(SNUM(conn)),
                                         lp_max_connections(SNUM(conn)));
                        if (lp_status(SNUM(conn))) 
-                               yield_connection(conn,"STATUS.",MAXSTATUS);
+                               yield_connection(conn,"",MAXSTATUS);
                }
                conn_free(conn);
                *ecode = ERRinvnetname;
@@ -536,12 +616,32 @@ connection_struct *make_connection(char *service,char *user,
        /* execute any "preexec = " line */
        if (*lp_preexec(SNUM(conn)))
        {
+               BOOL ret;
                pstring cmd;
                user_struct *vuser = get_valid_user_struct(&key);
                pstrcpy(cmd,lp_preexec(SNUM(conn)));
                standard_sub(conn,vuser, cmd);
                vuid_free_user_struct(vuser);
-               smbrun(cmd,NULL,False);
+               ret = smbrun(cmd,NULL,False);
+               if (ret != 0 && lp_preexec_close(SNUM(conn))) {
+                       DEBUG(1,("preexec gave %d - failing connection\n", ret));
+                       conn_free(conn);
+                       *ecode = ERRsrverror;
+                       return NULL;
+               }
+       }
+
+       /*
+        * Print out the 'connected as' stuff here as we need
+        * to know the effective uid and gid we will be using.
+        */
+
+       if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
+               dbgtext( "%s (%s) ", remote_machine, conn->client_address );
+               dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
+               dbgtext( "as user %s ", user );
+               dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
+               dbgtext( "(pid %d)\n", (int)getpid() );
        }
        
        /* we've finished with the sensitive stuff */
@@ -554,53 +654,10 @@ connection_struct *make_connection(char *service,char *user,
                set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn)));
        }
        
-       if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
-               
-               dbgtext( "%s (%s) ", remote_machine, client_connection_addr() );
-               dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)));
-               dbgtext( "as user %s ", user );
-               dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid );
-               dbgtext( "(pid %d)\n", (int)key.pid );
-       }
-
-       /* Invoke make connection hook */
+       /* Invoke VFS make connection hook */
 
        if (conn->vfs_ops.connect) {
-           struct vfs_connection_struct *vconn;
-
-           vconn = (struct vfs_connection_struct *)
-               malloc(sizeof(struct vfs_connection_struct));
-
-           if (vconn == NULL) {
-               DEBUG(0, ("No memory to create vfs_connection_struct"));
-               return NULL;
-           }
-
-           ZERO_STRUCTP(vconn);
-
-           /* Copy across relevant data from connection struct */
-
-           vconn->printer = conn->printer;
-           vconn->ipc = conn->ipc;
-           vconn->read_only = conn->read_only;
-           vconn->admin_user = conn->admin_user;
-
-           pstrcpy(vconn->dirpath, conn->dirpath);
-           pstrcpy(vconn->connectpath, conn->connectpath);
-           pstrcpy(vconn->origpath, conn->origpath);
-
-           pstrcpy(vconn->service, service);
-           pstrcpy(vconn->user, conn->user);
-
-           vconn->uid = conn->uid;
-           vconn->gid = conn->gid;
-           vconn->ngroups = conn->ngroups;
-           vconn->groups = (gid_t *)memdup(conn->groups,
-                                           conn->ngroups * sizeof(gid_t));
-
-           /* Call connect hook */
-           
-           if (conn->vfs_ops.connect(vconn, service, user) < 0) {
+            if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) {
                return NULL;
            }
        }
@@ -626,10 +683,18 @@ void close_cnum(connection_struct *conn, uint16 vuid)
 
        if (conn->vfs_ops.disconnect != NULL) {
 
-           /* Call disconnect hook */
+           /* Call VFS disconnect hook */
            
            conn->vfs_ops.disconnect();
            
+       }
+
+        /* Close dlopen() handle */
+
+        if (conn->vfs_conn->dl_handle != NULL) {
+            dlclose(conn->vfs_conn->dl_handle);  /* should we check return val? */
+        }
+
            /* Free vfs_connection_struct */
            
            if (conn->vfs_conn != NULL) {
@@ -638,14 +703,13 @@ void close_cnum(connection_struct *conn, uint16 vuid)
                }
                free(conn->vfs_conn);
            }
-       }
 
        yield_connection(conn,
                         lp_servicename(SNUM(conn)),
                         lp_max_connections(SNUM(conn)));
 
        if (lp_status(SNUM(conn)))
-               yield_connection(conn,"STATUS.",MAXSTATUS);
+               yield_connection(conn,"",MAXSTATUS);
 
        file_close_conn(conn);
        dptr_closecnum(conn);
index 1f098b2533d9345ad893386b3d76eb6c4d618865..be9aae7c5c321c339aaba6f1beef156afe9eebc9 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include "includes.h"
-
-/*
- * Hmmm, only check on WITH_SSL after we have included includes.h
- * which pulls in config.h which is where WITH_SSL is defined, if 
- * at all :-)
+/* 
+ * since includes.h pulls in config.h which is were WITH_SSL will be 
+ * defined, we want to include includes.h before testing for WITH_SSL
+ * RJS 26-Jan-1999
  */
 
+#include "includes.h"
+
 #ifdef WITH_SSL  /* should always be defined if this module is compiled */
 
 #include <ssl.h>
index 21ec4c2517844f74a0c950caeff9374f9a10525b..e6ee65d101d6a63a8d49fe30c9e25ecedfd079df 100644 (file)
@@ -22,7 +22,6 @@
 */
 
 #include "includes.h"
-#include "nterr.h"
 #include "trans2.h"
 
 extern int DEBUGLEVEL;
@@ -32,7 +31,7 @@ extern int Client;
 extern int smb_read_error;
 extern fstring local_machine;
 extern int global_oplock_break;
-extern dfs_internal dfs_struct;
+extern uint32 global_client_caps;
 
 /****************************************************************************
   Send the required number of replies back.
@@ -96,7 +95,14 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
     total_sent_thistime = params_to_send + data_to_send + 
                             alignment_offset + data_alignment_offset;
     /* We can never send more than useable_space */
-    total_sent_thistime = MIN(total_sent_thistime, useable_space);
+    /*
+     * Note that 'useable_space' does not include the alignment offsets,
+     * but we must include the alignment offsets in the calculation of
+     * the length of the data we send over the wire, as the alignment offsets
+     * are sent here. Fix from Marc_Jacobsen@hp.com.
+     */
+    total_sent_thistime = MIN(total_sent_thistime, useable_space+
+                               alignment_offset + data_alignment_offset);
 
     set_message(outbuf, 10, total_sent_thistime, True);
 
@@ -112,22 +118,19 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
     data_sent_thistime = MIN(data_sent_thistime,data_to_send);
 
     SSVAL(outbuf,smb_prcnt, params_sent_thistime);
+
+    /* smb_proff is the offset from the start of the SMB header to the
+       parameter bytes, however the first 4 bytes of outbuf are
+       the Netbios over TCP header. Thus use smb_base() to subtract
+       them from the calculation */
+
+    SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
+
     if(params_sent_thistime == 0)
-    {
-      /*SSVAL(outbuf,smb_proff,0);*/
-      SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
       SSVAL(outbuf,smb_prdisp,0);
-    }
     else
-    {
-      /* smb_proff is the offset from the start of the SMB header to the
-         parameter bytes, however the first 4 bytes of outbuf are
-         the Netbios over TCP header. Thus use smb_base() to subtract
-         them from the calculation */
-      SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
       /* Absolute displacement of param bytes sent in this packet */
       SSVAL(outbuf,smb_prdisp,pp - params);
-    }
 
     SSVAL(outbuf,smb_drcnt, data_sent_thistime);
     if(data_sent_thistime == 0)
@@ -217,11 +220,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
 
   /* XXXX we need to handle passed times, sattr and flags */
 
-  if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+  unix_convert(fname,conn,0,&bad_path,NULL);
     
   fsp = file_new();
   if (!fsp)
@@ -238,7 +237,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  unixmode = unix_mode(conn,open_attr | aARCH);
+  unixmode = unix_mode(conn,open_attr | aARCH, fname);
       
   open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
                   oplock_request, &rmode,&smb_action);
@@ -273,7 +272,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
   if(params == NULL)
     return(ERROR(ERRDOS,ERRnomem));
 
-  memset(params, 0, 28);
+  memset((char *)params,'\0',28);
   SSVAL(params,0,fsp->fnum);
   SSVAL(params,2,fmode);
   put_dos_date2(params,4, mtime);
@@ -299,12 +298,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
 /****************************************************************************
   get a level dependent lanman2 dir entry.
 ****************************************************************************/
-static int get_lanman2_dir_entry(connection_struct *conn,
+static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                 char *path_mask,int dirtype,int info_level,
                                 int requires_resume_key,
                                 BOOL dont_descend,char **ppdata, 
                                 char *base_data, int space_remaining, 
-                                BOOL *out_of_space,
+                                BOOL *out_of_space, BOOL *got_exact_match,
                                 int *last_name_off)
 {
   char *dname;
@@ -330,6 +329,7 @@ static int get_lanman2_dir_entry(connection_struct *conn,
 
   *fname = 0;
   *out_of_space = False;
+  *got_exact_match = False;
 
   if (!conn->dirptr)
     return(False);
@@ -347,6 +347,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
 
   while (!found)
   {
+    BOOL got_match;
+
     /* Needed if we run out of space */
     prev_dirpos = TellDir(conn->dirptr);
     dname = ReadDirName(conn->dirptr);
@@ -368,7 +370,26 @@ static int get_lanman2_dir_entry(connection_struct *conn,
 
     pstrcpy(fname,dname);      
 
-    if(mask_match(fname, mask, case_sensitive, True))
+    if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
+      got_match = mask_match(fname, mask, case_sensitive, True);
+
+    if(!got_match && !is_8_3(fname, False)) {
+
+      /*
+       * It turns out that NT matches wildcards against
+       * both long *and* short names. This may explain some
+       * of the wildcard wierdness from old DOS clients
+       * that some people have been seeing.... JRA.
+       */
+
+      pstring newname;
+      pstrcpy( newname, fname);
+      name_map_mangle( newname, True, False, SNUM(conn));
+      if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
+        got_match = mask_match(newname, mask, case_sensitive, True);
+    }
+
+    if(got_match)
     {
       BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
       if (dont_descend && !isdots)
@@ -407,7 +428,7 @@ static int get_lanman2_dir_entry(connection_struct *conn,
     }
   }
 
-  name_map_mangle(fname,False,SNUM(conn));
+  name_map_mangle(fname,False,True,SNUM(conn));
 
   p = pdata;
   nameptr = p;
@@ -503,7 +524,7 @@ static int get_lanman2_dir_entry(connection_struct *conn,
       SIVAL(p,0,0); p += 4;
       if (!was_8_3) {
         pstrcpy(p+2,fname);
-        if (!name_map_mangle(p+2,True,SNUM(conn)))
+        if (!name_map_mangle(p+2,True,True,SNUM(conn)))
           (p+2)[12] = 0;
       } else
         *(p+2) = 0;
@@ -580,6 +601,7 @@ static int get_lanman2_dir_entry(connection_struct *conn,
   *last_name_off = PTR_DIFF(nameptr,base_data);
   /* Advance the data pointer to the next slot */
   *ppdata = p;
+
   return(found);
 }
   
@@ -611,8 +633,9 @@ void mask_convert( char *mask)
 }
 
 /****************************************************************************
-  reply to a TRANS2_FINDFIRST
+ Reply to a TRANS2_FINDFIRST.
 ****************************************************************************/
+
 static int call_trans2findfirst(connection_struct *conn,
                                char *inbuf, char *outbuf, int bufsize,  
                                char **pparams, char **ppdata)
@@ -668,13 +691,11 @@ static int call_trans2findfirst(connection_struct *conn,
   pstrcpy(directory, params + 12); /* Complete directory path with 
                                     wildcard mask appended */
 
+  RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+
   DEBUG(5,("path=%s\n",directory));
 
-  if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+  unix_convert(directory,conn,0,&bad_path,NULL);
   if(!check_name(directory,conn)) {
     if((errno == ENOENT) && bad_path)
     {
@@ -709,40 +730,25 @@ static int call_trans2findfirst(connection_struct *conn,
   pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
   if(!*ppdata)
     return(ERROR(ERRDOS,ERRnomem));
-  memset(pdata, 0, max_data_bytes);
+  memset((char *)pdata,'\0',max_data_bytes + 1024);
 
   /* Realloc the params space */
   params = *pparams = Realloc(*pparams, 10);
   if(params == NULL)
     return(ERROR(ERRDOS,ERRnomem));
 
-  dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
+  dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
   if (dptr_num < 0)
     return(UNIXERROR(ERRDOS,ERRbadfile));
 
   /* Convert the formatted mask. */
   mask_convert(mask);
 
-#if 0 /* JRA */
-  /*
-   * Now we have a working mask_match in util.c, I believe
-   * we no longer need these hacks (in fact they break
-   * things). JRA. 
-   */
-
-  /* a special case for 16 bit apps */
-  if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
-
-  /* handle broken clients that send us old 8.3 format */
-  string_sub(mask,"????????","*");
-  string_sub(mask,".???",".*");
-#endif /* JRA */
-
   /* Save the wildcard match and attribs we are using on this directory - 
      needed as lanman2 assumes these are being saved between calls */
 
   if(!(wcard = strdup(mask))) {
-    dptr_close(dptr_num);
+    dptr_close(&dptr_num);
     return(ERROR(ERRDOS,ERRnomem));
   }
 
@@ -764,39 +770,49 @@ static int call_trans2findfirst(connection_struct *conn,
   out_of_space = False;
 
   for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
+  {
+    BOOL got_exact_match;
+
+    /* this is a heuristic to avoid seeking the dirptr except when 
+       absolutely necessary. It allows for a filename of about 40 chars */
+    if (space_remaining < DIRLEN_GUESS && numentries > 0)
     {
+      out_of_space = True;
+      finished = False;
+    }
+    else
+    {
+      finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+                   requires_resume_key,dont_descend,
+                   &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+                   &last_name_off);
+    }
 
-      /* this is a heuristic to avoid seeking the dirptr except when 
-        absolutely necessary. It allows for a filename of about 40 chars */
-      if (space_remaining < DIRLEN_GUESS && numentries > 0)
-       {
-         out_of_space = True;
-         finished = False;
-       }
-      else
-       {
-         finished = 
-           !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
-                                  requires_resume_key,dont_descend,
-                                  &p,pdata,space_remaining, &out_of_space,
-                                  &last_name_off);
-       }
+    if (finished && out_of_space)
+      finished = False;
 
-      if (finished && out_of_space)
-       finished = False;
+    if (!finished && !out_of_space)
+      numentries++;
 
-      if (!finished && !out_of_space)
-       numentries++;
-      space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
-    }
+    /*
+     * As an optimisation if we know we aren't looking
+     * for a wildcard name (ie. the name matches the wildcard exactly)
+     * then we can finish on any (first) match.
+     * This speeds up large directory searches. JRA.
+     */
+
+    if(got_exact_match)
+      finished = True;
+
+    space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+  }
   
   /* Check if we can close the dirptr */
   if(close_after_first || (finished && close_if_end))
-    {
-      dptr_close(dptr_num);
-      DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
-      dptr_num = -1;
-    }
+  {
+    DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
+    dptr_close(&dptr_num);
+  }
 
   /* 
    * If there are no matching entries we must return ERRDOS/ERRbadfile - 
@@ -804,7 +820,10 @@ static int call_trans2findfirst(connection_struct *conn,
    */
 
   if(numentries == 0)
+  {
+    dptr_close(&dptr_num);
     return(ERROR(ERRDOS,ERRbadfile));
+  }
 
   /* At this point pdata points to numentries directory entries. */
 
@@ -824,6 +843,17 @@ static int call_trans2findfirst(connection_struct *conn,
            smb_fn_name(CVAL(inbuf,smb_com)), 
            mask, directory, dirtype, numentries ) );
 
+  /* 
+   * Force a name mangle here to ensure that the
+   * mask as an 8.3 name is top of the mangled cache.
+   * The reasons for this are subtle. Don't remove
+   * this code unless you know what you are doing
+   * (see PR#13758). JRA.
+   */
+
+  if(!is_8_3( mask, False))
+    name_map_mangle(mask, True, True, SNUM(conn));
+
   return(-1);
 }
 
@@ -844,7 +874,7 @@ static int call_trans2findnext(connection_struct *conn,
   int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
   char *params = *pparams;
   char *pdata = *ppdata;
-  int16 dptr_num = SVAL(params,0);
+  int dptr_num = SVAL(params,0);
   int maxentries = SVAL(params,2);
   uint16 info_level = SVAL(params,4);
   uint32 resume_key = IVAL(params,6);
@@ -892,7 +922,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
   pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
   if(!*ppdata)
     return(ERROR(ERRDOS,ERRnomem));
-  memset(pdata, 0, max_data_bytes);
+  memset((char *)pdata,'\0',max_data_bytes + 1024);
 
   /* Realloc the params space */
   params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
@@ -969,7 +999,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
        */
 
       if(dname != NULL)
-        name_map_mangle( dname, False, SNUM(conn));
+        name_map_mangle( dname, False, True, SNUM(conn));
 
       if(dname && strcsequal( resume_name, dname))
       {
@@ -997,7 +1027,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
          */
 
         if(dname != NULL)
-          name_map_mangle( dname, False, SNUM(conn));
+          name_map_mangle( dname, False, True, SNUM(conn));
 
         if(dname && strcsequal( resume_name, dname))
         {
@@ -1010,38 +1040,49 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
   } /* end if requires_resume_key && !continue_bit */
 
   for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
+  {
+    BOOL got_exact_match;
+
+    /* this is a heuristic to avoid seeking the dirptr except when 
+       absolutely necessary. It allows for a filename of about 40 chars */
+    if (space_remaining < DIRLEN_GUESS && numentries > 0)
     {
-      /* this is a heuristic to avoid seeking the dirptr except when 
-        absolutely necessary. It allows for a filename of about 40 chars */
-      if (space_remaining < DIRLEN_GUESS && numentries > 0)
-       {
-         out_of_space = True;
-         finished = False;
-       }
-      else
-       {
-         finished = 
-           !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
-                                  requires_resume_key,dont_descend,
-                                  &p,pdata,space_remaining, &out_of_space,
-                                  &last_name_off);
-       }
+      out_of_space = True;
+      finished = False;
+    }
+    else
+    {
+      finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+                   requires_resume_key,dont_descend,
+                   &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+                   &last_name_off);
+    }
 
-      if (finished && out_of_space)
-       finished = False;
+    if (finished && out_of_space)
+      finished = False;
 
-      if (!finished && !out_of_space)
-       numentries++;
-      space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
-    }
+    if (!finished && !out_of_space)
+      numentries++;
+
+    /*
+     * As an optimisation if we know we aren't looking
+     * for a wildcard name (ie. the name matches the wildcard exactly)
+     * then we can finish on any (first) match.
+     * This speeds up large directory searches. JRA.
+     */
+
+    if(got_exact_match)
+      finished = True;
+
+    space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+  }
   
   /* Check if we can close the dirptr */
   if(close_after_request || (finished && close_if_end))
-    {
-      dptr_close(dptr_num); /* This frees up the saved mask */
-      DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
-      dptr_num = -1;
-    }
+  {
+    DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
+    dptr_close(&dptr_num); /* This frees up the saved mask */
+  }
 
 
   /* Set up the return parameter block */
@@ -1071,6 +1112,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
                              int length, int bufsize,
                              char **pparams, char **ppdata)
 {
+  int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
   char *pdata = *ppdata;
   char *params = *pparams;
   uint16 info_level = SVAL(params,0);
@@ -1079,7 +1121,6 @@ static int call_trans2qfsinfo(connection_struct *conn,
   char *vname = volume_label(SNUM(conn));
   int snum = SNUM(conn);
   char *fstype = lp_fstype(SNUM(conn));
-  extern uint32 global_client_caps;
 
   DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
 
@@ -1088,7 +1129,8 @@ static int call_trans2qfsinfo(connection_struct *conn,
     return (ERROR(ERRSRV,ERRinvdevice));
   }
 
-  pdata = *ppdata = Realloc(*ppdata, 1024); memset(pdata, 0, 1024);
+  pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
+  memset((char *)pdata,'\0',max_data_bytes + 1024);
 
   switch (info_level) 
   {
@@ -1096,7 +1138,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
     {
       SMB_BIG_UINT dfree,dsize,bsize;
       data_len = 18;
-      conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);       
+      conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); 
       SIVAL(pdata,l1_idFileSystem,st.st_dev);
       SIVAL(pdata,l1_cSectorUnit,bsize/512);
       SIVAL(pdata,l1_cUnit,dsize);
@@ -1125,16 +1167,22 @@ static int call_trans2qfsinfo(connection_struct *conn,
       break;
     }
     case SMB_QUERY_FS_ATTRIBUTE_INFO:
-      data_len = 12 + 2*strlen(fstype);
-      SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH); /* FS ATTRIBUTES */
+    {
+      int fstype_len;
+      SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
+                       FILE_DEVICE_IS_MOUNTED|
+            (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
 #if 0 /* Old code. JRA. */
       SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
 #endif /* Old code. */
+
       SIVAL(pdata,4,128); /* Max filename component length */
-      SIVAL(pdata,8,2*strlen(fstype));
-      ascii_to_unibuf(pdata+12, fstype, 1024-2-12);
+      fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
+      SIVAL(pdata,8,fstype_len);
+      data_len = 12 + fstype_len;
       SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
       break;
+    }
     case SMB_QUERY_FS_LABEL_INFO:
       data_len = 4 + strlen(vname);
       SIVAL(pdata,0,strlen(vname));
@@ -1152,26 +1200,27 @@ static int call_trans2qfsinfo(connection_struct *conn,
       /* NT4 always serves this up as unicode but expects it to be
        * delivered as ascii! (tridge && JRA)
        */
-      if (global_client_caps & CAP_NT_SMBS) {
+      if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
              data_len = 18 + strlen(vname);
              SIVAL(pdata,12,strlen(vname));
              pstrcpy(pdata+18,vname);      
       } else {
              data_len = 18 + 2*strlen(vname);
              SIVAL(pdata,12,strlen(vname)*2);
-             ascii_to_unibuf(pdata+18, vname, 1024-2-18);
+             dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring), False);
+                 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
       }
 
       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", 
-              strlen(vname),vname));
+              (int)strlen(vname),vname));
       break;
     case SMB_QUERY_FS_SIZE_INFO:
     {
       SMB_BIG_UINT dfree,dsize,bsize;
       data_len = 24;
-      conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);       
-      SIVAL(pdata,0,dsize);
-      SIVAL(pdata,8,dfree);
+      conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize); 
+      SBIG_UINT(pdata,0,dsize);
+      SBIG_UINT(pdata,8,dfree);
       SIVAL(pdata,16,bsize/512);
       SIVAL(pdata,20,512);
       break;
@@ -1237,6 +1286,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
                                    char **pparams,char **ppdata,
                                    int total_data)
 {
+  int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
   char *params = *pparams;
   char *pdata = *ppdata;
   uint16 tran_call = SVAL(inbuf, smb_setup0);
@@ -1257,20 +1307,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
     files_struct *fsp = file_fsp(params,0);
     info_level = SVAL(params,2);
 
-    if(fsp && fsp->open && fsp->is_directory) {
+    DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+    if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
       /*
        * This is actually a QFILEINFO on a directory
        * handle (returned from an NT SMB). NT5.0 seems
        * to do this call. JRA.
        */
       fname = fsp->fsp_name;
-      if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
-      if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && 
-         conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
+      unix_convert(fname,conn,0,&bad_path,&sbuf);
+      if (!check_name(fname,conn) || 
+          (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1279,6 +1327,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
         }
         return(UNIXERROR(ERRDOS,ERRbadpath));
       }
+
+      delete_pending = fsp->directory_delete_on_close;
+
     } else {
       /*
        * Original code - this is an open file.
@@ -1299,16 +1350,17 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
   } else {
     /* qpathinfo */
     info_level = SVAL(params,0);
+
+    DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+
     fname = &fname1[0];
     pstrcpy(fname,&params[6]);
-    if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+
+    RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+
+    unix_convert(fname,conn,0,&bad_path,&sbuf);
     if (!check_name(fname,conn) || 
-       (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),
-                                                &sbuf))) {
+        (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1336,8 +1388,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
   /* from now on we only want the part after the / */
   fname = p;
   
-  params = *pparams = Realloc(*pparams,2); memset(params, 0, 2);
-  data_size = 1024;
+  params = *pparams = Realloc(*pparams,2);
+  memset((char *)params,'\0',2);
+  data_size = max_data_bytes + 1024;
   pdata = *ppdata = Realloc(*ppdata, data_size); 
 
   if (total_data > 0 && IVAL(pdata,0) == total_data) {
@@ -1346,7 +1399,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
   }
 
-  memset(pdata, 0, data_size);
+  memset((char *)pdata,'\0',data_size);
 
   switch (info_level) 
     {
@@ -1417,26 +1470,37 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
     case SMB_QUERY_FILE_ALT_NAME_INFO:
       {
         pstring short_name;
-        char *data_end;
-
         pstrcpy(short_name,p);
         /* Mangle if not already 8.3 */
         if(!is_8_3(short_name, True))
         {
-          if(!name_map_mangle(short_name,True,SNUM(conn)))
+          if(!name_map_mangle(short_name,True,True,SNUM(conn)))
             *short_name = '\0';
         }
         strupper(short_name);
-        data_end = ascii_to_unibuf(pdata + 4, short_name, 1024-2-4);
-        data_size = data_end - pdata;
-        SIVAL(pdata,0,2*(data_size-4));
+        l = strlen(short_name);
+        dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring), False);
+        data_size = 4 + (2*l);
+        SIVAL(pdata,0,2*l);
       }
       break;
 
     case SMB_QUERY_FILE_NAME_INFO:
+      /*
+       * The first part of this code is essential
+       * to get security descriptors to work on mapped
+       * drives. Don't ask how I discovered this unless
+       * you like hearing about me suffering.... :-). JRA.
+       */
+      if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
+        l = l*2;
+        SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+        dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring), False);
+      } else {
+        pstrcpy(pdata+4,fname);
+      }
       data_size = 4 + l;
       SIVAL(pdata,0,l);
-      pstrcpy(pdata+4,fname);
       break;
 
     case SMB_QUERY_FILE_ALLOCATION_INFO:
@@ -1528,20 +1592,16 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
     fsp = file_fsp(params,0);
     info_level = SVAL(params,2);    
 
-    if(fsp && fsp->open && fsp->is_directory) {
+    if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
       /*
        * This is actually a SETFILEINFO on a directory
        * handle (returned from an NT SMB). NT5.0 seems
        * to do this call. JRA.
        */
       fname = fsp->fsp_name;
-      if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
-      if (!check_name(fname,conn) || (!VALID_STAT(st) && 
-                                     conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
+      unix_convert(fname,conn,0,&bad_path,&st);
+      if (!check_name(fname,conn) || 
+          (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1570,11 +1630,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
     info_level = SVAL(params,0);    
     fname = fname1;
     pstrcpy(fname,&params[6]);
-    if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+    unix_convert(fname,conn,0,&bad_path,&st);
     if(!check_name(fname, conn))
     {
       if((errno == ENOENT) && bad_path)
@@ -1600,10 +1656,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
           tran_call,fname,info_level,total_data));
 
   /* Realloc the parameter and data sizes */
-  params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
+  params = *pparams = Realloc(*pparams,2);
   if(params == NULL)
     return(ERROR(ERRDOS,ERRnomem));
 
+  SSVAL(params,0,0);
+
   size = st.st_size;
   tvs.modtime = st.st_mtime;
   tvs.actime = st.st_atime;
@@ -1651,14 +1709,25 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
 
     case SMB_SET_FILE_BASIC_INFO:
     {
+      /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
+      time_t write_time;
+      time_t changed_time;
+
       /* Ignore create time at offset pdata. */
 
       /* access time */
       tvs.actime = interpret_long_date(pdata+8);
 
-      /* write time + changed time, combined. */
-      tvs.modtime=MAX(interpret_long_date(pdata+16),
-                      interpret_long_date(pdata+24));
+      write_time = interpret_long_date(pdata+16);
+      changed_time = interpret_long_date(pdata+24);
+
+      tvs.modtime = MIN(write_time, changed_time);
+
+      /* Prefer a defined time to an undefined one. */
+      if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+       tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
+                      ? changed_time
+                      : write_time);
 
 #if 0 /* Needs more testing... */
       /* Test from Luke to prevent Win95 from
@@ -1673,6 +1742,26 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       break;
     }
 
+    /*
+     * NT seems to use this call with a size of zero
+     * to mean truncate the file. JRA.
+     */
+
+    case SMB_SET_FILE_ALLOCATION_INFO:
+    {
+      SMB_OFF_T newsize = IVAL(pdata,0);
+#ifdef LARGE_SMB_OFF_T
+      newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
+      if (IVAL(pdata,4) != 0)  /* more than 32 bits? */
+         return(ERROR(ERRDOS,ERRunknownlevel));
+#endif /* LARGE_SMB_OFF_T */
+      DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
+      if(newsize == 0)
+        size = 0;
+      break;
+    }
+
     case SMB_SET_FILE_END_OF_FILE_INFO:
     {
       size = IVAL(pdata,0);
@@ -1682,12 +1771,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       if (IVAL(pdata,4) != 0)  /* more than 32 bits? */
          return(ERROR(ERRDOS,ERRunknownlevel));
 #endif /* LARGE_SMB_OFF_T */
+      DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
       break;
     }
 
-    case SMB_SET_FILE_ALLOCATION_INFO:
-      break; /* We don't need to do anything for this call. */
-
     case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
     {
       if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
@@ -1695,121 +1782,133 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
         BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
 
         if(fsp->is_directory)
-          return(ERROR(ERRDOS,ERRnoaccess));
-
-        /*
-         * We can only set the delete on close flag if
-         * the share mode contained ALLOW_SHARE_DELETE
-         */
+        {
+          fsp->directory_delete_on_close = delete_on_close;
+          DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
+                delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
 
-        if(lp_share_modes(SNUM(conn)))
+        }
+       else if(fsp->stat_open)
+       {
+          DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
+                delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+       }
+        else
         {
-          if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
-            return(ERROR(ERRDOS,ERRnoaccess));
 
           /*
-           * If the flag has been set then
-           * modify the share mode entry for all files we have open
-           * on this device and inode to tell other smbds we have 
-           * changed the delete on close flag.
+           * We can only set the delete on close flag if
+           * the share mode contained ALLOW_SHARE_DELETE
            */
 
-          if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
+          if(lp_share_modes(SNUM(conn)))
           {
-            int i;
-            files_struct *iterate_fsp;
-            SMB_DEV_T dev = fsp->fd_ptr->dev;
-            SMB_INO_T inode = fsp->fd_ptr->inode;
-            int num_share_modes;
-            share_mode_entry *current_shares = NULL;
-
-            if(lock_share_entry(fsp->conn, dev, inode) == False)
+            if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
               return(ERROR(ERRDOS,ERRnoaccess));
 
             /*
-             * Before we allow this we need to ensure that all current opens
-             * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
-             * do not then we deny this (as we are essentially deleting the
-             * file at this point.
+             * If the flag has been set then
+             * modify the share mode entry for all files we have open
+             * on this device and inode to tell other smbds we have 
+             * changed the delete on close flag.
              */
 
-            num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
-            for(i = 0; i < num_share_modes; i++)
+            if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
             {
-              if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+              int i;
+              files_struct *iterate_fsp;
+              SMB_DEV_T dev = fsp->fd_ptr->dev;
+              SMB_INO_T inode = fsp->fd_ptr->inode;
+              int num_share_modes;
+              share_mode_entry *current_shares = NULL;
+
+              if(lock_share_entry(fsp->conn, dev, inode) == False)
+                return(ERROR(ERRDOS,ERRnoaccess));
+
+              /*
+               * Before we allow this we need to ensure that all current opens
+               * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
+               * do not then we deny this (as we are essentially deleting the
+               * file at this point.
+               */
+
+              num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
+              for(i = 0; i < num_share_modes; i++)
               {
-                DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
+                if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
+                {
+                  DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
 file %s as a share exists that was not opened with FILE_DELETE access.\n",
-                      fsp->fnum, fsp->fsp_name ));
-                /*
-                 * Release the lock.
-                 */
+                        fsp->fnum, fsp->fsp_name ));
+                  /*
+                   * Release the lock.
+                   */
 
-                unlock_share_entry(fsp->conn, dev, inode);
+                  unlock_share_entry(fsp->conn, dev, inode);
 
-                /*
-                 * current_shares was malloced by get_share_modes - free it here.
-                 */
+                  /*
+                   * current_shares was malloced by get_share_modes - free it here.
+                   */
 
-                free((char *)current_shares);
+                  free((char *)current_shares);
 
-                /*
-                 * Even though share violation would be more appropriate here,
-                 * return ERRnoaccess as that's what NT does.
-                 */
+                  /*
+                   * Even though share violation would be more appropriate here,
+                   * return ERRnoaccess as that's what NT does.
+                   */
 
-                return(ERROR(ERRDOS,ERRnoaccess));
+                  return(ERROR(ERRDOS,ERRnoaccess));
+                }
               }
-            }
 
-            /*
-             * current_shares was malloced by get_share_modes - free it here.
-             */
+              /*
+               * current_shares was malloced by get_share_modes - free it here.
+               */
 
-            free((char *)current_shares);
+              free((char *)current_shares);
 
-            DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
-                 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+              DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+                   delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
 
-            /*
-             * Go through all files we have open on the same device and
-             * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
-             * Other smbd's that have this file open will have to fend for themselves. We
-             * take care of this (rare) case in close_file(). See the comment there.
-             */
+              /*
+               * Go through all files we have open on the same device and
+               * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+               * Other smbd's that have this file open will have to fend for themselves. We
+               * take care of this (rare) case in close_file(). See the comment there.
+               */
 
-            for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
-                                  iterate_fsp = file_find_di_next(iterate_fsp))
-            {
-              int new_share_mode = (delete_on_close ? 
-                                    (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
-                                    (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
+              for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
+                                    iterate_fsp = file_find_di_next(iterate_fsp))
+              {
+                int new_share_mode = (delete_on_close ? 
+                                      (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
+                                      (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
 
-              DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
+                DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
 dev = %x, inode = %.0f from %x to %x\n", 
-                    iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev, 
-                    (double)inode, iterate_fsp->share_mode, new_share_mode ));
+                      iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev, 
+                      (double)inode, iterate_fsp->share_mode, new_share_mode ));
 
-              if(modify_share_mode(iterate_fsp, new_share_mode,
-                                   iterate_fsp->granted_oplock ? LEVEL_II_OPLOCK : NO_OPLOCK)==False)
-                DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+                if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
+                  DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
 dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
-            }
+              }
 
-            /*
-             * Set the delete on close flag in the reference
-             * counted struct. Delete when the last reference
-             * goes away.
-             */
-           fsp->fd_ptr->delete_on_close = delete_on_close;
-           unlock_share_entry(fsp->conn, dev, inode);
+              /*
+               * Set the delete on close flag in the reference
+               * counted struct. Delete when the last reference
+               * goes away.
+               */
+             fsp->fd_ptr->delete_on_close = delete_on_close;
 
-           DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
-                 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+             unlock_share_entry(fsp->conn, dev, inode);
 
-          } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
-        } /* end if lp_share_modes() */
+             DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+                   delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
 
+            } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
+          } /* end if lp_share_modes() */
+        } /* end if is_directory. */
       } else
         return(ERROR(ERRDOS,ERRunknownlevel));
       break;
@@ -1821,23 +1920,33 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
     }
   }
 
+  /* get some defaults (no modifications) if any info is zero or -1. */
+  if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
+    tvs.actime = st.st_atime;
+
+  if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+    tvs.modtime = st.st_mtime;
+
   DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
   DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
   DEBUG(6,("size: %.0f ", (double)size));
   DEBUG(6,("mode: %x\n"  , mode));
 
-  /* get some defaults (no modifications) if any info is zero. */
-  if (!tvs.actime) tvs.actime = st.st_atime;
-  if (!tvs.modtime) tvs.modtime = st.st_mtime;
-  if (!size) size = st.st_size;
+  if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
+     (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
+    /*
+     * Only do this test if we are not explicitly
+     * changing the size of a file.
+     */
+    if (!size)
+      size = st.st_size;
+  }
 
   /* Try and set the times, size and mode of this file -
      if they are different from the current values
    */
-  if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
-  {
-    if(fsp != NULL)
-    {
+  if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
+    if(fsp != NULL) {
       /*
        * This was a setfileinfo on an open file.
        * NT does this a lot. It's actually pointless
@@ -1845,38 +1954,51 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
        * on the next write, so we save the request
        * away and will set it on file code. JRA.
        */
-      fsp->pending_modtime = tvs.modtime;
-    }
-    else if(file_utime(conn, fname, &tvs)!=0)
-    {
-      return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+       if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
+         DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
+            ctime(&tvs.modtime) ));
+         fsp->pending_modtime = tvs.modtime;
+       }
+
+    } else {
+
+      DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
+
+      if(file_utime(conn, fname, &tvs)!=0)
+        return(UNIXERROR(ERRDOS,ERRnoaccess));
     }
   }
 
   /* check the mode isn't different, before changing it */
-  if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
-  {
-    DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
-    return(UNIXERROR(ERRDOS,ERRnoaccess));
+  if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
+
+    DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
+          fname, mode ));
+
+    if(file_chmod(conn, fname, mode, NULL)) {
+      DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
   }
 
-  if(size != st.st_size)
-  {
-    if (fd == -1)
-    {
-DEBUG(0, ("@@@ 23 @@@\n"));
-      fd = dos_open(fname,O_RDWR,0);
+  if(size != st.st_size) {
+
+    DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
+          fname, (double)size ));
+
+    if (fd == -1) {
+      fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
       if (fd == -1)
-      {
         return(UNIXERROR(ERRDOS,ERRbadpath));
-      }
-      set_filelen(fd, size);
-      close(fd);
-    }
-    else
-    {
-      set_filelen(fd, size);
+      set_filelen(fd, size); /* tpot vfs */
+      conn->vfs_ops.close(fd);
+    } else {
+        set_filelen(fd, size); /* tpot vfs */
     }
+
+    if(fsp)
+      set_filelen_write_cache(fsp, size);
   }
 
   SSVAL(params,0,0);
@@ -1905,14 +2027,10 @@ static int call_trans2mkdir(connection_struct *conn,
 
   DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
 
-  if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
-       {
-               SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
-               return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
-       }
+  unix_convert(directory,conn,0,&bad_path,NULL);
   if (check_name(directory,conn))
     ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
-                             unix_mode(conn,aDIR));
+                             unix_mode(conn,aDIR,directory));
   
   if(ret < 0)
     {
@@ -2006,6 +2124,47 @@ static int call_trans2findnotifynext(connection_struct *conn,
   return(-1);
 }
 
+/****************************************************************************
+  reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
+****************************************************************************/
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
+                                    char* outbuf, int length, int bufsize,
+                                    char** pparams, char** ppdata)
+{
+  char *params = *pparams;
+  enum remote_arch_types ra_type = get_remote_arch();
+  BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
+  pstring pathname;
+  int reply_size = 0;
+  int max_referral_level = SVAL(params,0);
+
+
+  DEBUG(10,("call_trans2getdfsreferral\n"));
+
+  if(!lp_host_msdfs())
+    return(ERROR(ERRDOS,ERRbadfunc));
+
+  /* if pathname is in UNICODE, convert to DOS */
+  /* NT always sends in UNICODE, may not set UNICODE flag */
+  if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
+    {
+      unistr_to_dos(pathname, &params[2]);
+      DEBUG(10,("UNICODE referral for %s\n",pathname));
+    }
+  else
+    pstrcpy(pathname,&params[2]);
+
+  if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
+    return(ERROR(ERRDOS,ERRbadfile));
+    
+  SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS | 
+       FLAGS2_DFS_PATHNAMES);
+  send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+
+  return(-1);
+}
+
+
 /****************************************************************************
   reply to a SMBfindclose (stop trans2 directory search)
 ****************************************************************************/
@@ -2013,11 +2172,11 @@ int reply_findclose(connection_struct *conn,
                    char *inbuf,char *outbuf,int length,int bufsize)
 {
        int outsize = 0;
-       int16 dptr_num=SVALS(inbuf,smb_vwv0);
+       int dptr_num=SVALS(inbuf,smb_vwv0);
 
        DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
 
-       dptr_close(dptr_num);
+       dptr_close(&dptr_num);
 
        outsize = set_message(outbuf,0,0,True);
 
@@ -2050,237 +2209,6 @@ int reply_findnclose(connection_struct *conn,
        return(outsize);
 }
 
-#define UNICODE_DFS
-
-/****************************************************************************
- reply to a TRANS2_GET_DFS_REFERRAL
- ****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn,
-                                    char *inbuf, char *outbuf, int length, 
-                                    int bufsize, 
-                                    char **pparams, char **ppdata,
-                                    int total_data)
-{
-       char *params = *pparams;
-       char *pdata;
-       char *pheader;
-       char *localstring_offset;
-       char *mangledstring_offset;
-       char *sharename_offset;
-       char *referal_offset;
-       
-       int i;
-       int j;
-       unsigned int total_params = SVAL(inbuf, smb_tpscnt);
-       int query_file_len=0;
-       int bytesreq=0;
-       int filename_len;
-       
-       BOOL first_one=True;
-       
-       referal_trans_param rtp;
-       dfs_internal_table *list=dfs_struct.table;
-       dfs_response reply;
-
-       DEBUG(0,("call_trans2getdfsreferral:1\n"));
-
-       ZERO_STRUCT(rtp);
-       ZERO_STRUCT(reply);
-
-       /* decode the param member of query */
-       rtp.level=SVAL(params, 0);
-       DEBUGADD(0,("rtp.level:[%d]\n",rtp.level));
-       
-       DEBUGADD(0,("total_params:[%d]\n",total_params));
-       for (i=0; i<(total_params-2)/2; i++)
-       {
-               rtp.directory[i]=SVAL(params, 2+2*i);
-       }
-/*
-       strupper(rtp.directory);
-*/
-       query_file_len=strlen(rtp.directory);
-       DEBUGADD(0,("rtp.directory:[%s]\n",rtp.directory));
-       DEBUGADD(0,("query_file_len:[%d]\n",query_file_len));
-               
-       /*
-         lookup in the internal DFS table all the entries
-         and calculate the required data buffer size
-       */
-       bytesreq=8;     /* the header */
-       reply.number_of_referal=0;
-       DEBUGADD(0,("call_trans2getdfsreferral:2\n"));
-       
-       for(i=0; i<dfs_struct.size; i++)
-       {
-               filename_len=list[i].localpath_length;
-       DEBUGADD(0,("checking against [%s][%d]\n", list[i].localpath, filename_len));
-               if( (filename_len==query_file_len) && 
-                   (!StrnCaseCmp(rtp.directory, list[i].localpath, query_file_len)) )
-               {
-                       
-                       bytesreq+=22;                             /* the referal size */
-                       bytesreq+=2*(list[i].sharename_length+1); /* the string length */
-                       reply.number_of_referal++;
-       DEBUGADD(0,("found\n"));
-                       
-                       if (first_one) {
-       DEBUGADD(0,("first one\n"));
-                               bytesreq+=2*(list[i].localpath_length+1);
-                               bytesreq+=2*(list[i].mangledpath_length+1);
-                               
-                               reply.path_consumed=list[i].localpath_length;
-                               
-                               strncpy(reply.filename, list[i].localpath, list[i].localpath_length+1);
-                               strncpy(reply.mangledname, list[i].mangledpath, list[i].mangledpath_length+1);
-                               rtp.type=list[i].type;
-                               first_one=False;
-                       }
-               }
-       }
-       DEBUGADD(0,("call_trans2getdfsreferral:3\n"));
-
-       /* allocate memory for the reply data */        
-       pdata = *ppdata = Realloc(*ppdata, bytesreq + 1024); 
-       memset(*ppdata, 0,  bytesreq+22);
-
-       pdata = *ppdata;
-       pheader = pdata;
-
-       localstring_offset  = pdata + 8 + reply.number_of_referal*22;
-
-#ifdef UNICODE_DFS
-       mangledstring_offset = localstring_offset + 2*(1+strlen(reply.filename));
-       sharename_offset = mangledstring_offset + 2*(1+strlen(reply.mangledname));
-
-#else
-       mangledstring_offset = localstring_offset + (1+strlen(reply.filename));
-       sharename_offset = mangledstring_offset + (1+strlen(reply.mangledname));
-#endif
-       referal_offset = pdata + 8;
-
-       /* right now respond storage server */
-/*
-       reply.server_function=rtp.type;
-*/
-       reply.server_function=0x3;
-
-       /* write the header */
-#ifdef UNICODE_DFS
-       SSVAL(pheader, 0, reply.path_consumed*2);
-#else
-       SSVAL(pheader, 0, reply.path_consumed);
-#endif
-       SSVAL(pheader, 2, reply.number_of_referal);
-       SIVAL(pheader, 4, reply.server_function);
-
-       /* write the local path string */
-#ifdef UNICODE_DFS
-       for(i=0; i<strlen(reply.filename); i++)
-       {
-               SSVAL(localstring_offset, 2*i, (uint16) reply.filename[i]);
-       }
-       SSVAL(localstring_offset, 2*strlen(reply.filename), 0);
-#else
-
-       for(i=0; i<strlen(reply.filename); i++)
-       {
-               localstring_offset[i]=reply.filename[i];
-       }
-       localstring_offset[strlen(reply.filename)]=0;
-#endif
-       DEBUG(0,("reply.filename is [%s]:[%d], i is [%d]\n", reply.filename, strlen(reply.filename), i));
-
-       /* write the mangled local path string */ 
-#ifdef UNICODE_DFS
-       for(i=0; i<strlen(reply.mangledname); i++)
-       {
-               SSVAL(mangledstring_offset, 2*i, (uint16) reply.mangledname[i]);
-       }
-       SSVAL(mangledstring_offset, 2*i, 0);
-#else
-       for(i=0; i<strlen(reply.mangledname); i++)
-       {
-               mangledstring_offset[i]=reply.mangledname[i];
-       }
-       mangledstring_offset[i]=0;
-#endif
-       DEBUGADD(0,("call_trans2getdfsreferral:4\n"));
-
-       /* the order of the referals defines the load balancing */
-
-       /* write each referal */
-       for(i=0; i<dfs_struct.size; i++)
-       {
-               filename_len=list[i].localpath_length;
-  
-               if(filename_len==query_file_len && 
-                  !strncasecmp(rtp.directory, list[i].localpath, query_file_len))
-               {
-               
-                       SSVAL(referal_offset,  0, 2);                   /* version */
-                       SSVAL(referal_offset,  2, 22);                  /* size */
-                       
-                       if (rtp.type==3)
-                               SSVAL(referal_offset,  4, 1);           /* type SMB server*/
-                       else            
-                               SSVAL(referal_offset,  4, 0);           /* type unknown */
-                       SSVAL(referal_offset,  6, 1);                   /* flags */
-                       SIVAL(referal_offset,  8, list[i].proximity);   /* proximity */
-                       SIVAL(referal_offset, 12, 300);                 /* ttl */
-                       SSVAL(referal_offset, 16, localstring_offset-referal_offset);
-                       SSVAL(referal_offset, 18, mangledstring_offset-referal_offset);
-                       SSVAL(referal_offset, 20, sharename_offset-referal_offset); 
-
-#ifdef UNICODE_DFS
-                       for(j=0; j<list[i].sharename_length; j++)
-                       {
-                               SSVAL(sharename_offset, 2*j, (uint16) list[i].sharename[j]);
-                       }
-                       SSVAL(sharename_offset, 2*j, 0);
-               
-                       sharename_offset=sharename_offset + 2*(1+list[i].sharename_length);
-#else
-                       for(j=0; j<list[i].sharename_length; j++)
-                       {
-                               sharename_offset[j]=list[i].sharename[j];
-                       }
-                       sharename_offset[j]=0;
-               
-                       sharename_offset=sharename_offset + (1+list[i].sharename_length);
-#endif
-
-                       referal_offset=referal_offset+22;
-               }                                       
-       }
-       
-       DEBUGADD(0,("call_trans2getdfsreferral:5\n"));
-
-       send_trans2_replies(outbuf, bufsize, params, 0, *ppdata, bytesreq+22);
-
-/*     send_trans2_replies(outbuf, bufsize, *ppdata, bytesreq, params, 0);*/
-       DEBUGADD(0,("call_trans2getdfsreferral:6\n"));
-
-       return(-1);
-}
-               
-/****************************************************************************
-reply to a TRANS2_REPORT_DFS_INCONSISTANCY
-****************************************************************************/
-static int call_trans2reportdfsinconsistancy(connection_struct *conn,
-                                            char *inbuf, char *outbuf, int length, 
-                                            int bufsize, 
-                                            char **pparams, char **ppdata)
-{
-       char *params = *pparams;
-
-       DEBUG(4,("call_trans2reportdfsinconsistancy\n"));
-       send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
-       return(-1);
-}
-
 
 /****************************************************************************
   reply to a SMBtranss2 - just ignore it!
@@ -2411,104 +2339,78 @@ int reply_trans2(connection_struct *conn,
        }
 
        /* Now we must call the relevant TRANS2 function */
-       switch(tran_call)
-       {
-               case TRANSACT2_OPEN:
-               {
-                       outsize = call_trans2open(conn, 
+       switch(tran_call)  {
+       case TRANSACT2_OPEN:
+               outsize = call_trans2open(conn, 
                                          inbuf, outbuf, bufsize, 
                                          &params, &data);
-                       break;
-               }
-               case TRANSACT2_FINDFIRST:
-               {
-                       outsize = call_trans2findfirst(conn, inbuf, outbuf, 
-                                                      bufsize, &params, &data);
-                       break;
-               }
-               case TRANSACT2_FINDNEXT:
-               {
-                       outsize = call_trans2findnext(conn, inbuf, outbuf, 
-                                                     length, bufsize, 
-                                                     &params, &data);
-                       break;
-               }
-               case TRANSACT2_QFSINFO:
-               {
-                       outsize = call_trans2qfsinfo(conn, inbuf, outbuf, 
-                                                length, bufsize, &params, 
-                                                &data);
-                       break;
-               }
-               case TRANSACT2_SETFSINFO:
-               {
-                       outsize = call_trans2setfsinfo(conn, inbuf, outbuf, 
-                                                      length, bufsize, 
-                                                      &params, &data);
-                       break;
-               }
-               case TRANSACT2_QPATHINFO:
-               case TRANSACT2_QFILEINFO:
-               {
-                       outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, 
-                                                          length, bufsize, 
-                                                          &params, &data, total_data);
-                       break;
-               }
-               case TRANSACT2_SETPATHINFO:
-               case TRANSACT2_SETFILEINFO:
-               {
-                       outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, 
-                                                            length, bufsize, 
-                                                            &params, &data, 
-                                                            total_data);
-                       break;
-               }
-               case TRANSACT2_FINDNOTIFYFIRST:
-               {
-                       outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, 
-                                                            length, bufsize, 
-                                                            &params, &data);
-                       break;
-               }
-               case TRANSACT2_FINDNOTIFYNEXT:
-               {
-                       outsize = call_trans2findnotifynext(conn, inbuf, outbuf, 
-                                                           length, bufsize, 
-                                                           &params, &data);
-                       break;
-               }
-               case TRANSACT2_MKDIR:
-               {
-                       outsize = call_trans2mkdir(conn, inbuf, outbuf, length, 
-                                                  bufsize, &params, &data);
-                       break;
-               }
-               case TRANSACT2_GET_DFS_REFERRAL:
-               {
-                       outsize = call_trans2getdfsreferral(conn, inbuf, outbuf, 
-                                                           length, bufsize, &params, 
-                                                           &data, total_data);
-                       break;
-               }
-               case TRANSACT2_REPORT_DFS_INCONSISTANCY:
-               {
-                       outsize = call_trans2reportdfsinconsistancy(conn, inbuf, outbuf,
-                                                                   length, bufsize, 
-                                                                   &params, &data);
-                       break;
-               }
-               default:
-               {
-                       /* Error in request */
-                       DEBUG(2,("Unknown request %d in trans2 call\n",
-                                 tran_call));
-                       if(params)
-                               free(params);
-                       if(data)
-                               free(data);
-                       return (ERROR(ERRSRV,ERRerror));
-               }
+               break;
+
+       case TRANSACT2_FINDFIRST:
+               outsize = call_trans2findfirst(conn, inbuf, outbuf, 
+                                              bufsize, &params, &data);
+               break;
+
+       case TRANSACT2_FINDNEXT:
+               outsize = call_trans2findnext(conn, inbuf, outbuf, 
+                                             length, bufsize, 
+                                             &params, &data);
+               break;
+
+       case TRANSACT2_QFSINFO:
+           outsize = call_trans2qfsinfo(conn, inbuf, outbuf, 
+                                        length, bufsize, &params, 
+                                        &data);
+           break;
+
+       case TRANSACT2_SETFSINFO:
+               outsize = call_trans2setfsinfo(conn, inbuf, outbuf, 
+                                              length, bufsize, 
+                                              &params, &data);
+               break;
+
+       case TRANSACT2_QPATHINFO:
+       case TRANSACT2_QFILEINFO:
+               outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, 
+                                                  length, bufsize, 
+                                                  &params, &data, total_data);
+               break;
+       case TRANSACT2_SETPATHINFO:
+       case TRANSACT2_SETFILEINFO:
+               outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, 
+                                                    length, bufsize, 
+                                                    &params, &data, 
+                                                    total_data);
+               break;
+
+       case TRANSACT2_FINDNOTIFYFIRST:
+               outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, 
+                                                    length, bufsize, 
+                                                    &params, &data);
+               break;
+
+       case TRANSACT2_FINDNOTIFYNEXT:
+               outsize = call_trans2findnotifynext(conn, inbuf, outbuf, 
+                                                   length, bufsize, 
+                                                   &params, &data);
+               break;
+       case TRANSACT2_MKDIR:
+               outsize = call_trans2mkdir(conn, inbuf, outbuf, length, 
+                                          bufsize, &params, &data);
+               break;
+
+       case TRANSACT2_GET_DFS_REFERRAL:
+               outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
+                                                   bufsize, &params, &data);
+               break;
+       default:
+               /* Error in request */
+               DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
+               if(params)
+                       free(params);
+               if(data)
+                       free(data);
+               return (ERROR(ERRSRV,ERRerror));
        }
        
        /* As we do not know how many data packets will need to be
@@ -2526,4 +2428,3 @@ int reply_trans2(connection_struct *conn,
                           call_trans2xxx calls have already sent
                           it. If outsize != -1 then it is returning */
 }
-
index 3493c2317890abe6c6dbe267995359af1b0aa90e..24e45a6d24a3f18f51a01473764cf3e4daf03d6d 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/Netbios implementation.
    Version 1.9.
-   Wrap disk only vfs functions to sidestep dodgy compilers.
+s   Wrap disk only vfs functions to sidestep dodgy compilers.
    Copyright (C) Tim Potter 1998
    
    This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@ void vfswrap_dummy_disconnect(void)
 
 /* Disk operations */
 
-SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize, 
+SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize, 
                               SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
     SMB_BIG_UINT result;
@@ -54,7 +54,7 @@ SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize,
     }
 #endif
 
-    result = sys_disk_free(path, bsize, dfree, dsize);
+    result = sys_disk_free(path, small_query, bsize, dfree, dsize);
     return result;
 }
     
@@ -204,9 +204,9 @@ int vfswrap_rename(char *old, char *new)
     return result;
 }
 
-void vfswrap_sync_file(int fd)
+void vfswrap_fsync(int fd)
 {
-    sys_sync_file(fd);
+    fsync(fd);
 }
 
 int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf)
@@ -252,15 +252,6 @@ int vfswrap_lstat(char *path,
     return result;
 }
 
-BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, 
-                       int type)
-{
-    BOOL result;
-
-    result = fcntl_lock(fd, op, offset, count, type);
-    return result;
-}
-
 int vfswrap_unlink(char *path)
 {
     int result;
index 18aaf0d3604c622fb26f56f7440ccad6f72f46ac..44f44bd169a437cc27fe01881484913b0aca5030 100644 (file)
@@ -20,9 +20,6 @@
 */
 
 #include "includes.h"
-#ifdef HAVE_LIBDL
-#include <dlfcn.h>
-#endif
 
 extern int DEBUGLEVEL;
 
@@ -61,11 +58,10 @@ struct vfs_ops default_vfs_ops = {
     vfswrap_write,
     vfswrap_lseek,
     vfswrap_rename,
-    vfswrap_sync_file,
+    vfswrap_fsync,
     vfswrap_stat,
     vfswrap_fstat,
     vfswrap_lstat,
-    vfswrap_fcntl_lock,
     vfswrap_unlink,
     vfswrap_chmod,
     vfswrap_utime
@@ -96,7 +92,9 @@ BOOL vfs_init_custom(connection_struct *conn)
 
     /* Open object file */
 
-    handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW);
+    handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL);
+    conn->vfs_conn->dl_handle = handle;
+
     if (!handle) {
        DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)),
                  dlerror()));
@@ -106,17 +104,17 @@ BOOL vfs_init_custom(connection_struct *conn)
     /* Get handle on vfs_init() symbol */
 
     fptr = dlsym(handle, "vfs_init");
+
     if (fptr == NULL) {
        DEBUG(0, ("No vfs_init() symbol found in %s\n", 
                  lp_vfsobj(SNUM(conn))));
        return False;
     }
 
-    dlclose(handle);
-
     /* Initialise vfs_ops structure */
 
-    if ((ops = fptr(lp_vfsoptions(SNUM(conn)))) == NULL) {
+    if ((ops = fptr(NULL)) == NULL) {
+        DEBUG(0, ("vfs_init function from %s failed\n", lp_vfsobj(SNUM(conn))));
        return False;
     }
 
@@ -182,8 +180,8 @@ BOOL vfs_init_custom(connection_struct *conn)
        conn->vfs_ops.rename = default_vfs_ops.rename;
     }
     
-    if (conn->vfs_ops.sync == NULL) {
-       conn->vfs_ops.sync = default_vfs_ops.sync;
+    if (conn->vfs_ops.fsync == NULL) {
+       conn->vfs_ops.fsync = default_vfs_ops.fsync;
     }
     
     if (conn->vfs_ops.stat == NULL) {
@@ -198,10 +196,6 @@ BOOL vfs_init_custom(connection_struct *conn)
        conn->vfs_ops.lstat = default_vfs_ops.lstat;
     }
     
-    if (conn->vfs_ops.lock == NULL) {
-       conn->vfs_ops.lock = default_vfs_ops.lock;
-    }
-    
     if (conn->vfs_ops.unlink == NULL) {
        conn->vfs_ops.unlink = default_vfs_ops.unlink;
     }
@@ -218,6 +212,24 @@ BOOL vfs_init_custom(connection_struct *conn)
 }
 #endif
 
+BOOL vfs_directory_exist(connection_struct *conn, char *dname,
+                         SMB_STRUCT_STAT *st)
+{
+  SMB_STRUCT_STAT st2;
+  BOOL ret;
+
+  if (!st) st = &st2;
+
+  if (conn->vfs_ops.stat(dos_to_unix(dname,False),st) != 0) 
+    return(False);
+
+  ret = S_ISDIR(st->st_mode);
+  if(!ret)
+    errno = ENOTDIR;
+
+  return ret;
+}
+
 /*******************************************************************
   check if a vfs file exists
 ********************************************************************/
@@ -377,3 +389,69 @@ char *vfs_readdirname(connection_struct *conn, void *p)
        unix_to_dos(dname, True);
        return(dname);
 }
+
+/* VFS options not quite working yet */
+
+#if 0
+
+/***************************************************************************
+  handle the interpretation of the vfs option parameter
+ *************************************************************************/
+static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
+{
+    struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
+    int i;
+    
+    /* Create new vfs option */
+
+    new_option = (struct vfs_options *)malloc(sizeof(*new_option));
+    if (new_option == NULL) {
+       return False;
+    }
+
+    ZERO_STRUCTP(new_option);
+
+    /* Get name and value */
+    
+    new_option->name = strtok(pszParmValue, "=");
+
+    if (new_option->name == NULL) {
+       return False;
+    }
+
+    while(isspace(*new_option->name)) {
+       new_option->name++;
+    }
+
+    for (i = strlen(new_option->name); i > 0; i--) {
+       if (!isspace(new_option->name[i - 1])) break;
+    }
+
+    new_option->name[i] = '\0';
+    new_option->name = strdup(new_option->name);
+
+    new_option->value = strtok(NULL, "=");
+
+    if (new_option->value != NULL) {
+
+       while(isspace(*new_option->value)) {
+           new_option->value++;
+       }
+       
+       for (i = strlen(new_option->value); i > 0; i--) {
+           if (!isspace(new_option->value[i - 1])) break;
+       }
+       
+       new_option->value[i] = '\0';
+       new_option->value = strdup(new_option->value);
+    }
+
+    /* Add to list */
+
+    DLIST_ADD(*options, new_option);
+
+    return True;
+}
+
+#endif
+
index 7835612d320f074815ddfcf99852a0fa3d7667af..cba78b78300ac2ac82cef0588fbc4d5860463339 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.po
 *.po32
 kernel_stat.h
index 65294c45ecf6c5d7ad4dfeaffd31e72f10f586de..4493ea716c9f31b721f172d2bf062bd66d9fc20a 100644 (file)
@@ -428,7 +428,7 @@ struct smbw_server *smbw_server(char *server, char *share)
                return NULL;
        }
 
-       make_nmb_name(&calling, global_myname, 0x0
+       make_nmb_name(&calling, global_myname, 0x0);
        make_nmb_name(&called , server, 0x20);
 
        DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server));
@@ -473,7 +473,7 @@ struct smbw_server *smbw_server(char *server, char *share)
        if (!cli_session_request(&c, &calling, &called)) {
                cli_shutdown(&c);
                if (strcmp(called.name, "*SMBSERVER")) {
-                       make_nmb_name(&called , "*SMBSERVER", 0x20, "");
+                       make_nmb_name(&called , "*SMBSERVER", 0x20);
                        goto again;
                }
                errno = ENOENT;
index faa930d63f9bf0d698d86dd5f5d5cf58594e2219..5d8c3be6b719bd121dd7f857806e29b50d2e67f8 100755 (executable)
@@ -2569,10 +2569,10 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
        if (strstr(syscmd,"%s"))
        {
                pstrcpy(filename,filename1);
-               string_sub(syscmd, "%s", filename);
+               pstring_sub(syscmd, "%s", filename);
        }
 
-       string_sub(syscmd, "%f", filename1);
+       pstring_sub(syscmd, "%f", filename1);
 
        /* Does the service have a printername? If not, make a fake and empty
         * printer name. That way a %p is treated sanely if no printer
@@ -2586,10 +2586,10 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
                tstr = SERVICE(snum);
        }
 
-       string_sub(syscmd, "%p", tstr);
+       pstring_sub(syscmd, "%p", tstr);
 
        /* If the lpr command support the 'Job' option replace here */
-       string_sub(syscmd, "%j", job_name);
+       pstring_sub(syscmd, "%j", job_name);
 
        if ( *syscmd != '\0')
        {
index d824c0add4522813f12aeb8f7c55faefe749283e..d52372461f9a7aae8aca9eeef178ca61e800187e 100644 (file)
@@ -515,6 +515,18 @@ uint32 _srv_net_share_get_info(const UNISTR2 *srv_name,
 
        switch (info_level)
        {
+               case 1:
+               {
+                       ctr->info.id1 = g_new(SHARE_INFO_1, 1);
+                       if (ctr->info.id1 == NULL)
+                       {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+                       make_srv_share_1_info(&ctr->info.id1->info1_hdr,
+                                             &ctr->info.id1->info1_str,
+                                             snum);
+                       return NT_STATUS_NOPROBLEMO;
+               }
                case 2:
                {
                        ctr->info.id2 = g_new(SHARE_INFO_2, 1);
index 0480bc977f9637f198ed482a173f2fd1150b9c1d..fd03b11ab31e18edde787b699cf50a0a1e264e92 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.lo
 tdbtool
 tdbtest
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 5bdd0d0bbe66abb1e1a48bdf0f75f12ecab42f42..e22e12beb40df75e0cb153ac4540f57ca77d46ab 100644 (file)
@@ -1,3 +1,4 @@
+.libs
 *.[lp]o
 *.po32
 
index 2ed30e0510b1231e8df9404c7e77c6824ddbe152..ec39b95bcf021a4326400e9908e494bf7339edee 100644 (file)
@@ -40,6 +40,8 @@
  */
 #define _PROTO_H_
 #define _NAMESERV_H_
+#define _DEBUG_H_
+#define _HASH_H_
 
 /* The main Samba system-adaptive header file.
  */
index b6ba43ea36810dccf7fca54173f4262427986105..e528a4f56ee96e8471f25963588b9a6b93946aa9 100644 (file)
@@ -1,4 +1,4 @@
-/* ************************************************************************** **
+/* ========================================================================== **
  *                                debug2html.c
  *
  * Copyright (C) 1998 by Christopher R. Hertel
  * does a decent job of converting Samba logs into HTML.
  * -------------------------------------------------------------------------- **
  *
- * $Revision: 1.9.2.1 $
+ * Revision 1.4  1998/11/13 03:37:01  tridge
+ * fixes for OSF1 compilation
  *
- * ************************************************************************** **
- */
-
-#include "includes.h"
-
-/* -------------------------------------------------------------------------- **
- * Global values.
+ * Revision 1.3  1998/10/28 20:33:35  crh
+ * I've moved the debugparse module files into the ubiqx directory because I
+ * know that 'make proto' will ignore them there.  The debugparse.h header
+ * file is included in includes.h, and includes.h is included in debugparse.c,
+ * so all of the pieces "see" each other.  I've compiled and tested this,
+ * and it does seem to work.  It's the same compromise model I used when
+ * adding the ubiqx modules into the system, which is why I put it all into
+ * the same directory.
+ *
+ * Chris -)-----
+ *
+ * Revision 1.1  1998/10/26 23:21:37  crh
+ * Here is the simple debug parser and the debug2html converter.  Still to do:
+ *
+ *   * Debug message filtering.
+ *   * I need to add all this to Makefile.in
+ *     (If it looks at all strange I'll ask for help.)
+ *
+ * If you want to compile debug2html, you'll need to do it by hand until I
+ * make the changes to Makefile.in.  Sorry.
+ *
+ * Chris -)-----
+ *
+ * ========================================================================== **
  */
 
-FILE *infile;
-FILE *outfile;
+#include "debugparse.h"
 
 /* -------------------------------------------------------------------------- **
  * The size of the read buffer.
@@ -81,7 +98,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode )
       if( dbg_message != mode )
         {
         /* Switching to message mode. */
-        (void)fprintf( outfile, "<PRE>\n" );
+        (void)printf( "<PRE>\n" );
         return( dbg_message );
         }
       break;
@@ -89,7 +106,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode )
       if( dbg_message == mode )
         {
         /* Switching out of message mode. */
-        (void)fprintf( outfile, "</PRE>\n\n" );
+        (void)printf( "</PRE>\n\n" );
         return( dbg_null );
         }
     }
@@ -117,16 +134,16 @@ static void newblock( dbg_Token old, dbg_Token new )
   switch( old )
     {
     case dbg_timestamp:
-      (void)fprintf( outfile, ",</B>" );
+      (void)printf( ",</B>" );
       break;
     case dbg_level:
-      (void)fprintf( outfile, "</FONT>]</B>\n   " );
+      (void)printf( "</FONT>]</B>\n   " );
       break;
     case dbg_sourcefile:
-      (void)fprintf( outfile, ":" );
+      (void)printf( ":" );
       break;
     case dbg_lineno:
-      (void)fprintf( outfile, ")" );
+      (void)printf( ")" );
       break;
     default:
       break;
@@ -135,13 +152,13 @@ static void newblock( dbg_Token old, dbg_Token new )
   switch( new )
     {
     case dbg_timestamp:
-      (void)fprintf( outfile, "<B>[" );
+      (void)printf( "<B>[" );
       break;
     case dbg_level:
-      (void)fprintf( outfile, " <B><FONT COLOR=MAROON>" );
+      (void)printf( " <B><FONT COLOR=MAROON>" );
       break;
     case dbg_lineno:
-      (void)fprintf( outfile, "(" );
+      (void)printf( "(" );
       break;
     default:
       break;
@@ -167,38 +184,41 @@ static void charprint( dbg_Token tok, int c )
       break;
     case dbg_null:
     case dbg_eof:
-      (void)putc( '\n', outfile );
+      (void)putchar( '\n' );
       break;
     default:
       switch( c )
         {
         case '<':
-          (void)fprintf( outfile, "&lt;" );
+          (void)printf( "&lt;" );
           break;
         case '>':
-          (void)fprintf( outfile, "&gt;" );
+          (void)printf( "&gt;" );
           break;
         case '&':
-          (void)fprintf( outfile, "&amp;" );
+          (void)printf( "&amp;" );
           break;
         case '\"':
-          (void)fprintf( outfile, "&#34;" );
+          (void)printf( "&#34;" );
           break;
         default:
-          (void)putc( c, outfile );
+          (void)putchar( c );
           break;
         }
     }
   } /* charprint */
 
-static void convert( void )
+int main( int argc, char *argv[] )
   /* ------------------------------------------------------------------------ **
-   * Read the input logfile, converting the entries to HTML.
+   * This simple program scans and parses Samba debug logs, and produces HTML
+   * output.
+   *
+   *  Input:  argc  - Currently ignored.
+   *          argv  - Currently ignored.
    *
-   *  Input:  none.
-   *  output: none.
-   *  Notes:  Reads from the global infile, writes to the global outfile.
-   *          These default to stdin and stdout, respectively.
+   *  Output: Always zero.
+   *
+   *  Notes:  The HTML output is sent to stdout.
    *
    * ------------------------------------------------------------------------ **
    */
@@ -211,8 +231,12 @@ static void convert( void )
             state = dbg_null,
             mode  = dbg_null;
 
-  while( (!feof( infile ))
-      && ((len = fread( bufr, 1, DBG_BSIZE, infile )) > 0) )
+  (void)printf( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
+  (void)printf( "<HTML>\n<HEAD>\n" );
+  (void)printf( "  <TITLE>Samba Debug Output</TITLE>\n</HEAD>\n\n<BODY>\n" );
+
+  while( (!feof( stdin ))
+      && ((len = fread( bufr, 1, DBG_BSIZE, stdin )) > 0) )
     {
     for( i = 0; i < len; i++ )
       {
@@ -228,94 +252,6 @@ static void convert( void )
     }
   (void)modechange( dbg_eof, mode );
 
-  } /* convert */
-
-static void usage( void )
-  /* ------------------------------------------------------------------------ **
-   * Prints a usage message on stderr, then gently exits.
-   *
-   *  Input:  none.
-   *  Output: none.  Exits with return code of 0.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  fprintf( stderr, "This utility converts Samba log files " );
-  fprintf( stderr, "into HTML documents.\n" );
-  fprintf( stderr, "Usage:\n" );
-  fprintf( stderr, "  debug2html <infile> <outfile>\n" );
-  exit( 0 );
-  } /* usage */
-
-static FILE *carefull_fopen( const char *path, const char *type )
-  /* ------------------------------------------------------------------------ **
-   * Checks for leading '-' characters, which are generically regarded as
-   * flags.  Also exits the program gracefully should the file fail to open.
-   *
-   *  Input:  path  - pathname of the file to open.
-   *          type  - open mode.  See fopen(3S).
-   *
-   *  Output: Pointer to open file.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  FILE *tmp;
-
-  if( '-' == path[0] || '\0' == path[0] )
-    usage();
-
-  tmp = sys_fopen( path, type );
-  if( NULL == tmp )
-    {
-    fprintf( stderr, "Error opening file %s: %s\n", path, strerror(errno) );
-    exit( 1 );
-    }
-  return( tmp );
-  } /* carefull_fopen */
-
-int main( int argc, char *argv[] )
-  /* ------------------------------------------------------------------------ **
-   * This simple program scans and parses Samba debug logs, and produces HTML
-   * output.
-   *
-   *  Input:  argc    - Argument count.
-   *          argv[1] - Input file name.
-   *          argv[2] - Output file name.
-   *                    A '-' character by itself means use defaults (i.e.,
-   *                    <stdin> or <stdout> depending upon the argument.
-   *                    A string beginning with '-' and containing more than
-   *                    that one character will generate a usage message.
-   *
-   *  Output: An exit value of 1 is returned if an error was encountered
-   *          while opening a file, else 0.
-   *
-   *  Notes:  The HTML output is sent to stdout.
-   *
-   * ------------------------------------------------------------------------ **
-   */
-  {
-  if( argc > 3 )
-    usage();
-
-  infile = stdin;
-  outfile = stdout;
-
-  if( argc > 1 && 0 != strcmp( argv[1], "-" ) )
-    infile = carefull_fopen( argv[1], "r" );
-
-  if( argc > 2 && 0 != strcmp( argv[2], "-" ) )
-    infile = carefull_fopen( argv[2], "w" );
-
-  (void)fprintf( outfile,
-                 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
-  (void)fprintf( outfile, "<HTML>\n<HEAD>\n" );
-  (void)fprintf( outfile,
-                 "  <TITLE>Samba Log</TITLE>\n</HEAD>\n\n<BODY>\n" );
-
-  convert();
-
-  (void)fprintf( outfile, "</BODY>\n</HTML>\n" );
-
+  (void)printf( "</BODY>\n</HTML>\n" );
   return( 0 );
   } /* main */
index 68b603bf1f6a2f66930ab20a1f693810277954f0..f403ee79bb615b0c0e943b0751b72ecf6c71a90c 100644 (file)
@@ -27,7 +27,7 @@
 */
 
 char *files_to_copy;
-char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype;
+char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup;
 char buffer[50][sizeof(pstring)];
 char sbuffer[50][sizeof(pstring)];
 char sub_dir[50][2][sizeof(pstring)];
@@ -96,13 +96,20 @@ static char *scan(char *chaine,char **entry)
        i++;
   }
   (*entry)[i]='\0'; 
-  pstrcpy(value,temp+i+1);      
+  if (temp[i]!='\0') {
+        i++;
+  }
+  while( temp[i]==' ' && temp[i]!='\0') {
+       i++;
+  }
+  pstrcpy(value,temp+i);      
   return (value);
 }
 
 static void build_subdir(void)
 {
   int i=0;
+  int j=0;
   char *entry;
   char *data;
  
@@ -111,12 +118,18 @@ static void build_subdir(void)
 #ifdef DEBUGIT
     fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
 #endif      
+    j = strlen(entry);
+    while (j) {
+      if (entry[j-1] != ' ') break;
+      j--;
+    }
+    entry[j] = '\0';
 
-    if (strcmp(data,"11")==0) {
+    if (strncmp(data,"11",2)==0) {
       pstrcpy(sub_dir[i][0],entry);
       pstrcpy(sub_dir[i][1],"");
     }
-    if (strcmp(data,"23")==0) {
+    if (strncmp(data,"23",2)==0) {
       pstrcpy(sub_dir[i][0],entry);
       pstrcpy(sub_dir[i][1],"color\\");
     }
@@ -176,6 +189,13 @@ static void lookup_strings(FILE *fichier)
                pointeur++;
        }  
   }
+
+  /* CCMRCF Mod, seg fault or worse if not found */
+  if (pointeur == 0) {
+     fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
+     exit(2);
+  }
+
 #ifdef DEBUGIT
   fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
 #endif
@@ -318,8 +338,8 @@ static void scan_copyfiles(FILE *fichier, char *chaine)
        fprintf(stderr,"\tsubdir %s:%s\n",sub_dir[i][0],sub_dir[i][1]);
 #endif      
        if (strcmp(sub_dir[i][0],part)==0)
-               pstrcpy(direc,sub_dir[i][1]);
-       i++;
+          pstrcpy(direc,sub_dir[i][1]);
+        i++;
       }        
       i=0;
       while (*buffer[i]!='\0') {
@@ -330,42 +350,84 @@ static void scan_copyfiles(FILE *fichier, char *chaine)
  * 
  * pscript.hlp =  pscript.hl_
  * hpdcmon.dll,hpdcmon.dl_
+ * MSVCRT.DLL,MSVCRT.DL_,,32
  * ctl3dv2.dll,ctl3dv2.dl_,ctl3dv2.tmp
  *
  * In the first 2 cases you want the first file name - in the last case
  * you only want the last file name (at least that is what a Win95
- * machine sent). This may still be wrong but at least I get the same list
+ * machine sent). In the third case you also want the first file name
+ * (detect by the last component being just a number ?).
+ * This may still be wrong but at least I get the same list
  * of files as seen on a printer test page.
  */
         part = strchr(buffer[i],'=');
         if (part) {
+          /*
+           * Case (1) eg. pscript.hlp =  pscript.hl_ - chop after the first name.
+           */
+
           *part = '\0';
-         while (--part > buffer[i])
-           if ((*part == ' ') || (*part =='\t')) *part = '\0';
-           else break;
-       } else {
-         part = strchr(buffer[i],',');
-         if (part) {
-           if ((mpart = strrchr(part+1,','))!=NULL) {
-               pstrcpy(buffer[i],mpart+1);
-           } else
-               *part = '\0';
+
+          /*
+           * Now move back to the start and print that.
+           */
+
+          while (--part > buffer[i]) {
+            if ((*part == ' ') || (*part =='\t'))
+              *part = '\0';
+            else
+              break;
+          }
+        } else {
+          part = strchr(buffer[i],',');
+          if (part) {
+            /*
+             * Cases (2-4)
+             */
+
+            if ((mpart = strrchr(part+1,','))!=NULL) {
+              /*
+               * Second ',' - case 3 or 4.
+               * Check if the last part is just a number,
+               * if so we need the first part.
+               */
+
+              char *endptr = NULL;
+              BOOL isnumber = False;
+
+              mpart++;
+              (void)strtol(mpart, &endptr, 10);
+
+              isnumber = ((endptr > mpart) && isdigit(*mpart));
+              if(!isnumber)
+                pstrcpy(buffer[i],mpart+1);
+              else
+                *part = '\0';
+            } else {
+              *part = '\0';
+            }
             while (--part > buffer[i])
               if ((*part == ' ') || (*part =='\t')) *part = '\0';
               else break;
-         }
-       }
-        if (strlen(files_to_copy) != 0)
-          pstrcat(files_to_copy,",");
-       pstrcat(files_to_copy,direc);
-       pstrcat(files_to_copy,buffer[i]);
-       fprintf(stderr,"%s%s\n",direc,buffer[i]);
-       i++;
-      } 
+          }
+           }
+        if (*buffer[i] != ';') {
+          if (strlen(files_to_copy) != 0)
+            pstrcat(files_to_copy,",");
+          pstrcat(files_to_copy,direc);
+          pstrcat(files_to_copy,buffer[i]);
+          fprintf(stderr,"%s%s\n",direc,buffer[i]);
+        }
+        i++;
+      } /* end while */ 
     }
     part=strtok(NULL,",");
-  }
-  while (part!=NULL);
+    if (part) {
+      while( *part ==' ' && *part != '\0') {
+        part++;
+      }
+    }
+  } while (part!=NULL);
   fprintf(stderr,"\n");
 }
 
@@ -378,6 +440,7 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
  
   helpfile=0;
   languagemonitor=0;
+  vendorsetup=0;
   datatype="RAW";
   if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
     fprintf(stderr, "scan_short_desc: malloc fail !\n");
@@ -407,6 +470,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
        languagemonitor=scan(buffer[i],&temp);
     else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) 
        datatype=scan(buffer[i],&temp);
+    else if (strncasecmp(buffer[i],"VendorSetup",11)==0) 
+       vendorsetup=scan(buffer[i],&temp);
     i++;       
   }
 
@@ -432,6 +497,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
          languagemonitor=scan(buffer[i],&temp);
       else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) 
          datatype=scan(buffer[i],&temp);
+      else if (strncasecmp(buffer[i],"VendorSetup",11)==0) 
+         vendorsetup=scan(buffer[i],&temp);
       i++;     
     }
   }
@@ -457,6 +524,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
        helpfile?helpfile:"(null)");
   fprintf(stderr,"LanguageMonitor: %s\n",
        languagemonitor?languagemonitor:"(null)");
+  fprintf(stderr,"VendorSetup: %s\n",
+       vendorsetup?vendorsetup:"(null)");
   if (copyfiles) scan_copyfiles(fichier,copyfiles);
 }
 
index a57af2fc4404faeb22691e0870dd7b21f8250f61..f0b68a7baea9b37f7c9c250c89f2339e0888a0fc 100644 (file)
@@ -3,7 +3,7 @@
    Version 1.9.
    Create codepage files from codepage_def.XXX files.
 
-   Copyright (C) Jeremy Allison 1997-1998.
+   Copyright (C) Jeremy Allison 1997-1999.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ static void read_line( char **buf, char *line_buf, int size)
  * Returns the number of lines copied.
  */
 
-static int clean_data( char **buf, uint32 *size)
+static int clean_data( char **buf, size_t *size)
 {
   pstring linebuf;
   char *p = *buf;
@@ -165,7 +165,7 @@ static void parse_error(char *buf, char *msg)
 static int do_compile(int codepage, char *input_file, char *output_file)
 {
   FILE *fp = NULL;
-  uint32 size = 0;
+  size_t size = 0;
   char *buf = NULL;
   char output_buf[CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES];
   int num_lines = 0;
@@ -309,7 +309,7 @@ definition file. File %s has %d.\n", prog_name, MAXCODEPAGELINES, input_file, nu
 
 static int do_decompile( int codepage, char *input_file, char *output_file)
 {
-  uint32 size = 0;
+  size_t size = 0;
   SMB_STRUCT_STAT st;
   char header_buf[CODEPAGE_HEADER_SIZE];
   char *buf = NULL;
@@ -325,7 +325,7 @@ static int do_decompile( int codepage, char *input_file, char *output_file)
     exit(1);
   }
 
-  size = (uint32)st.st_size;
+  size = (size_t)st.st_size;
 
   if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
   { 
index 27e1f9ef67d208abf82644ef9d632617adb34c33..81b10e4519a21ced5369f4163ee12d8f671f4b6a 100644 (file)
@@ -120,7 +120,7 @@ static void filter_child(int c, struct in_addr dest_ip)
                if (s != -1) FD_SET(s, &fds);
                if (c != -1) FD_SET(c, &fds);
 
-               num = sys_select(MAX(s+1, c+1),&fds,NULL, NULL);
+               num = sys_select(MAX(s+1, c+1),&fds,NULL);
                if (num <= 0) continue;
                
                if (c != -1 && FD_ISSET(c, &fds)) {
@@ -184,7 +184,7 @@ static void start_filter(char *desthost)
                FD_ZERO(&fds);
                FD_SET(s, &fds);
 
-               num = sys_select(s+1,&fds,NULL, NULL);
+               num = sys_select(s+1,&fds,NULL);
                if (num > 0) {
                        c = accept(s, &addr, &in_addrlen);
                        if (c != -1) {
index b7c678411c66a58209dab0cbcec780f390340c68..b6cc3f052439e8b270dfc1f456840beb426bcf84 100644 (file)
 
 #include "includes.h"
 
+/*
+ * stubs, to minimise linking, but unfortunately these are called
+ * in util_sec.c
+ */
+
+int DEBUGLEVEL;
+
+BOOL dbghdr( int level, char *file, char *func, int line )
+{
+  return( True );
+}
+
+#ifdef HAVE_STDARG_H
+ BOOL dbgtext( char *format_str, ... )
+  {
+  return( True );
+  } /* dbgtext */
+
+#else
+ BOOL dbgtext( va_alist )
+ va_dcl
+  {
+  return( True );
+  } /* dbgtext */
+
+#endif
+
+void smb_panic(char *reason)
+{
+       exit(1);
+}
 
 /*******************************************************************
 close the low 3 fd's and open dev/null in their place
index b5c3ab0d2c4b4ca6fb692af1a68b4528160a57c2..d1afdafe68e407ea1529bdff4e572e7e0009169b 100644 (file)
@@ -55,6 +55,7 @@ static int verbose, brief;
 static int            shares_only = 0;            /* Added by RJS */
 static int            locks_only  = 0;            /* Added by RJS */
 static BOOL processes_only=False;
+static int show_brl;
 
 
 /* added by OH */
@@ -103,12 +104,13 @@ static void print_share_mode(share_mode_entry *e, char *fname)
 
        if (Ucrit_checkPid(e->pid)) {
           printf("%-5d  ",(int)e->pid);
-         switch ((e->share_mode>>4)&0xF) {
+         switch (GET_DENY_MODE(e->share_mode)) {
          case DENY_NONE: printf("DENY_NONE  "); break;
          case DENY_ALL:  printf("DENY_ALL   "); break;
          case DENY_DOS:  printf("DENY_DOS   "); break;
          case DENY_READ: printf("DENY_READ  "); break;
          case DENY_WRITE:printf("DENY_WRITE "); break;
+         case DENY_FCB:  printf("DENY_FCB "); break;
          }
          switch (e->share_mode&0xF) {
          case 0: printf("RDONLY     "); break;
@@ -134,6 +136,24 @@ static void print_share_mode(share_mode_entry *e, char *fname)
        }
 }
 
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid, 
+                     enum brl_type lock_type,
+                     br_off start, br_off size)
+{
+       static int count;
+       if (count==0) {
+               printf("Byte range locks:\n");
+               printf("   Pid     dev:inode  R/W      start        size\n");
+               printf("------------------------------------------------\n");
+       }
+       count++;
+
+       printf("%6d   %05x:%05x    %s  %9.0f   %9.0f\n", 
+              (int)pid, (int)dev, (int)ino, 
+              lock_type==READ_LOCK?"R":"W",
+              (double)start, (double)size);
+}
+
 
 /*******************************************************************
  dump the elements of the profile structure
@@ -156,7 +176,7 @@ static int profile_dump(void)
 }
 
 
-static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, voidstate)
+static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
 {
        static pid_t last_pid;
        struct session_record *ptr;
@@ -234,11 +254,14 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
                return(1);
        }
        
-       while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
+       while ((c = getopt(argc, argv, "pdLSs:u:bPB")) != EOF) {
                switch (c) {
                case 'b':
                        brief = 1;
                        break;
+               case 'B':
+                       show_brl = 1;
+                       break;
                case 'd':
                        verbose = 1;
                        break;
@@ -336,6 +359,10 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
                }
                
                printf("\n");
+
+               if (show_brl) {
+                       brl_forall(print_brl);
+               }
                
                locking_end();
        }
index 865a23f7569e1db313650ff4c88368eeb01854b5..e4f603e0ce27f63f7a8d3fa23686a075f6c054c6 100644 (file)
@@ -43,40 +43,148 @@ extern int DEBUGLEVEL;
  Here we do a set of 'hard coded' checks for bad
  configuration settings.
 ************************************************/
-static void do_global_checks(void)
+
+static int do_global_checks(void)
 {
+       int ret = 0;
        SMB_STRUCT_STAT st;
+
        if (lp_security() > SEC_SHARE && lp_revalidate(-1)) {
                printf("WARNING: the 'revalidate' parameter is ignored in all but \
 'security=share' mode.\n");
        }
 
-    if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
+       if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
                printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
+               ret = 1;
        }
 
        if (lp_wins_support() && *lp_wins_server()) {
                printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
 cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
+               ret = 1;
        }
 
        if (!directory_exist(lp_lockdir(), &st)) {
                printf("ERROR: lock directory %s does not exist\n",
                       lp_lockdir());
+               ret = 1;
        } else if ((st.st_mode & 0777) != 0755) {
                printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
                       lp_lockdir());
+               ret = 1;
+       }
+
+       /*
+        * Password server sanity checks.
+        */
+
+       if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
+               pstring sec_setting;
+               if(lp_security() == SEC_SERVER)
+                       pstrcpy(sec_setting, "server");
+               else if(lp_security() == SEC_DOMAIN)
+                       pstrcpy(sec_setting, "domain");
+
+               printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
+to a valid password server.\n", sec_setting );
+               ret = 1;
        }
+
+       /*
+        * Password chat sanity checks.
+        */
+
+       if(lp_security() == SEC_USER && lp_unix_password_sync()) {
+
+               /*
+                * Check that we have a valid lp_passwd_program().
+                */
+
+               if(lp_passwd_program() == NULL) {
+                       printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
+parameter.\n" );
+                       ret = 1;
+               } else {
+                       pstring passwd_prog;
+                       pstring truncated_prog;
+                       char *p;
+
+                       pstrcpy( passwd_prog, lp_passwd_program());
+                       p = passwd_prog;
+                       *truncated_prog = '\0';
+                       next_token(&p, truncated_prog, NULL, sizeof(pstring));
+
+                       if(access(truncated_prog, F_OK) == -1) {
+                               printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
+cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
+                               ret = 1;
+                       }
+               }
+
+               if(lp_passwd_chat() == NULL) {
+                       printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
+parameter.\n");
+                       ret = 1;
+               }
+
+               /*
+                * Check that we have a valid script and that it hasn't
+                * been written to expect the old password.
+                */
+
+               if(lp_encrypted_passwords()) {
+                       if(strstr( lp_passwd_chat(), "%o")!=NULL) {
+                               printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
+via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
+                               ret = 1;
+                       }
+               }
+       }
+
+       /*
+        * WINS server line sanity checks.
+        */
+
+       if(*lp_wins_server()) {
+               fstring server;
+               int count = 0;
+               char *p = lp_wins_server();
+
+               while(next_token(&p,server,LIST_SEP,sizeof(server)))
+                       count++;
+               if(count > 1) {
+                       printf("ERROR: the 'wins server' parameter must only contain one WINS server.\n");
+                       ret = -1;
+               }
+       }
+
+       return ret;
 }   
 
- int main(int argc, char *argv[])
+static void usage(char *pname)
+{
+       printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
+       printf("\t-s                  Suppress prompt for enter\n");
+       printf("\t-h                  Print usage\n");
+       printf("\t-L servername       Set %%L macro to servername\n");
+       printf("\tconfigfilename      Configuration file to test\n");
+       printf("\thostname hostIP.    Hostname and Host IP address to test\n");
+       printf("\t                    against \"host allow\" and \"host deny\"\n");
+       printf("\n");
+}
+
+
+int main(int argc, char *argv[])
 {
   extern char *optarg;
   extern int optind;
+  extern fstring local_machine;
   pstring configfile;
   int opt;
   int s;
   BOOL silent_mode = False;
+  int ret = 0;
 
   TimeInit();
 
@@ -84,11 +192,23 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
   
   charset_initialise();
 
-  while ((opt = getopt(argc, argv,"s")) != EOF) {
+  while ((opt = getopt(argc, argv,"shL:")) != EOF) {
   switch (opt) {
     case 's':
       silent_mode = True;
       break;
+    case 'L':
+      fstrcpy(local_machine,optarg);
+      break;
+    case 'h':
+      usage(argv[0]);
+      exit(0);
+      break;
+    default:
+      printf("Incorrect program usage\n");
+      usage(argv[0]);
+      exit(1);
+      break;
     }
   }
 
@@ -104,65 +224,87 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
 
   printf("Load smb config files from %s\n",configfile);
 
-  if (!lp_load(configfile,False,True,False))
-    {
+  if (!lp_load(configfile,False,True,False)) {
       printf("Error loading services.\n");
       return(1);
-    }
-
+  }
 
   printf("Loaded services file OK.\n");
 
-  do_global_checks();
+  ret = do_global_checks();
 
-  for (s=0;s<1000;s++)
+  for (s=0;s<1000;s++) {
     if (VALID_SNUM(s))
       if (strlen(lp_servicename(s)) > 8) {
-       printf("WARNING: You have some share names that are longer than 8 chars\n");
-       printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
-       break;
+        printf("WARNING: You have some share names that are longer than 8 chars\n");
+        printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
+        break;
+      }
+  }
+
+  for (s=0;s<1000;s++) {
+    if (VALID_SNUM(s)) {
+      char *deny_list = lp_hostsdeny(s);
+      char *allow_list = lp_hostsallow(s);
+      if(deny_list) {
+        char *hasstar = strchr(deny_list, '*');
+        char *hasquery = strchr(deny_list, '?');
+        if(hasstar || hasquery) {
+          printf("Invalid character %c in hosts deny list %s for service %s.\n",
+                 hasstar ? *hasstar : *hasquery, deny_list, lp_servicename(s) );
+        }
       }
 
-  if (argc < 3)
-    {
-      if (!silent_mode) {
-       printf("Press enter to see a dump of your service definitions\n");
-       fflush(stdout);
-       getc(stdin);
+      if(allow_list) {
+        char *hasstar = strchr(allow_list, '*');
+        char *hasquery = strchr(allow_list, '?');
+        if(hasstar || hasquery) {
+          printf("Invalid character %c in hosts allow list %s for service %s.\n",
+                 hasstar ? *hasstar : *hasquery, allow_list, lp_servicename(s) );
+        }
       }
-      lp_dump(stdout,True);
+
+      if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
+        printf("Invalid combination of parameters for service %s. \
+Level II oplocks can only be set if oplocks are also set.\n",
+               lp_servicename(s) );
+      }
+    }
+  }
+
+  if (argc < 3) {
+    if (!silent_mode) {
+      printf("Press enter to see a dump of your service definitions\n");
+      fflush(stdout);
+      getc(stdin);
     }
+    lp_dump(stdout,True, lp_numservices());
+  }
   
-  if (argc >= 3)
-    {
-      char *cname;
-      char *caddr;
+  if (argc >= 3) {
+    char *cname;
+    char *caddr;
       
-      if (argc == 3) {
-       cname = argv[optind];
-       caddr = argv[optind+1];
-      } else {
-       cname = argv[optind+1];
-       caddr = argv[optind+2];
-      }
+    if (argc == 3) {
+      cname = argv[optind];
+      caddr = argv[optind+1];
+    } else {
+      cname = argv[optind+1];
+      caddr = argv[optind+2];
+    }
 
-      /* this is totally ugly, a real `quick' hack */
-      for (s=0;s<1000;s++)
-       if (VALID_SNUM(s))
-         {              
-           if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr))
-             {
-               printf("Allow connection from %s (%s) to %s\n",
-                      cname,caddr,lp_servicename(s));
-             }
-           else
-             {
-               printf("Deny connection from %s (%s) to %s\n",
-                      cname,caddr,lp_servicename(s));
-             }
-         }
+    /* this is totally ugly, a real `quick' hack */
+    for (s=0;s<1000;s++) {
+      if (VALID_SNUM(s)) {              
+        if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
+          printf("Allow connection from %s (%s) to %s\n",
+                 cname,caddr,lp_servicename(s));
+        } else {
+          printf("Deny connection from %s (%s) to %s\n",
+                 cname,caddr,lp_servicename(s));
+        }
+      }
     }
-  return(0);
+  }
+  return(ret);
 }
-
-
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32b746b8230688e70dc87afcaf5e3384f8eb4b52 100644 (file)
@@ -0,0 +1,2 @@
+.libs
+
index 48ffbfc62bc2e65e3e95313dabf1f24aa0312cc6..f253156b5be4a5e67c9c2d78663fc34ca1e57ace 100644 (file)
@@ -558,7 +558,7 @@ void cgi_setup(char *rootdir, int auth_required)
                *p = 0;
        }
 
-       string_sub(url, "/swat/", "");
+       string_sub(url, "/swat/", "", 0);
 
        if (url[0] != '/' && strstr(url,"..")==0 && file_exist(url, NULL)) {
                cgi_download(url);
index a59a5354f1189e5b1f76eabc4b47ac4801138435..5c800797c0413a8d7166d8d86f98d93570f7197c 100644 (file)
@@ -134,8 +134,7 @@ void status_page(void)
        TDB_CONTEXT *tdb;
 
        if (cgi_variable("smbd_restart")) {
-               if (smbd_running())
-                       stop_smbd();
+               stop_smbd();
                start_smbd();
        }
 
@@ -148,8 +147,7 @@ void status_page(void)
        }
 
        if (cgi_variable("nmbd_restart")) {
-               if (nmbd_running())
-                       stop_nmbd();
+               stop_nmbd();
                start_nmbd();
        }
        if (cgi_variable("nmbd_start")) {
index f9d5554488554e05d1d9306762ba195050308766..cf9c6935096305c543226e24718d0f9ce51a1dd5 100644 (file)
@@ -31,6 +31,8 @@
 static pstring servicesf = CONFIGFILE;
 static BOOL demo_mode = False;
 static BOOL have_write_access = False;
+static BOOL have_read_access = False;
+static int iNumNonAutoPrintServices = 0;
 
 /*
  * Password Management Globals
@@ -42,6 +44,7 @@ static BOOL have_write_access = False;
 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
 #define ADD_USER_FLAG "add_user_flag"
+#define DELETE_USER_FLAG "delete_user_flag"
 #define DISABLE_USER_FLAG "disable_user_flag"
 #define ENABLE_USER_FLAG "enable_user_flag"
 #define RHOST "remote_host"
@@ -212,9 +215,10 @@ static void show_parameter(int snum, struct parm_struct *parm)
                break;
 
        case P_OCTAL:
-               printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", make_parm_name(parm->label), *(int *)ptr);
-               printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'0%o\'\">",
-                       make_parm_name(parm->label),(int)(parm->def.ivalue));
+               printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
+               printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
+                      make_parm_name(parm->label),
+                      octal_string((int)(parm->def.ivalue)));
                break;
 
        case P_ENUM:
@@ -225,8 +229,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
                printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
                        make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
                break;
-
-       default:
+       case P_SEP:
                break;
        }
        printf("</td></tr>\n");
@@ -250,10 +253,18 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
                        continue;
                }
                if (parm->flags & FLAG_HIDE) continue;
+               if (snum >= 0) {
+                       if (printers & !(parm->flags & FLAG_PRINT)) continue;
+                       if (!printers & !(parm->flags & FLAG_SHARE)) continue;
+               }
                if (!advanced) {
-                       if (!printers && !(parm->flags & FLAG_BASIC)) {
+                       if (!(parm->flags & FLAG_BASIC)) {
                                void *ptr = parm->ptr;
 
+                               if (parm->class == P_LOCAL && snum >= 0) {
+                                       ptr = lp_local_ptr(snum, ptr);
+                               }
+
                                switch (parm->type) {
                                case P_CHAR:
                                        if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
@@ -283,8 +294,7 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
                                case P_ENUM:
                                        if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
                                        break;
-
-                               default:
+                               case P_SEP:
                                        continue;
                                }
                        }
@@ -298,6 +308,15 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
        }
 }
 
+/****************************************************************************
+  load the smb.conf file into loadparm.
+****************************************************************************/
+static BOOL load_config(BOOL save_def)
+{
+       lp_resetnumservices();
+       return lp_load(servicesf,False,save_def,False);
+}
+
 /****************************************************************************
   write a config file 
 ****************************************************************************/
@@ -307,13 +326,13 @@ static void write_config(FILE *f, BOOL show_defaults)
        fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
        fprintf(f, "# Date: %s\n\n", timestring(False));
        
-       lp_dump(f, show_defaults);      
+       lp_dump(f, show_defaults, iNumNonAutoPrintServices);    
 }
 
 /****************************************************************************
   save and reoad the smb.conf config file 
 ****************************************************************************/
-static int save_reload(void)
+static int save_reload(int snum)
 {
        FILE *f;
 
@@ -324,14 +343,18 @@ static int save_reload(void)
        }
 
        write_config(f, False);
+       if (snum)
+               lp_dump_one(f, False, snum);
        fclose(f);
 
        lp_killunused(NULL);
 
-       if (!lp_load(servicesf,False,False,False)) {
+       if (!load_config(False)) {
                 printf("Can't reload %s\n", servicesf);
                 return 0;
         }
+       iNumNonAutoPrintServices = lp_numservices();
+       load_printers();
 
        return 1;
 }
@@ -378,14 +401,6 @@ static void commit_parameters(int snum)
        }
 }
 
-/****************************************************************************
-  load the smb.conf file into loadparm.
-****************************************************************************/
-static BOOL load_config(void)
-{
-       return lp_load(servicesf,False,True,False);
-}
-
 /****************************************************************************
   spit out the html for a link with an image 
 ****************************************************************************/
@@ -401,13 +416,22 @@ static void image_link(char *name,char *hlink, char *src)
 ****************************************************************************/
 static void show_main_buttons(void)
 {
-       image_link("Home", "", "images/home.gif");
+       char *p;
 
+       if ((p = cgi_user_name()) && strcmp(p, "root")) {
+               printf("Logged in as <b>%s</b><p>\n", p);
+       }
+
+       image_link("Home", "", "images/home.gif");
+       if (have_write_access) {
        image_link("Globals", "globals", "images/globals.gif");
        image_link("Shares", "shares", "images/shares.gif");
        image_link("Printers", "printers", "images/printers.gif");
+       }
+       if (have_read_access) {
        image_link("Status", "status", "images/status.gif");
        image_link("View Config", "viewconfig","images/viewconfig.gif");
+       }
        image_link("Password Management", "passwd", "images/passwd.gif");
 
        printf("<HR>\n");
@@ -461,7 +485,7 @@ static void globals_page(void)
 
        if (cgi_variable("Commit")) {
                commit_parameters(GLOBALS_SNUM);
-               save_reload();
+               save_reload(0);
        }
 
        printf("<FORM name=\"swatform\" method=post>\n");
@@ -510,26 +534,29 @@ static void shares_page(void)
 
        if (cgi_variable("Commit") && snum >= 0) {
                commit_parameters(snum);
-               save_reload();
+               save_reload(0);
        }
 
        if (cgi_variable("Delete") && snum >= 0) {
                lp_remove_service(snum);
-               save_reload();
+               save_reload(0);
                share = NULL;
                snum = -1;
        }
 
        if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+               load_config(False);
                lp_copy_service(GLOBALS_SNUM, share);
-               save_reload();
+               iNumNonAutoPrintServices = lp_numservices();
+               save_reload(0);
                snum = lp_servicenumber(share);
        }
 
        printf("<FORM name=\"swatform\" method=post>\n");
 
        printf("<table>\n");
-       printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
+       printf("<tr>\n");
+       printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
        printf("<td><select name=share>\n");
        if (snum < 0)
                printf("<option value=\" \"> \n");
@@ -541,10 +568,18 @@ static void shares_page(void)
                               s, s);
                }
        }
-       printf("</select></td></tr><p>");
-
-       printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
+       printf("</select></td>\n");
+       if (have_write_access) {
+               printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
+       }
+       printf("</tr>\n");
+       printf("</table>");
+       printf("<table>");
+       if (have_write_access) {
+               printf("<tr>\n");
+               printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
        printf("<td><input type=text size=30 name=newshare></td></tr>\n");
+       }
        printf("</table>");
 
 
@@ -553,7 +588,7 @@ static void shares_page(void)
                        printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
                }
 
-               printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
+               printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
                if (advanced == 0) {
                        printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
                } else {
@@ -580,11 +615,9 @@ change a password either locally or remotely
 *************************************************************/
 static BOOL change_password(const char *remote_machine, char *user_name, 
                            char *old_passwd, char *new_passwd, 
-                           BOOL add_user, BOOL enable_user, BOOL disable_user)
+                               int local_flags)
 {
        BOOL ret = False;
-       uint16 acb_info = 0;
-       uint16 acb_mask = 0;
        pstring err_str;
        pstring msg_str;
 
@@ -607,23 +640,13 @@ static BOOL change_password(const char *remote_machine, char *user_name,
                return False;
        }
        
-       if (enable_user)
-       {
-               acb_mask |= ACB_DISABLED;
-               acb_info &= ~ACB_DISABLED;
-       }
-
-       if (disable_user)
-       {
-               acb_mask |= ACB_DISABLED;
-               acb_info |= ACB_DISABLED;
-       }
-
-       ret = local_password_change(user_name, add_user,
-                                   acb_info, acb_mask,
-                                   new_passwd, err_str, sizeof(err_str),
+#if 0
+       ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
                                    msg_str, sizeof(msg_str));
-
+#else
+       ret = False;
+       slprintf(err_str, sizeof(err_str)-1, "TODO: local_password_change disabled\n");
+#endif
        if(*msg_str)
                printf("%s\n<p>", msg_str);
        if(*err_str)
@@ -639,6 +662,7 @@ static void chg_passwd(void)
 {
        char *host;
        BOOL rslt;
+       int local_flags = 0;
 
        /* Make sure users name has been specified */
        if (strlen(cgi_variable(SWAT_USER)) == 0) {
@@ -647,10 +671,10 @@ static void chg_passwd(void)
        }
 
        /*
-        * smbpasswd doesn't require anything but the users name to disable or enable the user,
+        * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
         * so if that's what we're doing, skip the rest of the checks
         */
-       if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
+       if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
 
                /*
                 * If current user is not root, make sure old password has been specified 
@@ -689,19 +713,28 @@ static void chg_passwd(void)
        } else {
                host = "127.0.0.1";
        }
+
+       /*
+        * Set up the local flags.
+        */
+
+       local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
+       local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
+       local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
+       local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
+
        rslt = change_password(host,
                               cgi_variable(SWAT_USER),
                               cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
-                              cgi_variable(ADD_USER_FLAG)? True : False,
-                              cgi_variable(ENABLE_USER_FLAG)? True : False,
-                              cgi_variable(DISABLE_USER_FLAG)? True : False);
-
+                                  local_flags);
 
+       if(local_flags == 0) {
        if (rslt == True) {
                printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
        } else {
                printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
        }
+       }
        
        return;
 }
@@ -752,6 +785,8 @@ static void passwd_page(void)
        if (demo_mode || am_root()) {
                printf("<input type=submit name=%s value=\"Add New User\">\n",
                       ADD_USER_FLAG);
+               printf("<input type=submit name=%s value=\"Delete User\">\n",
+                      DELETE_USER_FLAG);
                printf("<input type=submit name=%s value=\"Disable User\">\n", 
                       DISABLE_USER_FLAG);
                printf("<input type=submit name=%s value=\"Enable User\">\n", 
@@ -763,7 +798,7 @@ static void passwd_page(void)
         * Do some work if change, add, disable or enable was
         * requested. It could be this is the first time through this
         * code, so there isn't anything to do.  */
-       if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
+       if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
            (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
                chg_passwd();           
        }
@@ -786,7 +821,7 @@ static void passwd_page(void)
        printf("<tr><td> Re-type New Password : </td>\n");
        printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
        printf("<tr><td> Remote Machine : </td>\n");
-       printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
+       printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
 
        printf("</table>");
 
@@ -825,26 +860,37 @@ static void printers_page(void)
 
        printf("<H2>Printer Parameters</H2>\n");
 
+       printf("<H3>Important Note:</H3>\n");
+       printf("Printer names marked with [*] in the Choose Printer drop-down box ");
+       printf("are autoloaded printers from ");
+       printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">Printcap Name</A>.\n");
+       printf("Attempting to delete these printers from SWAT will have no effect.\n");
+
        if (cgi_variable("Advanced") && !cgi_variable("Basic"))
                advanced = 1;
 
        if (cgi_variable("Commit") && snum >= 0) {
                commit_parameters(snum);
-               save_reload();
+               if (snum >= iNumNonAutoPrintServices)
+                   save_reload(snum);
+               else
+                   save_reload(0);
        }
 
        if (cgi_variable("Delete") && snum >= 0) {
                lp_remove_service(snum);
-               save_reload();
+               save_reload(0);
                share = NULL;
                snum = -1;
        }
 
        if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
+               load_config(False);
                lp_copy_service(GLOBALS_SNUM, share);
+               iNumNonAutoPrintServices = lp_numservices();
                snum = lp_servicenumber(share);
                lp_do_parameter(snum, "print ok", "Yes");
-               save_reload();
+               save_reload(0);
                snum = lp_servicenumber(share);
        }
 
@@ -858,23 +904,36 @@ static void printers_page(void)
        for (i=0;i<lp_numservices();i++) {
                s = lp_servicename(i);
                if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
+                    if (i >= iNumNonAutoPrintServices)
+                        printf("<option %s value=\"%s\">[*]%s\n",
+                               (share && strcmp(share,s)==0)?"SELECTED":"",
+                               s, s);
+                    else
                        printf("<option %s value=\"%s\">%s\n", 
                               (share && strcmp(share,s)==0)?"SELECTED":"",
                               s, s);
                }
        }
-       printf("</select></td></tr><p>");
+       printf("</select></td>");
+       if (have_write_access) {
+               printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
+       }
+       printf("</tr>");
+       printf("</table>\n");
 
+       if (have_write_access) {
+               printf("<table>\n");
        printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
        printf("<td><input type=text size=30 name=newshare></td></tr>\n");
        printf("</table>");
+       }
 
 
        if (snum >= 0) {
                if (have_write_access) {
                        printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
                }
-               printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
+               printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
                if (advanced == 0) {
                        printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
                } else {
@@ -907,6 +966,12 @@ static void printers_page(void)
        int opt;
        char *page;
 
+       fault_setup(NULL);
+
+#if defined(HAVE_SET_AUTH_PARAMETERS)
+       set_auth_parameters(argc, argv);
+#endif /* HAVE_SET_AUTH_PARAMETERS */
+
        /* just in case it goes wild ... */
        alarm(300);
 
@@ -914,6 +979,10 @@ static void printers_page(void)
 
        if (!dbf) dbf = stderr;
 
+       /* we don't want stderr screwing us up */
+       close(2);
+       open("/dev/null", O_WRONLY);
+
        while ((opt = getopt(argc, argv,"s:a")) != EOF) {
                switch (opt) {
                case 's':
@@ -926,7 +995,9 @@ static void printers_page(void)
        }
 
        charset_initialise();
-       load_config();
+       load_config(True);
+       iNumNonAutoPrintServices = lp_numservices();
+       load_printers();
 
        cgi_setup(SWATDIR, !demo_mode);
 
@@ -934,24 +1005,34 @@ static void printers_page(void)
        
        cgi_load_variables(NULL);
 
-       show_main_buttons();
-
-       page = cgi_pathinfo();
-
+       if (!file_exist(servicesf, NULL)) {
+               have_read_access = True;
+               have_write_access = True;
+       } else {
        /* check if the authenticated user has write access - if not then
           don't show write options */
        have_write_access = (access(servicesf,W_OK) == 0);
 
+               /* if the user doesn't have read access to smb.conf then
+                  don't let them view it */
+               have_read_access = (access(servicesf,R_OK) == 0);
+       }
+
+
+       show_main_buttons();
+
+       page = cgi_pathinfo();
+
        /* Root gets full functionality */
-       if (strcmp(page, "globals")==0) {
+       if (have_read_access && strcmp(page, "globals")==0) {
                globals_page();
-       } else if (strcmp(page,"shares")==0) {
+       } else if (have_read_access && strcmp(page,"shares")==0) {
                shares_page();
-       } else if (strcmp(page,"printers")==0) {
+       } else if (have_read_access && strcmp(page,"printers")==0) {
                printers_page();
-       } else if (strcmp(page,"status")==0) {
+       } else if (have_read_access && strcmp(page,"status")==0) {
                status_page();
-       } else if (strcmp(page,"viewconfig")==0) {
+       } else if (have_read_access && strcmp(page,"viewconfig")==0) {
                viewconfig_page();
        } else if (strcmp(page,"passwd")==0) {
                passwd_page();