first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
authorAndrew Tridgell <tridge@samba.org>
Mon, 13 Dec 1999 13:27:58 +0000 (13:27 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 13 Dec 1999 13:27:58 +0000 (13:27 +0000)
(This used to be commit 453a822a76780063dff23526c35408866d0c0154)

322 files changed:
README
Roadmap
WHATSNEW.txt
docs/announce
docs/faq/sambafaq-2.html
docs/htmldocs/DOMAIN_MEMBER.html
docs/htmldocs/nmbd.8.html
docs/htmldocs/nmblookup.1.html
docs/htmldocs/samba.7.html
docs/htmldocs/smb.conf.5.html
docs/htmldocs/smbclient.1.html
docs/htmldocs/smbd.8.html
docs/htmldocs/smbstatus.1.html
docs/htmldocs/swat.8.html
docs/htmldocs/testparm.1.html
docs/manpages/nmbd.8
docs/manpages/nmblookup.1
docs/manpages/samba.7
docs/manpages/smb.conf.5
docs/manpages/smbclient.1
docs/manpages/smbd.8
docs/manpages/smbmnt.8
docs/manpages/smbmount.8
docs/manpages/smbstatus.1
docs/manpages/smbumount.8
docs/manpages/swat.8
docs/manpages/testparm.1
docs/samba.lsm
docs/textdocs/Application_Serving.txt
docs/textdocs/BROWSING-Config.txt
docs/textdocs/BROWSING.txt
docs/textdocs/BUGS.txt
docs/textdocs/CVS_ACCESS.txt
docs/textdocs/DHCP-Server-Configuration.txt
docs/textdocs/DIAGNOSIS.txt
docs/textdocs/DNIX.txt
docs/textdocs/DOMAIN.txt
docs/textdocs/DOMAIN_CONTROL.txt
docs/textdocs/DOMAIN_MEMBER.txt
docs/textdocs/ENCRYPTION.txt
docs/textdocs/Faxing.txt
docs/textdocs/GOTCHAS.txt
docs/textdocs/HINTS.txt
docs/textdocs/MIRRORS.txt
docs/textdocs/Macintosh_Clients.txt
docs/textdocs/NTDOMAIN.txt
docs/textdocs/NetBIOS.txt
docs/textdocs/OS2-Client-HOWTO.txt
docs/textdocs/PRINTER_DRIVER.txt
docs/textdocs/PROFILES.txt
docs/textdocs/Passwords.txt
docs/textdocs/Printing.txt
docs/textdocs/Recent-FAQs.txt
docs/textdocs/RoutedNetworks.txt
docs/textdocs/SCO.txt
docs/textdocs/SSLeay.txt
docs/textdocs/Speed.txt
docs/textdocs/Speed2.txt
docs/textdocs/Support.txt
docs/textdocs/Tracing.txt
docs/textdocs/UNIX-SMB.txt
docs/textdocs/UNIX_INSTALL.txt
docs/textdocs/UNIX_SECURITY.txt
docs/textdocs/Win95.txt
docs/textdocs/WinNT.txt
docs/textdocs/cifsntdomain.txt
docs/textdocs/security_level.txt
docs/yodldocs/DOMAIN_MEMBER.yo
docs/yodldocs/nmbd.8.yo
docs/yodldocs/nmblookup.1.yo
docs/yodldocs/samba.7.yo
docs/yodldocs/smb.conf.5.yo
docs/yodldocs/smbclient.1.yo
docs/yodldocs/smbd.8.yo
docs/yodldocs/smbstatus.1.yo
docs/yodldocs/swat.8.yo
docs/yodldocs/testparm.1.yo
examples/autofs/auto.a
examples/printer-accounting/hp5-redir
examples/printer-accounting/lp-acct
examples/printing/smbprint
examples/validchars/validchr.com
packaging/Digital/package-prep
packaging/Digital/samba.init
packaging/Example/package-prep
packaging/PHT/TurboLinux/makefile-path.patch
packaging/PHT/TurboLinux/smb.conf
packaging/RedHat/makefile-path.patch
packaging/RedHat/makerpms.sh.tmpl
packaging/RedHat/samba.log
packaging/RedHat/samba2.spec.tmpl
packaging/RedHat/smb.conf
packaging/SGI/idb.pl
packaging/SGI/inst.msg
packaging/SGI/mkman
packaging/SGI/mkrelease.sh
packaging/SGI/sambalp
packaging/SGI/smb.conf
packaging/Solaris/pkg-specs/pkginfo
packaging/SuSE/5.2/samba.spec
source3/.cvsignore
source3/Makefile.in
source3/acconfig.h
source3/architecture.doc
source3/auth/pass_check.c
source3/client/client.c
source3/client/clitar.c
source3/client/smbmnt.c
source3/client/smbmount.c
source3/client/smbumount.c
source3/codepages/codepage_def.932
source3/config.guess
source3/configure
source3/configure.developer
source3/configure.in
source3/groupdb/aliasdb.c
source3/groupdb/aliasfile.c
source3/groupdb/groupdb.c
source3/groupdb/groupfile.c
source3/include/byteorder.h
source3/include/charset.h
source3/include/client.h
source3/include/config.h.in
source3/include/includes.h
source3/include/local.h
source3/include/nameserv.h
source3/include/ntdomain.h
source3/include/nterr.h
source3/include/profile.h
source3/include/proto.h
source3/include/rpc_dce.h
source3/include/rpc_lsa.h
source3/include/rpc_misc.h
source3/include/rpc_netlogon.h
source3/include/rpc_reg.h
source3/include/rpc_samr.h
source3/include/rpc_secdes.h
source3/include/rpc_srvsvc.h
source3/include/rpcclient.h
source3/include/smb.h
source3/include/trans2.h
source3/include/version.h
source3/lib/access.c
source3/lib/bitmap.c
source3/lib/charcnv.c
source3/lib/charset.c
source3/lib/crc32.c
source3/lib/debug.c
source3/lib/doscalls.c
source3/lib/genrand.c
source3/lib/interface.c
source3/lib/kanji.c
source3/lib/md4.c
source3/lib/pidfile.c
source3/lib/replace.c
source3/lib/signal.c
source3/lib/smbrun.c
source3/lib/snprintf.c
source3/lib/system.c
source3/lib/time.c
source3/lib/username.c
source3/lib/util.c
source3/lib/util_file.c
source3/lib/util_sid.c
source3/lib/util_sock.c
source3/lib/util_str.c
source3/lib/util_unistr.c
source3/libsmb/clientgen.c
source3/libsmb/namequery.c
source3/libsmb/nmblib.c
source3/libsmb/nterr.c
source3/libsmb/passchange.c
source3/libsmb/pwd_cache.c
source3/libsmb/smbdes.c
source3/libsmb/smbencrypt.c
source3/libsmb/smberr.c
source3/locking/locking.c
source3/locking/locking_shm.c
source3/locking/locking_slow.c
source3/locking/shmem.c
source3/locking/shmem_sysv.c
source3/lsarpcd/srv_lsa.c
source3/mem_man/mem_man.c
source3/mem_man/mem_man.h
source3/nmbd/asyncdns.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_become_dmb.c
source3/nmbd/nmbd_browserdb.c
source3/nmbd/nmbd_browsesync.c
source3/nmbd/nmbd_elections.c
source3/nmbd/nmbd_incomingdgrams.c
source3/nmbd/nmbd_incomingrequests.c
source3/nmbd/nmbd_mynames.c
source3/nmbd/nmbd_namelistdb.c
source3/nmbd/nmbd_namequery.c
source3/nmbd/nmbd_nameregister.c
source3/nmbd/nmbd_packets.c
source3/nmbd/nmbd_processlogon.c
source3/nmbd/nmbd_responserecordsdb.c
source3/nmbd/nmbd_sendannounce.c
source3/nmbd/nmbd_serverlistdb.c
source3/nmbd/nmbd_subnetdb.c
source3/nmbd/nmbd_synclists.c
source3/nmbd/nmbd_winsproxy.c
source3/nmbd/nmbd_winsserver.c
source3/nmbd/nmbd_workgroupdb.c
source3/param/loadparm.c
source3/passdb/ldap.c
source3/passdb/nispass.c
source3/passdb/pass_check.c
source3/passdb/passdb.c
source3/passdb/passgrp.c
source3/passdb/smbpass.c
source3/passdb/smbpasschange.c
source3/passdb/smbpassfile.c
source3/passdb/smbpassgroup.c
source3/printing/pcap.c
source3/printing/print_svid.c
source3/printing/printing.c
source3/profile/profile.c
source3/rpc_client/cli_login.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_client/cli_netlogon.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_reg.c
source3/rpc_client/cli_samr.c
source3/rpc_client/cli_srvsvc.c
source3/rpc_client/cli_wkssvc.c
source3/rpc_client/ntclienttrust.c
source3/rpc_parse/parse_lsa.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_net.c
source3/rpc_parse/parse_prs.c
source3/rpc_parse/parse_reg.c
source3/rpc_parse/parse_rpc.c
source3/rpc_parse/parse_samr.c
source3/rpc_parse/parse_sec.c
source3/rpc_parse/parse_srv.c
source3/rpc_parse/parse_wks.c
source3/rpc_server/srv_lookup.c
source3/rpc_server/srv_lsa.c
source3/rpc_server/srv_lsa_hnd.c
source3/rpc_server/srv_netlog.c
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_reg.c
source3/rpc_server/srv_samr.c
source3/rpc_server/srv_srvsvc.c
source3/rpc_server/srv_util.c
source3/rpc_server/srv_wkssvc.c
source3/rpcclient/cmd_lsarpc.c
source3/rpcclient/cmd_netlogon.c
source3/rpcclient/cmd_reg.c
source3/rpcclient/cmd_samr.c
source3/rpcclient/cmd_srvsvc.c
source3/rpcclient/cmd_wkssvc.c
source3/rpcclient/rpcclient.c
source3/script/installbin.sh
source3/script/installcp.sh
source3/script/installscripts.sh
source3/script/installswat.sh
source3/script/makeyodldocs.sh
source3/script/mkproto.awk
source3/script/smbtar
source3/smbd/blocking.c
source3/smbd/chgpasswd.c
source3/smbd/close.c
source3/smbd/connection.c
source3/smbd/dfree.c
source3/smbd/dir.c
source3/smbd/dosmode.c
source3/smbd/fileio.c
source3/smbd/filename.c
source3/smbd/files.c
source3/smbd/groupname.c
source3/smbd/ipc.c
source3/smbd/mangle.c
source3/smbd/message.c
source3/smbd/negprot.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/password.c
source3/smbd/pipes.c
source3/smbd/predict.c
source3/smbd/process.c
source3/smbd/quotas.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/service.c
source3/smbd/ssl.c
source3/smbd/trans2.c
source3/smbd/uid.c
source3/smbwrapper/realcalls.h
source3/smbwrapper/shared.c
source3/smbwrapper/smbsh.c
source3/smbwrapper/smbw.c
source3/smbwrapper/smbw_dir.c
source3/smbwrapper/wrapped.c
source3/tests/fcntl_lock.c
source3/tests/ftruncate.c
source3/tests/getgroups.c
source3/tests/shared_mmap.c
source3/tests/summary.c
source3/tests/sysv_ipc.c
source3/utils/debug2html.c
source3/utils/make_printerdef.c
source3/utils/make_smbcodepage.c
source3/utils/nmblookup.c
source3/utils/rpctorture.c
source3/utils/smbfilter.c
source3/utils/smbpasswd.c
source3/utils/smbrun.c
source3/utils/status.c
source3/utils/testparm.c
source3/utils/torture.c
source3/web/cgi.c
source3/web/diagnose.c
source3/web/startstop.c
source3/web/statuspage.c
source3/web/swat.c
swat/help/welcome.html

diff --git a/README b/README
index d1e50585c849ab0a7c721419acc7359aefc4537a..70b4b76ac3553c8e6a36bfdf6c4325217e75039f 100644 (file)
--- a/README
+++ b/README
@@ -1,10 +1,13 @@
-This is version 2.1.0alphaX of Samba, the free SMB and CIFS client and
+This is version 2.0.X of Samba, the free SMB and CIFS client and
 server for unix and other operating systems. Samba is maintained by
 the Samba Team, who support the original author, Andrew Tridgell.
 
 >>>> Please read THE WHOLE of this file as it gives important information
 >>>> about the configuration and use of Samba.
 
+NOTE: Installation instructions may be found in 
+      docs/textdocs/UNIX_INSTALL.txt
+
 This software is freely distributable under the GNU public license, a
 copy of which you should have received with this software (in a file
 called COPYING). 
@@ -136,14 +139,7 @@ available on the web page.
 
 If you would like to help with the documentation (and we _need_ help!)
 then have a look at the mailing list samba-docs, archived at
-http://samba.org/listproc/samba-docs.
-
-
-FTP SITE
---------
-
-Please use a mirror site! The list of mirrors is in docs/MIRRORS.txt.
-The master ftp site is samba.org in the directory pub/samba.
+http://lists.samba.org/
 
 
 MAILING LIST
@@ -161,7 +157,7 @@ body of "subscribe samba-announce Your Name". All announcements also
 go to the samba list.
 
 For details of other Samba mailing lists and for access to archives, see
-http://samba.org/listproc.
+http://lists.samba.org/
 
 
 NEWS GROUP
@@ -186,6 +182,3 @@ As well as general information and documentation, this also has searchable
 archives of the mailing list and a user survey that shows who else is using
 this package. Have you registered with the survey yet? :-)
 
-It is maintained by Paul Blackman (thanks Paul!). You can contact him
-as ictinus@samba.org.
-
diff --git a/Roadmap b/Roadmap
index 2af17985d1b3330b26c22529ce2d24b08d6bd5f8..83b0bcc0e6beeba6b950e33fe8ea116ca14d19e4 100644 (file)
--- a/Roadmap
+++ b/Roadmap
@@ -1,9 +1,9 @@
-Copyright (C) 1997-1998 - Samba-Team
+Copyright (C) 1997-1999 - Samba-Team
 
 The Samba-Team are committed to an aggressive program to deliver quality
 controlled software to a well defined roadmap.
 
-The current Samba release 2.0.0 is called the "Domain Client Release"
+The current Samba release 2.0.4 is called the "NT Security update".
 
 It correctly implements the Windows NT specific SMB calls,
 and will operate correctly as a client in a Windows NT
@@ -24,6 +24,9 @@ are in place:
 2.0.x       -   "NT Security update" - Allowing Windows NT Clients to
                 manipulate file security and ownership using native tools.
 
+Note that the "NT Security update" part of the Roadmap has been
+achieved with the Samba 2.0.4 release.
+
 2.0.xx      -   "Thin Server" mode, allowing a Samba server to be
                 inserted into a network with no UNIX setup required.
                 Some management capabilities for Samba using native NT tools.
index bff189c2dbafa21065e8edd80f8bbc4c98dd131a..ab78957cca00b60ba59081340616424035eefec2 100644 (file)
@@ -1,5 +1,263 @@
-          WHATS NEW IN Samba 2.0.0 beta1
-          ==============================
+              WHATS NEW IN Samba 2.0.4b
+              =========================
+
+This is the latest stable release of Samba. This is the
+version that all production Samba servers should be running
+for all current bug-fixes.
+
+New/Changed parameters in 2.0.4
+-------------------------------
+
+There are 5 new parameters and one modified parameter in
+the smb.conf file.
+
+allow trusted domains
+restrict anonymous
+mangle locks
+oplock break wait time
+oplock contention limit
+
+The new parameters are :
+
+allow trusted domains
+---------------------
+
+This option is used in "security=domain" settings and allows
+the Samba admin to restrict access to users within the domain
+the the Samba server is in.
+
+restrict anonymous
+------------------
+
+This parameter allows the Samba admin to cause Samba to
+refuse access to anonymous users. Use of this parameter
+is only recommened for homogenous NT client environments.
+
+mangle locks
+------------
+
+This parameter was added to get around a bug in Windows NT
+when dealing with Samba running on 32-bit systems (such
+as Linux x86). This bug causes NT to send 64 bit locking
+requests to 32-bit systems even though Samba correctly 
+tells the NT client not to do so. This option causes Samba
+to map the lock requests from 64 bits to 32 bits on these
+systems.
+
+oplock break wait time
+----------------------
+
+This tuning parameter, added to help with clients that don't
+respond to oplock break requests, causes Samba to deley for
+this number of milliseconds before sending an oplock break
+request to a client that caused the break to be sent. The
+default is 10ms. This is an advanced tuning parameter and
+should not be changed lightly.
+
+oplock contention limit
+-----------------------
+
+This tuning parameter causes Samba not to grant oplocks
+when an smbd daemon notices that there have been this 
+many concurrent requests for an oplock on a file. This
+prevents the "baton passing" oplock problem where many
+clients accessing one file pass the oplock between themselves
+like a baton. The default is 2. This is an advanced tuning
+parameter and should not be changed lightly.
+
+The modified parameter is :
+
+nt acl support
+--------------
+
+This is a global parameter that defaulted to False in
+the previous release (2.0.3) and now defaults to True
+as the RPC code has been added to Samba to allow it to
+map UNIX permissions to NT ACLs.
+
+All of these new parameters and changes are documented in the
+smb.conf man pages and html pages.
+
+Updated and New documentation
+-----------------------------
+
+A new document describing the manipulation of UNIX permissions
+via the Windows NT security dialogs and their interaction with
+Samba 2.0.4 is provided as :
+
+docs/textdocs/NT_Security.txt
+docs/htmldocs/NT_Security.html
+
+Changes in 2.0.4b
+-----------------
+
+A bug with MS-Word 97 saving files with zero UNIX permissions
+was fixed. Even though a workaround is available (set force
+create mode = 644 on the share) Word is such an important
+application that a point fix was neccessary.
+
+Changes in 2.0.4a
+-----------------
+
+The text and html versions of NT_Security were missing from
+the shipping tarball. Also a compile bug for platforms that
+don't have usleep was fixed.
+
+Bugfixes added since 2.0.3
+--------------------------
+
+1). Fix for 8 character password problem when using HPUX and
+plaintext passwords.
+2). --with-pam option added to ./configure.
+3). Client fixes for memory leak and display of 64 bit values.
+4). Fixes for -E and -s option with smbclient.
+5). smbclient now allows -L //server or -L \\server
+6). smbtar fix for display of 64 bit values.
+7). Endian independence added to DCE/RPC code.
+8). DCE/RPC marshalling/unmarshalling code re-written to provide
+overflow reporting and sign and seal support.
+9). Bind NAK reply packet added to DCE/RPC code, used to correctly
+refuse bind requests (prevents NT system event log messages).
+10). Mapping of UNIX permissions into NT ACL's for get and set
+added.
+11). DCE/RPC enumeration of numbers of shares made dynamic. 
+Samba now has no limit on the number of exported shares seen.
+12). Fix to speed up random number seed generation on /dev/urandom
+being unavailable.
+13). Several memory fixes added by running Purify on the code.
+14). Read from client error messages improved.
+15). Fixed endianness used in UNICODE strings.
+16). Cope with ERRORmoredata in an RPC pipe client call.
+17). Check for malformed responses in nmbd register name.
+18). NT Encrypted password changing from the NT password dialog box
+now fully implmented.
+19). Mangle 64-bit lock ranges into 32-bits (NT bug!) on a 32-bit
+Samba platform.
+20). Allow file to be pseudo-openend in order to read security only.
+21). Improve filename mangling to reduce chance of collisions.
+22). Added code to prevent granting of oplocks when a file is under
+contention.
+23). Added tunable wait time before sending an oplock break request
+to a client if the client caused the break request. Helps with clients
+not responding to oplock breaks.
+24). Always respond negatively to queued local oplock break messages
+before shutdown. This can prevent "freezes" on an oplock error.
+25). Allow admin to restrict logons to correct domain when in domain
+level security.
+26). Added "restrict anonymous" patch from Andy (thwartedefforts@wonky.org)
+to prevent parameter substitution problems with anonymous connections.
+27). Fix SMBseek where seeking to a negative number sets the offset
+to zero.
+28). Fixed problem with mode getting corrupted in trans2 request
+(setting to zero means please ignore it).
+29). Correctly become the authenticated user on an authenticated
+DCE/RPC pipe request.
+30). Correctly reset debug level in nmbd if someone set it on the
+command line.
+31). Added more checking into testparm
+32). NetBench simulator added to smbtorture by Andrew.
+33). Fixed NIS+ option compile (was broken in 2.0.3).
+34). Recursive smbclient directory listing fix. Patch from E. Jay Berkenbilt
+(ejb@ql.org)
+
+Bugfixes added since 2.0.2
+--------------------------
+
+1). --with-ssl configure now include ssl include directory. Fix
+from Richard Sharpe.
+2). Patch for configure for glibc2.1 support (large files etc.).
+3). Several bugfixes for smbclient tar mode from Bob Boehmer
+(boehmer@worldnet.att.net) to fix smbclient aborting problems
+when restoring tar files.
+4). Some automount fixes for smbmount.
+5). Attempt to fix the AIX 4.1.x/3.x problems where smbd runs as
+root. As no-one has given us root access to such a server this
+cannot be tested fully, but should work.
+6). Crash bug fix in debug code where *real* uid rather than 
+*effective* uid was being checked before attempting to rotate
+log files. This fix should help a *lot* of people who were
+reporting smbd aborting in the middle of a copy operation.
+7). SIGALRM bugfix to ensure infinate file locks time out.
+8). New code to implement NT ACL reporting for cacls.exe program.
+9). UDP loopback socket rebind fix for Solaris.
+10). Ensure all UNICODE strings are correctly in little-endian
+format.
+11). smbpasswd file locking fix.
+12). Fixes for strncpy problems with glibc2.1.
+13). Ensure smbd correctly reports major and minor version number
+and server type when queried via NT rpc calls.
+14). Bugfix for short mangled names not being pulled off the
+mangled stack correctly.
+15). Fix for mapping of rwx bits being incorrectly overwritten
+when doing ATTRIB.EXE
+16). Fix for returning multiple PDU packets in NT rpc code. Should
+allow multiple shares to be returned correctly).
+17). Improved mapping of NT open access requests into UNIX open
+modes.
+18). Fix for copying files from an NTFS volume that contain
+multiple data forks. Added 'magic' error code NT needs.
+19). Fixed crash bug when primary NT authentication server
+is down, rolls over to secondaries correctly now.
+20). Fixed timeout processing to be timer based. Now will
+always occur even if smbd is under load.
+21). Fixed signed/unsigned problem in quotas code.
+22). Fixed bug where setting the password of a completely fresh
+user would end up setting the account disabled flag.
+23). Improved user logon messages to help admins having
+trouble with user authentication.
+
+Bugfixes added since 2.0.1
+--------------------------
+
+Note that due to a critical signal handling bug in 2.0.1,
+this release has been removed and replaced immediately with 
+2.0.2. The Samba Team would like to apologise for any problem
+this may have caused.
+
+1). Fixed smbd looping on SIGCLD problem. This was
+    caused by a missing break statement in a critical
+    piece of code.
+
+Bugfixes added since 2.0.0
+--------------------------
+
+1). Autoconf changes for gcc2.7.x and Solaris 2.5/2.6
+2). Autoconf changes to help HPUX configure correctly.
+3). Autoconf changes to allow lock directory to be set.
+4). Client fix to allow port to be set.
+5). clitar fix to send debug messages to stderr.
+6). smbmount race condition fix.
+7). Fix for bug where trying to browse large numbers of shares
+    generated an error from an NT client.
+8). Wrapper for setgroups for SunOS 4.x
+9). Fix for directory deleting failing from multiuser NT.
+10). Fix for crash bug if bitmap was full.
+11). Fix for Linux genrand where /dev/random could cause 
+     clients to timeout on connect if the entropy pool was
+     empty.
+12). The default PASSWD_CHAT may now be overridden in local.h
+13). HPUX printing fixes for default programs.
+14). Reverted (erroneous) code in MACHINE.SID generation that
+     was setting the sid to 0x21 - should be *decimal* 21.
+15). Fix for printing to remote machine under SVR4.
+16). Fix for chgpasswd wait being interrupted with EINTR.
+17). Fix for disk free routine. NT and Win98 now correctly
+     show greater than 2GB disks.
+18). Fix for crash bug in stat cache statistics printing.
+19). Fix for filenames ending in .~xx.
+20). Fix for access check code wait being interrupted with EINTR.
+21). Fix for password changes from "invalid password" to a valid
+     one setting the account disabled bit.
+22). Fix for smbd crash bug in SMBreadraw cache prime code.
+23). Fix for overly zealous lock range overflow reporting.
+24). Fix for large disk disk free reporting (NT SMB code).
+25). Fix for NT failing to truncate files correctly.
+26). Fix for smbd crash bug with SMBcancel calls.
+27). Additional -T flag to nmblookup to do reverse DNS on addresses.
+28). SWAT fix to start/stop smbd/nmbd correctly.
+
+Major changes in Samba 2.0
+--------------------------
 
 This is a MAJOR new release of Samba, the UNIX based SMB/CIFS file 
 and print server for Windows systems.
@@ -12,9 +270,6 @@ for configuring Samba has been added.
 In addition, Samba has been re-written to help portability to
 other POSIX-based systems, based on the GNU autoconf tool.
 
-Major changes in Samba 2.0
---------------------------
-
 There are many major changes in Samba for version 2.0.  Here are 
 some of them:
 
@@ -107,6 +362,10 @@ In addition, Samba now defaults to case sensitivity options that
 match a Windows NT server precisely, that is, case insensitive 
 but case preserving.
 
+The default format of the smbpasswd file has also been
+changed for this release, although the new tools will read
+and write the old format, for backwards compatibility.
+
 =====================================================================
 
 NOTE - Primary Domain Controller Functionality
@@ -120,9 +379,11 @@ Domain Controller than serving Windows NT logon requests.
 A useful version of a Primary Domain Controller contains
 many remote procedure calls to do things like enumerate users, 
 groups, and security information, only some of which Samba currently
-implements.  For this reason we have chosen not to advertise
-and actively support Primary Domain Controller functionality
-with this release.
+implements. In addition, there are outstanding (known) bugs with
+using Samba as a PDC in this release that the Samba Team are actively
+working on. For this reason we have chosen not to advertise and 
+actively support Primary Domain Controller functionality with this
+release.
 
 This work is being done in the CVS (developer) versions of Samba,
 development of which continues at a fast pace.  If you are
index 6548a515548794422fa32c562b3d7cc2124948db..856fd000364ab2c0f4445c9f5408bd09052c852e 100644 (file)
@@ -1,4 +1,4 @@
-               Announcing Samba version 1.9
+               Announcing Samba version 2.0
                ============================
 
 What is Samba?
@@ -47,10 +47,12 @@ umask support, guest connections, name mangling and hidden and system
 attribute mapping. Look at the FAQs included with the package for
 a full list of features.
 
-What's new since 1.8?
+What's new since 1.9?
 ---------------------
 
 Lots of stuff. See the change log and man pages for details.
+In particular, please check the WHATSNEW.txt file in the root directory
+of each release. This file has current change/update information.
 
 Where can I get a client for my PC?
 -----------------------------------
@@ -136,7 +138,7 @@ There is also often quite a bit of discussion about Samba on the
 newsgroup comp.protocols.smb.
 
 A WWW site with lots of Samba info can be found at 
-http://samba.org/
+http://samba.org/samba/
 
 The Samba Team (Contact: samba-bugs@samba.org)
 June 1996
index dfababb66a4ed1bc23d2d9afffdaec7d17e5fb46..d78f5d627c71635cbd8d72685b089e2bb68565d7 100644 (file)
 <P>
 <A NAME="no_browse"></A> 
 
-See 
-<A HREF="ftp://samba.org/pub/samba/BROWSING.txt">BROWSING.txt</A>
-for more information on browsing.  Browsing.txt can also be found
-in the docs directory of the Samba source.</P>
-<P>If your GUI client does not permit you to select non-browsable
-servers, you may need to do so on the command line. For example, under
-Lan Manager you might connect to the above service as disk drive M:
-thusly:
+See BROWSING.txt for more information on browsing.  BROWSING.txt can
+be found in the docs directory of the Samba source.</P> <P>If your GUI
+client does not permit you to select non-browsable servers, you may
+need to do so on the command line. For example, under Lan Manager you
+might connect to the above service as disk drive M: thusly:
 <BLOCKQUOTE><CODE>
 <PRE>
    net use M: \\mary\fred
index 6d9741f2f275529ee2a937c72d1df902ca1524ef..409534c99ef8a16d824f28b63e0fbe5ce29cd20f 100644 (file)
@@ -13,7 +13,7 @@
 
 <h1>Joining an NT Domain with Samba 2.0</h1>
 <h2>Jeremy Allison, Samba Team</h2>
-<h2>11th November 1998</h2>
+<h2>7th October 1999</h2>
 
     
  
@@ -23,7 +23,8 @@
 <p><br>In order for a Samba-2 server to join an NT domain, you must first add
 the NetBIOS name of the Samba server to the NT domain on the PDC using
 Server Manager for Domains.  This creates the machine account in the
-domain (PDC) SAM.
+domain (PDC) SAM. Note that you should add the Samba server as a "Windows
+NT Workstation or Server", <em>NOT</em> as a Primary or backup domain controller.
 <p><br>Assume you have a Samba-2 server with a NetBIOS name of <code>SERV1</code> and are
 joining an NT domain called <code>DOM</code>, which has a PDC with a NetBIOS name
 of <code>DOMPDC</code> and two backup domain controllers with NetBIOS names <code>DOMBDC1</code>
@@ -63,6 +64,9 @@ use domain security.
 <p><br>line in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section to read: 
 <p><br><code>workgroup = DOM</code>
 <p><br>as this is the name of the domain we are joining. 
+<p><br>You must also have the parameter <a href="smb.conf.5.html#encryptpasswords"><strong>"encrypt passwords"</strong></a>
+set to <code>"yes"</code> in order for your users to authenticate to the
+NT PDC.
 <p><br>Finally, add (or modify) a:
 <p><br><a href="smb.conf.5.html#passwordserver"><strong>"password server ="</strong></a>
 <p><br>line in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section to read: 
@@ -72,18 +76,13 @@ to contact in order to authenticate users. Samba will try to contact
 each of these servers in order, so you may want to rearrange this list
 in order to spread out the authentication load among domain
 controllers.
-<p><br>Currently, Samba requires that a defined list of domain controllers be
-listed in this parameter in order to authenticate with domain-level
-security. NT does not use this method, and will either broadcast or
-use a WINS database in order to find domain controllers to
+<p><br>Alternatively, if you want smbd to automatically determine the
+list of Domain controllers to use for authentication, you may set this line to be :
+<p><br><code>password server = *</code>
+<p><br>This method, which is new in Samba 2.0.6 and above, allows Samba
+to use exactly the same mechanism that NT does. This method either broadcasts or
+uses a WINS database in order to find domain controllers to
 authenticate against.
-<p><br>Originally, I considered this idea for Samba, but dropped it because
-it seemed so insecure.  However several Samba-2 alpha users have
-requested that this feature be added to make Samba more NT-like, so
-I'll probably add a special name of <code>'*'</code> (which means: act like NT
-when looking for domain controllers) in a future release of the
-code. At present, however, you need to know where your domain
-controllers are.
 <p><br>Finally, restart your Samba daemons and get ready for clients to begin
 using domain security!
 <p><br><center>Why is this better than security = server? </center>
index 3139e90ad128848ea4811f5d0f83c2b9419d9d43..03fd3588e2654ae988178a9799f3389719fa558b 100644 (file)
@@ -25,7 +25,7 @@ naming services to clients
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
     
-<p><br><strong>nmbd</strong> [<a href="nmbd.8.html#minusD">-D</a>] [<a href="nmbd.8.html#minuso">-o</a>] [<a href="nmbd.8.html#minusa">-a</a>] [<a href="nmbd.8.html#minusH">-H lmhosts file</a>] [<a href="nmbd.8.html#minusd">-d debuglevel</a>] [<a href="nmbd.8.html#minusl">-l log file basename</a>] [<a href="nmbd.8.html#minusn">-n primary NetBIOS name</a>] [<a href="nmbd.8.html#minusp">-p port number</a>] [<a href="nmbd.8.html#minuss">-s configuration file</a>] [<a href="nmbd.8.html#minusi">-i NetBIOS scope</a>] [<a href="nmbd.8.html#minush">-h</a>]
+<p><br><strong>nmbd</strong> [<a href="nmbd.8.html#minusD">-D</a>] [<a href="nmbd.8.html#minusa">-a</a>] [<a href="nmbd.8.html#minuso">-o</a>] [<a href="nmbd.8.html#minush">-h</a>] [<a href="nmbd.8.html#minusV">-V</a>] [<a href="nmbd.8.html#minusH">-H lmhosts file</a>] [<a href="nmbd.8.html#minusd">-d debuglevel</a>] [<a href="nmbd.8.html#minusl">-l log file basename</a>] [<a href="nmbd.8.html#minusn">-n primary NetBIOS name</a>] [<a href="nmbd.8.html#minusp">-p port number</a>] [<a href="nmbd.8.html#minuss">-s configuration file</a>] [<a href="nmbd.8.html#minusi">-i NetBIOS scope</a>]
 <p><br><a name="DESCRIPTION"></a>
 <h2>DESCRIPTION</h2>
     
@@ -70,6 +70,10 @@ append log messages to the log file.  This is the default.
 <li><strong><strong>-o</strong></strong> If this parameter is specified, the log files will be
 overwritten when opened.  By default, the log files will be appended
 to.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>nmbd</strong>.
+<p><br><a name="minusV"></a>
+<li><strong><strong>-V</strong></strong> Prints the version number for <strong>nmbd</strong>.
 <p><br><a name="minusH"></a>
 <li><strong><strong>-H filename</strong></strong> NetBIOS lmhosts file.
 <p><br>The lmhosts file is a list of NetBIOS names to IP addresses that is
@@ -133,8 +137,6 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
 are <em>very</em> rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
-<p><br><a name="minush"></a>
-<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>nmbd</strong>.
 <p><br></ul>
 <p><br><a name="FILES"></a>
 <h2>FILES</h2>
index 5ff58e5b401613b078c02af45f187732a3d57c5a..2c3e80c76e24516f8cd804507b65c8df021e36b2 100644 (file)
@@ -24,7 +24,7 @@
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
      
-<p><br><strong>nmblookup</strong> [<a href="nmblookup.1.html#minusM">-M</a>] [<a href="nmblookup.1.html#minusR">-R</a>] [<a href="nmblookup.1.html#minusS">-S</a>] [<a href="nmblookup.1.html#minusr">-r</a>] [<a href="nmblookup.1.html#minusA">-A</a>] [<a href="nmblookup.1.html#minush">-h</a>] [<a href="nmblookup.1.html#minusB">-B broadcast address</a>] [<a href="nmblookup.1.html#minusU">-U unicast address</a>] [<a href="nmblookup.1.html#minusd">-d debuglevel</a>] [<a href="nmblookup.1.html#minuss">-s smb config file</a>] [<a href="nmblookup.1.html#minusi">-i NetBIOS scope</a>] <a href="nmblookup.1.html#name">name</a>
+<p><br><strong>nmblookup</strong> [<a href="nmblookup.1.html#minusM">-M</a>] [<a href="nmblookup.1.html#minusR">-R</a>] [<a href="nmblookup.1.html#minusS">-S</a>] [<a href="nmblookup.1.html#minusr">-r</a>] [<a href="nmblookup.1.html#minusA">-A</a>] [<a href="nmblookup.1.html#minush">-h</a>] [<a href="nmblookup.1.html#minusB">-B broadcast address</a>] [<a href="nmblookup.1.html#minusU">-U unicast address</a>] [<a href="nmblookup.1.html#minusd">-d debuglevel</a>] [<a href="nmblookup.1.html#minuss">-s smb config file</a>] [<a href="nmblookup.1.html#minusi">-i NetBIOS scope</a>] [<a href="nmblookup.1.html#minusT">-T</a>] <a href="nmblookup.1.html#name">name</a>
 <p><br><a name="DESCRIPTION"></a>
 <h2>DESCRIPTION</h2>
     
@@ -38,8 +38,9 @@ or to a particular machine. All queries are done over UDP.
     
 <p><br><ul>
 <p><br><a name="minusM"></a>
-<li><strong><strong>-M</strong></strong> Searches for a master browser. This is done by doing a
-broadcast lookup on the special name <code>__MSBROWSE__</code>.
+<li><strong><strong>-M</strong></strong> Searches for a master browser by looking up the 
+NetBIOS name <a href="nmblookup.1.html#name"><strong>name</strong></a> with a type of 0x1d. If <a href="nmblookup.1.html#name"><strong>name</strong></a>
+is <code>"-"</code> then it does a lookup on the special name <code>__MSBROWSE__</code>.
 <p><br><a name="minusR"></a>
 <li><strong><strong>-R</strong></strong> Set the recursion desired bit in the packet to do a
 recursive lookup. This is used when sending a name query to a machine
@@ -67,8 +68,8 @@ query on this address.
 <p><br><a name="minusB"></a>
 <li><strong><strong>-B broadcast address</strong></strong> Send the query to the given broadcast
 address. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the primary network
-interface as either auto-detected or defined in the 
+send the query to the broadcast address of the network
+interfaces as either auto-detected or defined in the 
 <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a> parameter of the 
 <a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a> file.
 <p><br><a name="minusU"></a>
@@ -100,6 +101,11 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
 are <em>very</em> rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
+<p><br><a name="minusT"></a>
+<li><strong><strong>-T</strong></strong> This causes any IP addresses found in the lookup to be
+looked up via a reverse DNS lookup into a DNS name, and printed out
+before each <code>"IP address   NetBIOS name"</code> pair that is the normal
+output.
 <p><br><a name="name"></a>
 <li><strong><strong>name</strong></strong> This is the NetBIOS name being queried. Depending upon
 the previous options this may be a NetBIOS name or IP address. If a
index 2fc86fd65af268c91ec0cba25fc8d5908b5033a4..f197ccfa32cdc681f1e26ef3613129b0883d81ce 100644 (file)
@@ -56,14 +56,6 @@ client. This is useful for accessing SMB shares on other compatible
 servers (such as Windows NT), and can also be used to allow a UNIX box
 to print to a printer attached to any SMB server (such as a PC running
 Windows NT).
-<p><br><li><strong><a href="rpcclient.1.html"><strong>rpcclient</strong></a></strong> <br> <br> The <a href="rpcclient.1.html"><strong>rpcclient</strong>
-(1)</a> program is a client that can 'talk' to an
-SMB/CIFS MSRPC server.  Operations include things like managing a SAM
-Database (users, groups and aliases) in the same way as the Windows NT
-programs <strong>User Manager for Domains</strong> and <strong>Server Manager for Domains</strong>;
-managing a remote registry in the same way as the Windows NT programs
-<strong>REGEDT32.EXE</strong> and <strong>REGEDIT.EXE</strong>; viewing a remote event log (same
-as <strong>EVENTVWR.EXE</strong>).
 <p><br><li><strong><a href="testparm.1.html"><strong>testparm</strong></a></strong> <br> <br> The <a href="testparm.1.html"><strong>testparm
 (1)</strong></a> utility allows you to test your <a href="smb.conf.5.html"><strong>smb.conf
 (5)</strong></a> configuration file.
index f2f75170f80fe84a588df1cd14f49d06bf95bebe..521c70d653efc338c7aad130b7d6ba7909210b6f 100644 (file)
@@ -204,6 +204,7 @@ would look like this:
 
        [printers]
                path = /usr/spool/public
+               writeable = no
                guest ok = yes
                printable = yes 
 
@@ -400,6 +401,8 @@ password.
 <p><br>Here is a list of all global parameters. See the section of each
 parameter for details.  Note that some are synonyms.
 <p><br><ul>
+<p><br><li > <a href="smb.conf.5.html#adduserscript"><strong>add user script</strong></a>
+<p><br><li > <a href="smb.conf.5.html#allowtrusteddomains"><strong>allow trusted domains</strong></a>
 <p><br><li > <a href="smb.conf.5.html#announceas"><strong>announce as</strong></a>
 <p><br><li > <a href="smb.conf.5.html#announceversion"><strong>announce version</strong></a>
 <p><br><li > <a href="smb.conf.5.html#autoservices"><strong>auto services</strong></a>
@@ -411,22 +414,24 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#codingsystem"><strong>coding system</strong></a>
 <p><br><li > <a href="smb.conf.5.html#configfile"><strong>config file</strong></a>
 <p><br><li > <a href="smb.conf.5.html#deadtime"><strong>deadtime</strong></a>
+<p><br><li > <a href="smb.conf.5.html#debughirestimestamp"><strong>debug hires timestamp</strong></a>
+<p><br><li > <a href="smb.conf.5.html#debugpid"><strong>debug pid</strong></a>
 <p><br><li > <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
+<p><br><li > <a href="smb.conf.5.html#debuguid"><strong>debug uid</strong></a>
 <p><br><li > <a href="smb.conf.5.html#debuglevel"><strong>debuglevel</strong></a>
 <p><br><li > <a href="smb.conf.5.html#default"><strong>default</strong></a>
 <p><br><li > <a href="smb.conf.5.html#defaultservice"><strong>default service</strong></a>
+<p><br><li > <a href="smb.conf.5.html#deleteuserscript"><strong>delete user script</strong></a>
 <p><br><li > <a href="smb.conf.5.html#dfreecommand"><strong>dfree command</strong></a>
 <p><br><li > <a href="smb.conf.5.html#dnsproxy"><strong>dns proxy</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainadmingroup"><strong>domain admin group</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainadminusers"><strong>domain admin users</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domaincontroller"><strong>domain controller</strong></a>
-<p><br><li > <a href="smb.conf.5.html#domaingroupmap"><strong>domain group map</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domaingroups"><strong>domain groups</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainguestgroup"><strong>domain guest group</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainguestusers"><strong>domain guest users</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainlogons"><strong>domain logons</strong></a>
 <p><br><li > <a href="smb.conf.5.html#domainmaster"><strong>domain master</strong></a>
-<p><br><li > <a href="smb.conf.5.html#domainusermap"><strong>domain user map</strong></a>
 <p><br><li > <a href="smb.conf.5.html#encryptpasswords"><strong>encrypt passwords</strong></a>
 <p><br><li > <a href="smb.conf.5.html#getwdcache"><strong>getwd cache</strong></a>
 <p><br><li > <a href="smb.conf.5.html#homedirmap"><strong>homedir map</strong></a>
@@ -434,15 +439,15 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a>
 <p><br><li > <a href="smb.conf.5.html#keepalive"><strong>keepalive</strong></a>
 <p><br><li > <a href="smb.conf.5.html#kerneloplocks"><strong>kernel oplocks</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ldapbindas"><strong>ldap bind as</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ldappasswdfile"><strong>ldap passwd file</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ldapfilter"><strong>ldap filter</strong></a>
 <p><br><li > <a href="smb.conf.5.html#ldapport"><strong>ldap port</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ldaproot"><strong>ldap root</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ldaprootpasswd"><strong>ldap root passwd</strong></a>
 <p><br><li > <a href="smb.conf.5.html#ldapserver"><strong>ldap server</strong></a>
 <p><br><li > <a href="smb.conf.5.html#ldapsuffix"><strong>ldap suffix</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lmannounce"><strong>lm announce</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lminterval"><strong>lm interval</strong></a>
 <p><br><li > <a href="smb.conf.5.html#loadprinters"><strong>load printers</strong></a>
-<p><br><li > <a href="smb.conf.5.html#localgroupmap"><strong>local group map</strong></a>
 <p><br><li > <a href="smb.conf.5.html#localmaster"><strong>local master</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lockdir"><strong>lock dir</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lockdirectory"><strong>lock directory</strong></a>
@@ -455,6 +460,7 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#lpqcachetime"><strong>lpq cache time</strong></a>
 <p><br><li > <a href="smb.conf.5.html#machinepasswordtimeout"><strong>machine password timeout</strong></a>
 <p><br><li > <a href="smb.conf.5.html#mangledstack"><strong>mangled stack</strong></a>
+<p><br><li > <a href="smb.conf.5.html#maptoguest"><strong>map to guest</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maxdisksize"><strong>max disk size</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maxlogsize"><strong>max log size</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maxmux"><strong>max mux</strong></a>
@@ -464,15 +470,18 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#maxwinsttl"><strong>max wins ttl</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maxxmit"><strong>max xmit</strong></a>
 <p><br><li > <a href="smb.conf.5.html#messagecommand"><strong>message command</strong></a>
+<p><br><li > <a href="smb.conf.5.html#minpasswdlength"><strong>min passwd length</strong></a>
 <p><br><li > <a href="smb.conf.5.html#minwinsttl"><strong>min wins ttl</strong></a>
 <p><br><li > <a href="smb.conf.5.html#nameresolveorder"><strong>name resolve order</strong></a>
 <p><br><li > <a href="smb.conf.5.html#netbiosaliases"><strong>netbios aliases</strong></a>
 <p><br><li > <a href="smb.conf.5.html#netbiosname"><strong>netbios name</strong></a>
 <p><br><li > <a href="smb.conf.5.html#nishomedir"><strong>nis homedir</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ntaclsupport"><strong>nt acl support</strong></a>
 <p><br><li > <a href="smb.conf.5.html#ntpipesupport"><strong>nt pipe support</strong></a>
 <p><br><li > <a href="smb.conf.5.html#ntsmbsupport"><strong>nt smb support</strong></a>
 <p><br><li > <a href="smb.conf.5.html#nullpasswords"><strong>null passwords</strong></a>
 <p><br><li > <a href="smb.conf.5.html#olelockingcompatibility"><strong>ole locking compatibility</strong></a>
+<p><br><li > <a href="smb.conf.5.html#oplockbreakwaittime"><strong>oplock break wait time</strong></a>
 <p><br><li > <a href="smb.conf.5.html#oslevel"><strong>os level</strong></a>
 <p><br><li > <a href="smb.conf.5.html#packetsize"><strong>packet size</strong></a>
 <p><br><li > <a href="smb.conf.5.html#panicaction"><strong>panic action</strong></a>
@@ -494,6 +503,7 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#readsize"><strong>read size</strong></a>
 <p><br><li > <a href="smb.conf.5.html#remoteannounce"><strong>remote announce</strong></a>
 <p><br><li > <a href="smb.conf.5.html#remotebrowsesync"><strong>remote browse sync</strong></a>
+<p><br><li > <a href="smb.conf.5.html#restrictanonymous"><strong>restrict anonymous</strong></a>
 <p><br><li > <a href="smb.conf.5.html#root"><strong>root</strong></a>
 <p><br><li > <a href="smb.conf.5.html#rootdir"><strong>root dir</strong></a>
 <p><br><li > <a href="smb.conf.5.html#rootdirectory"><strong>root directory</strong></a>
@@ -535,6 +545,7 @@ parameter for details.  Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#validchars"><strong>valid chars</strong></a>
 <p><br><li > <a href="smb.conf.5.html#winsproxy"><strong>wins proxy</strong></a>
 <p><br><li > <a href="smb.conf.5.html#winsserver"><strong>wins server</strong></a>
+<p><br><li > <a href="smb.conf.5.html#winshook"><strong>wins hook</strong></a>
 <p><br><li > <a href="smb.conf.5.html#winssupport"><strong>wins support</strong></a>
 <p><br><li > <a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a>
 <p><br><li > <a href="smb.conf.5.html#writeraw"><strong>write raw</strong></a>
@@ -565,6 +576,7 @@ parameter for details. Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#directory"><strong>directory</strong></a>
 <p><br><li > <a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a>
 <p><br><li > <a href="smb.conf.5.html#directorymode"><strong>directory mode</strong></a>
+<p><br><li > <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security mask</strong></a>
 <p><br><li > <a href="smb.conf.5.html#dontdescend"><strong>dont descend</strong></a>
 <p><br><li > <a href="smb.conf.5.html#dosfiletimeresolution"><strong>dos filetime resolution</strong></a>
 <p><br><li > <a href="smb.conf.5.html#dosfiletimes"><strong>dos filetimes</strong></a>
@@ -574,7 +586,9 @@ parameter for details. Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#followsymlinks"><strong>follow symlinks</strong></a>
 <p><br><li > <a href="smb.conf.5.html#forcecreatemode"><strong>force create mode</strong></a>
 <p><br><li > <a href="smb.conf.5.html#forcedirectorymode"><strong>force directory mode</strong></a>
+<p><br><li > <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security mode</strong></a>
 <p><br><li > <a href="smb.conf.5.html#forcegroup"><strong>force group</strong></a>
+<p><br><li > <a href="smb.conf.5.html#forcesecuritymode"><strong>force security mode</strong></a>
 <p><br><li > <a href="smb.conf.5.html#forceuser"><strong>force user</strong></a>
 <p><br><li > <a href="smb.conf.5.html#fstype"><strong>fstype</strong></a>
 <p><br><li > <a href="smb.conf.5.html#group"><strong>group</strong></a>
@@ -587,6 +601,7 @@ parameter for details. Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#hostsdeny"><strong>hosts deny</strong></a>
 <p><br><li > <a href="smb.conf.5.html#include"><strong>include</strong></a>
 <p><br><li > <a href="smb.conf.5.html#invalidusers"><strong>invalid users</strong></a>
+<p><br><li > <a href="smb.conf.5.html#level2oplocks"><strong>level2 oplocks</strong></a>
 <p><br><li > <a href="smb.conf.5.html#locking"><strong>locking</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lppausecommand"><strong>lppause command</strong></a>
 <p><br><li > <a href="smb.conf.5.html#lpqcommand"><strong>lpq command</strong></a>
@@ -595,22 +610,24 @@ parameter for details. Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#magicoutput"><strong>magic output</strong></a>
 <p><br><li > <a href="smb.conf.5.html#magicscript"><strong>magic script</strong></a>
 <p><br><li > <a href="smb.conf.5.html#manglecase"><strong>mangle case</strong></a>
+<p><br><li > <a href="smb.conf.5.html#manglelocks"><strong>mangle locks</strong></a>
 <p><br><li > <a href="smb.conf.5.html#mangledmap"><strong>mangled map</strong></a>
 <p><br><li > <a href="smb.conf.5.html#manglednames"><strong>mangled names</strong></a>
 <p><br><li > <a href="smb.conf.5.html#manglingchar"><strong>mangling char</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maparchive"><strong>map archive</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maphidden"><strong>map hidden</strong></a>
 <p><br><li > <a href="smb.conf.5.html#mapsystem"><strong>map system</strong></a>
-<p><br><li > <a href="smb.conf.5.html#maptoguest"><strong>map to guest</strong></a>
 <p><br><li > <a href="smb.conf.5.html#maxconnections"><strong>max connections</strong></a>
 <p><br><li > <a href="smb.conf.5.html#minprintspace"><strong>min print space</strong></a>
 <p><br><li > <a href="smb.conf.5.html#onlyguest"><strong>only guest</strong></a>
 <p><br><li > <a href="smb.conf.5.html#onlyuser"><strong>only user</strong></a>
 <p><br><li > <a href="smb.conf.5.html#oplocks"><strong>oplocks</strong></a>
+<p><br><li > <a href="smb.conf.5.html#oplockcontentionlimit"><strong>oplock contention limit</strong></a>
 <p><br><li > <a href="smb.conf.5.html#path"><strong>path</strong></a>
 <p><br><li > <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>
 <p><br><li > <a href="smb.conf.5.html#postscript"><strong>postscript</strong></a>
 <p><br><li > <a href="smb.conf.5.html#preexec"><strong>preexec</strong></a>
+<p><br><li > <a href="smb.conf.5.html#preexecclose"><strong>preexec close</strong></a>
 <p><br><li > <a href="smb.conf.5.html#preservecase"><strong>preserve case</strong></a>
 <p><br><li > <a href="smb.conf.5.html#printcommand"><strong>print command</strong></a>
 <p><br><li > <a href="smb.conf.5.html#printok"><strong>print ok</strong></a>
@@ -628,6 +645,8 @@ parameter for details. Note that some are synonyms.
 <p><br><li > <a href="smb.conf.5.html#revalidate"><strong>revalidate</strong></a>
 <p><br><li > <a href="smb.conf.5.html#rootpostexec"><strong>root postexec</strong></a>
 <p><br><li > <a href="smb.conf.5.html#rootpreexec"><strong>root preexec</strong></a>
+<p><br><li > <a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>
+<p><br><li > <a href="smb.conf.5.html#rootpreexecclose"><strong>root preexec close</strong></a>
 <p><br><li > <a href="smb.conf.5.html#setdirectory"><strong>set directory</strong></a>
 <p><br><li > <a href="smb.conf.5.html#sharemodes"><strong>share modes</strong></a>
 <p><br><li > <a href="smb.conf.5.html#shortpreservecase"><strong>short preserve case</strong></a>
@@ -652,6 +671,46 @@ parameter for details. Note that some are synonyms.
 <h2>EXPLANATION OF EACH PARAMETER</h2>
     
 <p><br><ul>
+<p><br><a name="adduserscript"></a>
+<li><strong><strong>add user script (G)</strong></strong>
+<p><br>This is the full pathname to a script that will be run <em>AS ROOT</em> by
+<a href="smbd.8.html"><strong>smbd (8)</strong></a> under special circumstances decribed
+below.
+<p><br>Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task. This option allows <a href="smbd.8.html"><strong>smbd</strong></a> to create
+the required UNIX users <em>ON DEMAND</em> when a user accesses the Samba
+server.
+<p><br>In order to use this option, <a href="smbd.8.html"><strong>smbd</strong></a> must be set to
+<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> or
+<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a> and <strong>"add user script"</strong>
+must be set to a full pathname for a script that will create a UNIX user
+given one argument of <strong>%u</strong>, which expands into the UNIX user name to
+create.
+<p><br>When the Windows user attempts to access the Samba server, at
+<em>"login"</em>(session setup in the SMB protocol) time,
+<a href="smbd.8.html"><strong>smbd</strong></a> contacts the <a href="smb.conf.5.html#passwordserver"><strong>password
+server</strong></a> and attempts to authenticate the given user
+with the given password. If the authentication succeeds then
+<a href="smbd.8.html"><strong>smbd</strong></a> attempts to find a UNIX user in the UNIX
+password database to map the Windows user into. If this lookup fails,
+and <strong>"add user script"</strong> is set then <a href="smbd.8.html"><strong>smbd</strong></a> will
+call the specified script <em>AS ROOT</em>, expanding any <strong>%u</strong> argument
+to be the user name to create.
+<p><br>If this script successfully creates the user then
+<a href="smbd.8.html"><strong>smbd</strong></a> will continue on as though the UNIX user
+already existed. In this way, UNIX users are dynamically created to
+match existing Windows NT accounts.
+<p><br>See also <a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a>,
+<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>, <a href="smb.conf.5.html#passwordserver"><strong>password
+server</strong></a>, <a href="smb.conf.5.html#deleteuserscript"><strong>delete user
+script</strong></a>.
+<p><br><strong>Default:</strong>
+<code> add user script = &lt;empty string&gt;</code>
+<p><br><strong>Example:</strong>
+<code> add user script = /usr/local/samba/bin/add_user %u</code>
 <p><br><a name="adminusers"></a>
 <li><strong><strong>admin users (S)</strong></strong>
 <p><br>This is a list of users who will be granted administrative privileges
@@ -666,46 +725,25 @@ file permissions.
 <code> admin users = jason</code>
 <p><br><a name="allowhosts"></a>
 <li><strong><strong>allow hosts (S)</strong></strong>
-<p><br>A synonym for this parameter is <a href="smb.conf.5.html#hostsallow"><strong>'hosts allow'</strong></a>
-<p><br>This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service.
-<p><br>If specified in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section then it will
-apply to all services, regardless of whether the individual service
-has a different setting.
-<p><br>You can specify the hosts by name or IP number. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like <code>"allow hosts = 150.203.5."</code>. The full syntax of the list is
-described in the man page <strong>hosts_access (5)</strong>. Note that this man
-page may not be present on your system, so a brief description will
-be given here also.
-<p><br><em>NOTE:</em> IF you wish to allow the <a href="smbpasswd.html.8"><strong>smbpasswd
-(8)</strong></a> program to be run by local users to change
-their Samba passwords using the local <a href="smbd.8.html"><strong>smbd (8)</strong></a>
-daemon, then you <em>MUST</em> ensure that the localhost is listed in your
-<strong>allow hosts</strong> list, as <a href="smbpasswd.html.8"><strong>smbpasswd (8)</strong></a> runs
-in client-server mode and is seen by the local
-<a href="smbd.8.html"><strong>smbd</strong></a> process as just another client.
-<p><br>You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups. The <em>EXCEPT</em> keyword can also
-be used to limit a wildcard list. The following examples may provide
-some help:
-<p><br><strong>Example 1</strong>: allow localhost and all IPs in 150.203.*.* except one
-<p><br><code>  hosts allow = localhost, 150.203. EXCEPT 150.203.6.66</code>
-<p><br><strong>Example 2</strong>: allow localhost and hosts that match the given network/netmask
-<p><br><code>  hosts allow = localhost, 150.203.15.0/255.255.255.0</code>
-<p><br><strong>Example 3</strong>: allow a localhost plus a couple of hosts
-<p><br><code>  hosts allow = localhost, lapland, arvidsjaur</code>
-<p><br><strong>Example 4</strong>: allow only hosts in NIS netgroup "foonet" or localhost, but 
-deny access from one particular host
-<p><br><code>  hosts allow = @foonet, localhost</code>
-<code>         hosts deny = pirate</code>
-<p><br>Note that access still requires suitable user-level passwords.
-<p><br>See <a href="testparm.1.html"><strong>testparm (1)</strong></a> for a way of testing your
-host access to see if it does what you expect.
-<p><br><strong>Default:</strong>
-<code> none (i.e., all hosts permitted access)</code>
-<p><br><strong>Example:</strong>
-<code> allow hosts = 150.203.5. localhost myhost.mynet.edu.au</code>
+<p><br>Synonym for <a href="smb.conf.5.html#hostsallow"><strong>hosts allow</strong></a>.
+<p><br><a name="allowtrusteddomains"></a>
+<li><strong><strong>allow trusted domains (G)</strong></strong>
+<p><br>This option only takes effect when the <a href="smb.conf.5.html#security"><strong>security</strong></a>
+option is set to <strong>server</strong> or <strong>domain</strong>.  If it is set to no,
+then attempts to connect to a resource from a domain or workgroup other than
+the one which smbd is running in will fail, even if that domain
+is trusted by the remote server doing the authentication.
+<p><br>This is useful if you only want your Samba server to serve resources
+to users in the domain it is a member of. As an example, suppose that there are
+two domains DOMA and DOMB.  DOMB is trusted by DOMA, which contains
+the Samba server.  Under normal circumstances, a user with an account
+in DOMB can then access the resources of a UNIX account with the same
+account name on the Samba server even if they do not have an account
+in DOMA.  This can make implementing a security boundary difficult.
+<p><br><strong>Default:</strong>
+<code>     allow trusted domains = Yes</code>
+<p><br><strong>Example:</strong>
+<code>     allow trusted domains = No</code>
 <p><br><a name="alternatepermissions"></a>
 <li><strong><strong>alternate permissions (S)</strong></strong>
 <p><br>This is a deprecated parameter. It no longer has any effect in Samba2.0.
@@ -717,13 +755,14 @@ regardless if the owner of the file is the currently logged on user or not.
 <li><strong><strong>announce as (G)</strong></strong>
 <p><br>This specifies what type of server <a href="nmbd.8.html"><strong>nmbd</strong></a> will
 announce itself as, to a network neighborhood browse list. By default
-this is set to Windows NT. The valid options are : "NT", "Win95" or
-"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
-respectively. Do not change this parameter unless you have a specific
-need to stop Samba appearing as an NT server as this may prevent Samba
-servers from participating as browser servers correctly.
-<p><br><strong>Default:</strong>
-<code> announce as = NT</code>
+this is set to Windows NT. The valid options are : "NT", which is a
+synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
+"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
+and Windows for Workgroups respectively. Do not change this parameter
+unless you have a specific need to stop Samba appearing as an NT server
+as this may prevent Samba servers from participating as browser servers correctly.
+<p><br><strong>Default:</strong>
+<code> announce as = NT Server</code>
 <p><br><strong>Example</strong>
 <code> announce as = Win95</code>
 <p><br><a name="announceversion"></a>
@@ -787,11 +826,15 @@ will serve to packets coming in those interfaces.  Note that you
 should not use this parameter for machines that are serving PPP or
 other intermittent or non-broadcast network interfaces as it will not
 cope with non-permanent interfaces.
-<p><br>In addition, to change a users SMB password, the
-<a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> by default connects to the
-<em>"localhost" - 127.0.0.1</em> address as an SMB client to issue the
-password change request. If <strong>"bind interfaces only"</strong> is set then
-unless the network address <em>127.0.0.1</em> is added to the
+<p><br>If <strong>"bind interfaces only"</strong> is set then unless the network address
+<em>127.0.0.1</em> is added to the <a href="smb.conf.5.html#interfaces"><strong>'interfaces'</strong></a> parameter
+list <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> and
+<a href="swat.8.html"><strong>swat</strong></a> may not work as expected due to the
+reasons covered below.
+<p><br>To change a users SMB password, the <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a>
+by default connects to the <em>"localhost" - 127.0.0.1</em> address as an SMB
+client to issue the password change request. If <strong>"bind interfaces only"</strong>
+is set then unless the network address <em>127.0.0.1</em> is added to the
 <a href="smb.conf.5.html#interfaces"><strong>'interfaces'</strong></a> parameter list then
 <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> will fail to connect in it's
 default mode. <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> can be forced to
@@ -799,6 +842,13 @@ use the primary IP interface of the local host by using its
 <a href="smbpasswd.8.html#minusr"><strong>"-r remote machine"</strong></a> parameter, with
 <strong>"remote machine"</strong> set to the IP name of the primary interface
 of the local host.
+<p><br>The <a href="swat.8.html"><strong>swat</strong></a> status page tries to connect with
+<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a> at the address 
+<em>127.0.0.1</em> to determine if they are running.  Not adding <em>127.0.0.1</em>  will cause
+<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a> to always show
+"not running" even if they really are.  This can prevent
+<a href="swat.8.html"><strong>swat</strong></a> from starting/stopping/restarting
+<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a>.
 <p><br><strong>Default:</strong>
 <code> bind interfaces only = False</code>
 <p><br><strong>Example:</strong>
@@ -839,10 +889,10 @@ shares in a net view and in the browse list.
 <p><br><strong>Example:</strong>
 <code> browseable = No</code>
 <p><br><a name="casesensitive"></a>
-<li><strong><strong>case sensitive (S)</strong></strong>
+<li><strong><strong>case sensitive (G)</strong></strong>
 <p><br>See the discussion in the section <a href="smb.conf.5.html#NAMEMANGLING"><strong>NAME MANGLING</strong></a>.
 <p><br><a name="casesignames"></a>
-<li><strong><strong>casesignames (S)</strong></strong>
+<li><strong><strong>casesignames (G)</strong></strong>
 <p><br>Synonym for <a href="smb.conf.5.html#casesensitive"><strong>"case sensitive"</strong></a>.
 <p><br><a name="changenotifytimeout"></a>
 <li><strong><strong>change notify timeout (G)</strong></strong>
@@ -877,7 +927,12 @@ in order for the conversion to the UNIX character set to be done
 correctly. 
 <p><br><li > <strong>ISO8859-5</strong> Russian Cyrillic UNIX character set. The parameter
 <a href="smb.conf.5.html#clientcodepage"><strong>client code page</strong></a> <em>MUST</em> be set to code
-page 866 if the <strong>character set</strong> parameter is set to ISO8859-2
+page 866 if the <strong>character set</strong> parameter is set to ISO8859-5
+in order for the conversion to the UNIX character set to be done
+correctly. 
+<p><br><li > <strong>ISO8859-7</strong> Greek UNIX character set. The parameter
+<a href="smb.conf.5.html#clientcodepage"><strong>client code page</strong></a> <em>MUST</em> be set to code
+page 737 if the <strong>character set</strong> parameter is set to ISO8859-7
 in order for the conversion to the UNIX character set to be done
 correctly. 
 <p><br><li > <strong>KOI8-R</strong> Alternate mapping for Russian Cyrillic UNIX
@@ -1048,6 +1103,17 @@ performed.
 <code> deadtime = 0</code>
 <p><br><strong>Example:</strong>
 <code> deadtime = 15</code>
+<p><br><a name="debughirestimestamp"></a>
+<li><strong><strong>debug hires timestamp (G)</strong></strong>
+<p><br>Sometimes the timestamps in the log messages are needed with a
+resolution of higher that seconds, this boolean parameter adds
+microsecond resolution to the timestamp message header when turned on.
+<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
+must be on for this to have an effect.
+<p><br><strong>Default:</strong>
+<code> debug hires timestamp = No</code>
+<p><br><strong>Example:</strong>
+<code> debug hires timestamp = Yes</code>
 <p><br><a name="debugtimestamp"></a>
 <li><strong><strong>debug timestamp (G)</strong></strong>
 <p><br>Samba2.0 debug log messages are timestamped by default. If you are
@@ -1058,6 +1124,29 @@ off.
 <code> debug timestamp = Yes</code>
 <p><br><strong>Example:</strong>
 <code> debug timestamp = No</code>
+<p><br><a name="debugpid"></a>
+<li><strong><strong>debug pid (G)</strong></strong>
+<p><br>When using only one log file for more then one forked smbd-process
+there may be hard to follow which process outputs which message.
+This boolean parameter is adds the process-id to the timestamp message
+headers in the logfile when turned on.
+<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
+must be on for this to have an effect.
+<p><br><strong>Default:</strong>
+<code> debug pid = No</code>
+<p><br><strong>Example:</strong>
+<code> debug pid = Yes</code>
+<p><br><a name="debuguid"></a>
+<li><strong><strong>debug uid (G)</strong></strong>
+<p><br>Samba is sometimes run as root and sometime run as the connected
+user, this boolean parameter inserts the current euid, egid, uid
+and gid to the timestamp message headers in the log file if turned on.
+<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
+must be on for this to have an effect.
+<p><br><strong>Default:</strong>
+<code> debug uid = No</code>
+<p><br><strong>Example:</strong>
+<code> debug uid = Yes</code>
 <p><br><a name="debuglevel"></a>
 <li><strong><strong>debug level (G)</strong></strong>
 <p><br>The value of the parameter (an integer) allows the debug level
@@ -1101,6 +1190,51 @@ interesting things.
 
 </pre>
 
+<p><br><a name="deleteuserscript"></a>
+<li><strong><strong>delete user script (G)</strong></strong>
+<p><br>This is the full pathname to a script that will be run <em>AS ROOT</em> by
+<a href="smbd.8.html"><strong>smbd (8)</strong></a> under special circumstances decribed
+below.
+<p><br>Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task. This option allows <a href="smbd.8.html"><strong>smbd</strong></a> to delete
+the required UNIX users <em>ON DEMAND</em> when a user accesses the Samba
+server and the Windows NT user no longer exists.
+<p><br>In order to use this option, <a href="smbd.8.html"><strong>smbd</strong></a> must be set to
+<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a> and <strong>"delete user
+script"</strong> must be set to a full pathname for a script that will delete
+a UNIX user given one argument of <strong>%u</strong>, which expands into the UNIX
+user name to delete. <em>NOTE</em> that this is different to the
+<a href="smb.conf.5.html#adduserscript"><strong>add user script</strong></a> which will work with the
+<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> option as well as
+<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>. The reason for this
+is only when Samba is a domain member does it get the information
+on an attempted user logon that a user no longer exists. In the
+<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> mode a missing user
+is treated the same as an invalid password logon attempt. Deleting
+the user in this circumstance would not be a good idea.
+<p><br>When the Windows user attempts to access the Samba server, at
+<em>"login"</em>(session setup in the SMB protocol) time,
+<a href="smbd.8.html"><strong>smbd</strong></a> contacts the <a href="smb.conf.5.html#passwordserver"><strong>password
+server</strong></a> and attempts to authenticate the given user
+with the given password. If the authentication fails with the specific
+Domain error code meaning that the user no longer exists then
+<a href="smbd.8.html"><strong>smbd</strong></a> attempts to find a UNIX user in the UNIX
+password database that matches the Windows user account. If this lookup succeeds,
+and <strong>"delete user script"</strong> is set then <a href="smbd.8.html"><strong>smbd</strong></a> will
+call the specified script <em>AS ROOT</em>, expanding any <strong>%u</strong> argument
+to be the user name to delete.
+<p><br>This script should delete the given UNIX username. In this way, UNIX
+users are dynamically deleted to match existing Windows NT accounts.
+<p><br>See also <a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>,
+<a href="smb.conf.5.html#passwordserver"><strong>password server</strong></a>, <a href="smb.conf.5.html#adduserscript"><strong>add user
+script</strong></a>.
+<p><br><strong>Default:</strong>
+<code> delete user script = &lt;empty string&gt;</code>
+<p><br><strong>Example:</strong>
+<code> delete user script = /usr/local/samba/bin/del_user %u</code>
 <p><br><a name="deletereadonly"></a>
 <li><strong><strong>delete readonly (S)</strong></strong>
 <p><br>This parameter allows readonly files to be deleted.  This is not
@@ -1135,14 +1269,7 @@ as the user has permissions to do so).
 <code> delete veto files = True</code>
 <p><br><a name="denyhosts"></a>
 <li><strong><strong>deny hosts (S)</strong></strong>
-<p><br>The opposite of <a href="smb.conf.5.html#allowhosts"><strong>'allow hosts'</strong></a> - hosts listed
-here are <em>NOT</em> permitted access to services unless the specific
-services have their own lists to override this one. Where the lists
-conflict, the <a href="smb.conf.5.html#allowhosts"><strong>'allow'</strong></a> list takes precedence.
-<p><br><strong>Default:</strong>
-<code> none (i.e., no hosts specifically excluded)</code>
-<p><br><strong>Example:</strong>
-<code> deny hosts = 150.203.4. badhost.mynet.edu.au</code>
+<p><br>Synonym for <a href="smb.conf.5.html#hostsdeny"><strong>hosts deny</strong></a>.
 <p><br><a name="dfreecommand"></a>
 <li><strong><strong>dfree command (G)</strong></strong>
 <p><br>The dfree command setting should only be used on systems where a
@@ -1209,7 +1336,8 @@ bits are added).
 <p><br>See the <a href="smb.conf.5.html#forcedirectorymode"><strong>"force directory mode"</strong></a> parameter
 to cause particular mode bits to always be set on created directories.
 <p><br>See also the <a href="smb.conf.5.html#createmode"><strong>"create mode"</strong></a> parameter for masking
-mode bits on created files.
+mode bits on created files, and the <a href="smb.conf.5.html#directorysecuritymask"><strong>"directory security mask"</strong></a>
+parameter.
 <p><br><strong>Default:</strong>
 <code> directory mask = 0755</code>
 <p><br><strong>Example:</strong>
@@ -1217,6 +1345,31 @@ mode bits on created files.
 <p><br><a name="directorymode"></a>
 <li><strong><strong>directory mode (S)</strong></strong>
 <p><br>Synonym for <a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a>.
+<p><br><a name="directorysecuritymask"></a>
+<li><strong><strong>directory security mask (S)</strong></strong>
+<p><br>This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+directory using the native NT security dialog box.
+<p><br>This parameter is applied as a mask (AND'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change.
+<p><br>If not set explicitly this parameter is set to the same value as the
+<a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a> parameter. To allow a user to
+modify all the user/group/world permissions on a directory, set this
+parameter to 0777.
+<p><br><em>Note</em> that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0777.
+<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
+mode</strong></a>, <a href="smb.conf.5.html#securitymask"><strong>security
+mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security mode</strong></a>
+parameters.
+<p><br><strong>Default:</strong>
+<code> directory security mask = &lt;same as directory mask&gt;</code>
+<p><br><strong>Example:</strong>
+<code> directory security mask = 0777</code>
 <p><br><a name="dnsproxy"></a>
 <li><strong><strong>dns proxy (G)</strong></strong>
 <p><br>Specifies that <a href="nmbd.8.html"><strong>nmbd</strong></a> when acting as a WINS
@@ -1235,7 +1388,7 @@ DNS name lookup requests, as doing a name lookup is a blocking action.
 <p><br><a name="domainadmingroup"></a>
 <strong>domain admin group (G)</strong>
 <p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code.  It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1243,7 +1396,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
 <p><br><a name="domainadminusers"></a> 
 <li><strong><strong>domain admin users (G)</strong></strong>
 <p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1253,70 +1406,10 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
 <p><br>This is a <strong>DEPRECATED</strong> parameter. It is currently not used within
 the Samba source and should be removed from all current smb.conf
 files. It is left behind for compatibility reasons.
-<p><br><a name="domaingroupmap"></a>
-<li><strong><strong>domain group map (G)</strong></strong>
-<p><br>This option allows you to specify a file containing unique mappings
-of individual NT Domain Group names (in any domain) to UNIX group
-names.  This allows NT domain groups to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-<p><br>This option is used in conjunction with <a href="smb.conf.5.html#localgroupmap"><strong>'local group map'</strong></a>
-and <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>.  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-<p><br>The map file is parsed line by line.  If any line begins with a <code>'#'</code>
-or a <code>';'</code> then it is ignored.  Each line should contain a single UNIX
-group name on the left then a single NT Domain Group name on the right,
-separated by a tabstop or <code>'='</code>.  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-<p><br><code>  UNIXgroupname   \\DOMAIN_NAME\\DomainGroupName </code>
-<p><br>or:
-<p><br><code>  UNIXgroupname   DomainGroupName </code>
-<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
-or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
-<p><br>Any UNIX groups that are <em>NOT</em> specified in this map file are assumed to
-be either Local or Domain Groups, depending on the role of the Samba Server.
-<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
-will present <em>ALL</em> such unspecified UNIX groups as its own NT Domain
-Groups, with the same name.
-<p><br>In the case where Samba is member of a domain using
-<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
-its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
-as if it was an NT Domain Group.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
-a local Workstation.
-<p><br>This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you <strong>want</strong> to get fancy, however, you can.
-<p><br>Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group <em>REQUIRES</em> the following:
-<p><br><ul>
-<p><br><li > that the UNIX group exists on the UNIX server.
-<p><br><li > that the NT Domain Group exists in the specified NT Domain
-<p><br><li > that the UNIX Server knows about the specified Domain; 
-<p><br><li > that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>.
-<p><br></ul>
-<p><br>Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
 <p><br><a name="domaingroups"></a>
 <li><strong><strong>domain groups (G)</strong></strong>
 <p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1324,7 +1417,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
 <p><br><a name="domainguestgroup"></a>
 <li><strong><strong>domain guest group (G)</strong></strong>
 <p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1332,7 +1425,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
 <p><br><a name="domainguestusers"></a>
 <li><strong><strong>domain guest users (G)</strong></strong>
 <p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1372,72 +1465,8 @@ if this parameter is set and <a href="nmbd.8.html"><strong>nmbd</strong></a> cla
 special name for a <a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a> before a Windows NT
 PDC is able to do so then cross subnet browsing will behave strangely
 and may fail.
-<p><br>By default ("auto") Samba will attempt to become the domain master
-browser only if it is the Primary Domain Controller.
 <p><br><strong>Default:</strong>
-<code> domain master = auto</code>
-<p><br><strong>Example:</strong>
 <code> domain master = no</code>
-<p><br><a name="domainusermap"></a>
-<li><strong><strong>domain user map (G)</strong></strong>
-<p><br>This option allows you to specify a file containing unique mappings
-of individual NT Domain User names (in any domain) to UNIX user
-names.  This allows NT domain users to be presented correctly to
-NT systems, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-<p><br>This option is used in conjunction with <a href="smb.conf.5.html#localgroupmap"><strong>'local group map'</strong></a>
-and <a href="smb.conf.5.html#domaingroupmap"><strong>'domain group map'</strong></a>.  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-<p><br>This option, which provides (and maintains) a one-to-one link between
-UNIX and NT users, is <em>DIFFERENT</em> from <a href="smb.conf.5.html#usernamemap"><strong>'username map'</strong></a>, which does <em>NOT</em> maintain a distinction between the
-name(s) it can map to and the name it maps.
-<p><br>The map file is parsed line by line.  If any line begins with a <code>'#'</code>
-or a <code>';'</code> then the line is ignored.  Each line should contain a single UNIX
-user name on the left then a single NT Domain User name on the right,
-separated by a tabstop or <code>'='</code>.  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-<p><br><code>  UNIXusername    \\DOMAIN_NAME\\DomainUserName </code>
-<p><br>or:
-<p><br><code>  UNIXusername    DomainUserName </code>
-<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
-or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
-<p><br>Any UNIX users that are <em>NOT</em> specified in this map file are assumed
-to be either Domain or Workstation Users, depending on the role of the
-Samba Server.
-<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
-will present <em>ALL</em> such unspecified UNIX users as its own NT Domain
-Users, with the same name.
-<p><br>In the case where Samba is a member of a domain using
-<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
-its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
-as if it was an NT Domain User.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX users which also are not NT Domain
-Users are treated as Local Users in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Users,
-which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
-a local Workstation.
-<p><br>This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you <strong>want</strong> to get fancy, however, you can.
-<p><br>Note that adding an entry to map an arbitrary NT User in an arbitrary
-Domain to an arbitrary UNIX user <em>REQUIRES</em> the following:
-<p><br><ul>
-<p><br><li > that the UNIX user exists on the UNIX server.
-<p><br><li > that the NT Domain User exists in the specified NT Domain.
-<p><br><li > that the UNIX Server knows about the specified Domain.
-<p><br></ul>
-<p><br>Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
 <p><br><a name="dontdescend"></a>
 <li><strong><strong>dont descend (S)</strong></strong>
 <p><br>There are certain directories on some systems (e.g., the <code>/proc</code> tree
@@ -1599,6 +1628,31 @@ details on masking mode bits on created directories.
 <p><br>would force all created directories to have read and execute
 permissions set for 'group' and 'other' as well as the
 read/write/execute bits set for the 'user'.
+<p><br><a name="forcedirectorysecuritymode"></a>
+<li><strong><strong>force directory security mode (S)</strong></strong>
+<p><br>This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a directory
+using the native NT security dialog box.
+<p><br>This parameter is applied as a mask (OR'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a directory,
+the user has always set to be 'on'.
+<p><br>If not set explicitly this parameter is set to the same value as the
+<a href="smb.conf.5.html#forcedirectorymode"><strong>force directory mode</strong></a> parameter. To allow
+a user to modify all the user/group/world permissions on a directory,
+with restrictions set this parameter to 000.
+<p><br><em>Note</em> that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0000.
+<p><br>See also the <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security mask</strong></a>,
+<a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security
+mode</strong></a> parameters.
+<p><br><strong>Default:</strong>
+<code> force directory security mode = &lt;same as force directory mode&gt;</code>
+<p><br><strong>Example:</strong>
+<code> force directory security mode = 0</code>
 <p><br><a name="forcegroup"></a>
 <li><strong><strong>force group (S)</strong></strong>
 <p><br>This specifies a UNIX group name that will be assigned as the default
@@ -1608,10 +1662,51 @@ use the named group for their permissions checking. Thus, by assigning
 permissions for this group to the files and directories within this
 service the Samba administrator can restrict or allow sharing of these
 files.
+<p><br>In Samba 2.0.5 and above this parameter has extended functionality in the following
+way. If the group name listed here has a '+' character prepended to it
+then the current user accessing the share only has the primary group 
+default assigned to this group if they are already assigned as a member
+of that group. This allows an administrator to decide that only users
+who are already in a particular group will create files with group 
+ownership set to that group. This gives a finer granularity of ownership
+assignment. For example, the setting <code>force group = +sys</code> means
+that only users who are already in group sys will have their default
+primary group assigned to sys when accessing this Samba share. All
+other users will retain their ordinary primary group.
+<p><br>If the <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a> parameter is also set the
+group specified in <strong>force group</strong> will override the primary group
+set in <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a>.
+<p><br>See also <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a>
 <p><br><strong>Default:</strong>
 <code> no forced group</code>
 <p><br><strong>Example:</strong>
 <code> force group = agroup</code>
+<p><br><a name="forcesecuritymode"></a>
+<li><strong><strong>force security mode (S)</strong></strong>
+<p><br>This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a file
+using the native NT security dialog box.
+<p><br>This parameter is applied as a mask (OR'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a file, the
+user has always set to be 'on'.
+<p><br>If not set explicitly this parameter is set to the same value as the
+<a href="smb.conf.5.html#forcecreatemode"><strong>force create mode</strong></a> parameter. To allow
+a user to modify all the user/group/world permissions on a file,
+with no restrictions set this parameter to 000.
+<p><br><em>Note</em> that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0000.
+<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
+mode</strong></a>, <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security
+mask</strong></a>, <a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>
+parameters.
+<p><br><strong>Default:</strong>
+<code> force security mode = &lt;same as force create mode&gt;</code>
+<p><br><strong>Example:</strong>
+<code> force security mode = 0</code>
 <p><br><a name="forceuser"></a>
 <li><strong><strong>force user (S)</strong></strong>
 <p><br>This specifies a UNIX user name that will be assigned as the default
@@ -1623,6 +1718,11 @@ clients still need to connect as a valid user and supply a valid
 password. Once connected, all file operations will be performed as the
 <code>"forced user"</code>, no matter what username the client connected as.
 <p><br>This can be very useful.
+<p><br>In Samba 2.0.5 and above this parameter also causes the primary
+group of the forced user to be used as the primary group for all
+file activity. Prior to 2.0.5 the primary group was left as the
+primary group of the connecting user (this was a bug).
+<p><br>See also <a href="smb.conf.5.html#forcegroup"><strong>"force group"</strong></a>
 <p><br><strong>Default:</strong>
 <code> no forced user</code>
 <p><br><strong>Example:</strong>
@@ -1728,7 +1828,7 @@ files"</strong></a> and <a href="smb.conf.5.html#casesensitive"><strong>"case se
 <p><br><strong>Example</strong>
 <code> hide files = /.*/DesktopFolderDB/TrashFor%m/resource.frk/</code>
 <p><br>The above example is based on files that the Macintosh SMB client
-(DAVE) available from <a href="www.thursby.com"><strong>Thursby</strong></a> creates for
+(DAVE) available from <a href="http://www.thursby.com"><strong>Thursby</strong></a> creates for
 internal use, and also still hides all files beginning with a dot.
 <p><br><a name="homedirmap"></a>
 <li><strong><strong>homedir map (G)</strong></strong>
@@ -1751,16 +1851,57 @@ logons</strong></a>.
 <code> homedir map = amd.homedir</code>
 <p><br><a name="hostsallow"></a>
 <li><strong><strong>hosts allow (S)</strong></strong>
-<p><br>Synonym for <a href="smb.conf.5.html#allowhosts"><strong>allow hosts</strong></a>.
+<p><br>A synonym for this parameter is <a href="smb.conf.5.html#allowhosts"><strong>'allow hosts'</strong></a>
+<p><br>This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service.
+<p><br>If specified in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section then it will
+apply to all services, regardless of whether the individual service
+has a different setting.
+<p><br>You can specify the hosts by name or IP number. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like <code>"allow hosts = 150.203.5."</code>. The full syntax of the list is
+described in the man page <strong>hosts_access (5)</strong>. Note that this man
+page may not be present on your system, so a brief description will
+be given here also.
+<p><br>Note that the localhost address 127.0.0.1 will always be allowed
+access unless specifically denied by a "hosts deny" option.
+<p><br>You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups. The <em>EXCEPT</em> keyword can also
+be used to limit a wildcard list. The following examples may provide
+some help:
+<p><br><strong>Example 1</strong>: allow all IPs in 150.203.*.* except one
+<p><br><code>  hosts allow = 150.203. EXCEPT 150.203.6.66</code>
+<p><br><strong>Example 2</strong>: allow hosts that match the given network/netmask
+<p><br><code>  hosts allow = 150.203.15.0/255.255.255.0</code>
+<p><br><strong>Example 3</strong>: allow a couple of hosts
+<p><br><code>  hosts allow = lapland, arvidsjaur</code>
+<p><br><strong>Example 4</strong>: allow only hosts in NIS netgroup "foonet", but 
+deny access from one particular host
+<p><br><code>  hosts allow = @foonet</code>
+<p><br><code>  hosts deny = pirate</code>
+<p><br>Note that access still requires suitable user-level passwords.
+<p><br>See <a href="testparm.1.html"><strong>testparm (1)</strong></a> for a way of testing your
+host access to see if it does what you expect.
+<p><br><strong>Default:</strong>
+<code> none (i.e., all hosts permitted access)</code>
+<p><br><strong>Example:</strong>
+<code> allow hosts = 150.203.5. myhost.mynet.edu.au</code>
 <p><br><a name="hostsdeny"></a>
 <li><strong><strong>hosts deny (S)</strong></strong>
-<p><br>Synonym for <a href="smb.conf.5.html#denyhosts"><strong>denyhosts</strong></a>.
+<p><br>The opposite of <a href="smb.conf.5.html#hostsallow"><strong>'hosts allow'</strong></a> - hosts listed
+here are <em>NOT</em> permitted access to services unless the specific
+services have their own lists to override this one. Where the lists
+conflict, the <a href="smb.conf.5.html#hostsallow"><strong>'allow'</strong></a> list takes precedence.
+<p><br><strong>Default:</strong>
+<code> none (i.e., no hosts specifically excluded)</code>
+<p><br><strong>Example:</strong>
+<code> hosts deny = 150.203.4. badhost.mynet.edu.au</code>
 <p><br><a name="hostsequiv"></a>
 <li><strong><strong>hosts equiv (G)</strong></strong>
 <p><br>If this global parameter is a non-null string, it specifies the name
 of a file to read for the names of hosts and users who will be allowed
 access without specifying a password.
-<p><br>This is not be confused with <a href="smb.conf.5.html#allowhosts"><strong>allow hosts</strong></a> which
+<p><br>This is not be confused with <a href="smb.conf.5.html#hostsallow"><strong>hosts allow</strong></a> which
 is about hosts access to services and is more useful for guest
 services. <strong>hosts equiv</strong> may be useful for NT clients which will not
 supply passwords to samba.
@@ -1782,20 +1923,32 @@ is included literally, as though typed in place.
 <a href="smb.conf.5.html#percentP"><strong>%P</strong></a> and <a href="smb.conf.5.html#percentS"><strong>%S</strong></a>.
 <p><br><a name="interfaces"></a>
 <li><strong><strong>interfaces (G)</strong></strong>
-<p><br>This option allows you to setup multiple network interfaces, so that
-Samba can properly handle browsing on all interfaces.
-<p><br>The option takes a list of ip/netmask pairs. The netmask may either be
-a bitmask, or a bitlength.
+<p><br>This option allows you to override the default network interfaces list
+that Samba will use for browsing, name registration and other NBT
+traffic. By default Samba will query the kernel for the list of all
+active interfaces and use any interfaces except 127.0.0.1 that are
+broadcast capable.
+<p><br>The option takes a list of interface strings. Each string can be in
+any of the following forms:
+<p><br><ul>
+<li > a network interface name (such as eth0). This may include
+     shell-like wildcards so eth* will match any interface starting
+     with the substring "eth"
+if() a IP address. In this case the netmask is determined
+     from the list of interfaces obtained from the kernel
+if() a IP/mask pair. 
+if() a broadcast/mask pair. 
+</ul>
+<p><br>The "mask" parameters can either be a bit length (such as 24 for a C
+class network) or a full netmask in dotted decmal form.
+<p><br>The "IP" parameters above can either be a full dotted decimal IP
+address or a hostname which will be looked up via the OSes normal
+hostname resolution mechanisms.
 <p><br>For example, the following line:
-<p><br><code>interfaces = 192.168.2.10/24 192.168.3.10/24</code>
-<p><br>would configure two network interfaces with IP addresses 192.168.2.10
-and 192.168.3.10. The netmasks of both interfaces would be set to
-255.255.255.0.
-<p><br>You could produce an equivalent result by using:
-<p><br><code>interfaces = 192.168.2.10/255.255.255.0 192.168.3.10/255.255.255.0</code>
-<p><br>if you prefer that format.
-<p><br>If this option is not set then Samba will attempt to find a primary
-interface, but won't attempt to configure more than one interface.
+<p><br><code>interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0</code>
+<p><br>would configure three network interfaces corresponding to the eth0
+device and IP addresses 192.168.2.10 and 192.168.3.10. The netmasks of
+the latter two interfaces would be set to 255.255.255.0.
 <p><br>See also <a href="smb.conf.5.html#bindinterfacesonly"><strong>"bind interfaces only"</strong></a>.
 <p><br><a name="invalidusers"></a>
 <li><strong><strong>invalid users (S)</strong></strong>
@@ -1833,9 +1986,9 @@ has the SO_KEEPALIVE attribute set on it (see <a href="smb.conf.5.html#socketopt
 options"</strong></a>). Basically you should only use this option
 if you strike difficulties.
 <p><br><strong>Default:</strong>
-<code> keep alive = 0</code>
+<code> keepalive = 0</code>
 <p><br><strong>Example:</strong>
-<code> keep alive = 60</code>
+<code> keepalive = 60</code>
 <p><br><a name="kerneloplocks"></a>
 <li><strong><strong>kernel oplocks (G)</strong></strong>
 <p><br>For UNIXs that support kernel based <a href="smb.conf.5.html#oplocks"><strong>oplocks</strong></a>
@@ -1849,42 +2002,57 @@ data consistency between SMB/CIFS, NFS and local file access (and is a
 <p><br>This parameter defaults to <em>"On"</em> on systems that have the support,
 and <em>"off"</em> on systems that don't. You should never need to touch
 this parameter.
-<p><br><a name="ldapbindas"></a>
-<li><strong><strong>ldap bind as (G)</strong></strong>
-<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the <strong>--with-ldap</strong>
-option.
-<p><br>This parameter specifies the entity to bind to an LDAP directory as.
-Usually it should be safe to use the LDAP root account; for larger
-installations it may be preferable to restrict Samba's access. See also
-<a href="smb.conf.5.html#ldappasswdfile"><strong>ldap passwd file</strong></a>.
-<p><br><strong>Default:</strong>
-<code> none (bind anonymously)</code>
-<p><br><strong>Example:</strong>
-<code> ldap bind as = "uid=root, dc=mydomain, dc=org"</code>
-<p><br><a name="ldappasswdfile"></a>
-<li><strong><strong>ldap passwd file (G)</strong></strong>
+<p><br>See also the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> and <a href="smb.conf.5.html#level2oplocks"><strong>"level2 oplocks"</strong></a>
+parameters.
+<p><br><a name="ldapfilter"></a>
+<li><strong><strong>ldap filter (G)</strong></strong>
 <p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the <strong>--with-ldap</strong>
-option.
-<p><br>This parameter specifies a file containing the password with which
-Samba should bind to an LDAP server. For obvious security reasons
-this file must be set to mode 700 or less.
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the <strong>--with-ldap</strong> option.
+<p><br>This parameter specifies an LDAP search filter used to search for a
+user name in the LDAP database. It must contain the string
+<a href="smb.conf.5.html#percentU"><strong>%u</strong></a> which will be replaced with the user being
+searched for.
 <p><br><strong>Default:</strong>
-<code> none (bind anonymously)</code>
-<p><br><strong>Example:</strong>
-<code> ldap passwd file = /usr/local/samba/private/ldappasswd</code>
+<code> empty string.</code>
 <p><br><a name="ldapport"></a>
 <li><strong><strong>ldap port (G)</strong></strong>
 <p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the <strong>--with-ldap</strong>
-option.
-<p><br>This parameter specifies the TCP port number of the LDAP server.
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the <strong>--with-ldap</strong> option.
+<p><br>This parameter specifies the TCP port number to use to contact
+the LDAP server on.
 <p><br><strong>Default:</strong>
 <code> ldap port = 389.</code>
+<p><br><a name="ldaproot"></a>
+<li><strong><strong>ldap root (G)</strong></strong>
+<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the <strong>--with-ldap</strong> option.
+<p><br>This parameter specifies the entity to bind to the LDAP server
+as (essentially the LDAP username) in order to be able to perform
+queries and modifications on the LDAP database.
+<p><br>See also <a href="smb.conf.5.html#ldaprootpasswd"><strong>ldap root passwd</strong></a>.
+<p><br><strong>Default:</strong>
+<code> empty string (no user defined)</code>
+<p><br><a name="ldaprootpasswd"></a>
+<li><strong><strong>ldap root passwd (G)</strong></strong>
+<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the <strong>--with-ldap</strong> option.
+<p><br>This parameter specifies the password for the entity to bind to the
+LDAP server as (the password for this LDAP username) in order to be
+able to perform queries and modifications on the LDAP database.
+<p><br><em>BUGS:</em> This parameter should <em>NOT</em> be a readable parameter
+in the <strong>smb.conf</strong> file and will be removed once a correct
+storage place is found.
+<p><br>See also <a href="smb.conf.5.html#ldaproot"><strong>ldap root</strong></a>.
+<p><br><strong>Default:</strong>
+<code> empty string.</code>
 <p><br><a name="ldapserver"></a>
 <li><strong><strong>ldap server (G)</strong></strong>
 <p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
@@ -1892,8 +2060,7 @@ password database stored on an LDAP server back-end. These options
 are only available if your version of Samba was configured with
 the <strong>--with-ldap</strong> option.
 <p><br>This parameter specifies the DNS name of the LDAP server to use
-when storing and retrieving information about Samba users and
-groups.
+for SMB/CIFS authentication purposes.
 <p><br><strong>Default:</strong>
 <code> ldap server = localhost</code>
 <p><br><a name="ldapsuffix"></a>
@@ -1902,13 +2069,42 @@ groups.
 password database stored on an LDAP server back-end. These options
 are only available if your version of Samba was configured with
 the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies the node of the LDAP tree beneath which
-Samba should store its information. This parameter MUST be provided
-when using LDAP with Samba.
-<p><br><strong>Default:</strong>
-<code> none</code>
-<p><br><strong>Example:</strong>
-<code> ldap suffix = "dc=mydomain, dc=org"</code>
+<p><br>This parameter specifies the <code>"dn"</code> or LDAP <em>"distinguished name"</em>
+that tells <a href="smbd.8.html"><strong>smbd</strong></a> to start from when searching
+for an entry in the LDAP password database.
+<p><br><strong>Default:</strong>
+<code> empty string.</code>
+<p><br><a name="level2oplocks"></a>
+<li><strong><strong>level2 oplocks (S)</strong></strong>
+<p><br>This parameter (new in Samba 2.0.5) controls whether Samba supports
+level2 (read-only) oplocks on a share. In Samba 2.0.4 this parameter
+defaults to "False" as the code is new, but will default to "True"
+in a later release.
+<p><br>Level2, or read-only oplocks allow Windows NT clients that have an
+oplock on a file to downgrade from a read-write oplock to a read-only
+oplock once a second client opens the file (instead of releasing all
+oplocks on a second open, as in traditional, exclusive oplocks). This
+allows all openers of the file that support level2 oplocks to cache
+the file for read-ahead only (ie. they may not cache writes or lock
+requests) and increases performance for many acesses of files that
+are not commonly written (such as application .EXE files).
+<p><br>Once one of the clients which have a read-only oplock writes to
+the file all clients are notified (no reply is needed or waited
+for) and told to break their oplocks to "none" and delete any
+read-ahead caches.
+<p><br>It is recommended that this parameter be turned on to speed access
+to shared executables (and also to test the code :-).
+<p><br>For more discussions on level2 oplocks see the CIFS spec.
+<p><br>Currently, if <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> are supported
+then level2 oplocks are not granted (even if this parameter is set
+to <code>"true"</code>). Note also, the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> parameter must
+be set to "true" on this share in order for this parameter to have any
+effect.
+<p><br>See also the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> and <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> parameters.
+<p><br><strong>Default:</strong>
+<code> level2 oplocks = False</code>
+<p><br><strong>Example:</strong>
+<code> level2 oplocks = True</code>
 <p><br><a name="lmannounce"></a>
 <li><strong><strong>lm announce (G)</strong></strong>
 <p><br>This parameter determines if <a href="nmbd.8.html"><strong>nmbd</strong></a> will produce
@@ -1949,66 +2145,6 @@ will be loaded for browsing by default. See the
 <code> load printers = yes</code>
 <p><br><strong>Example:</strong>
 <code> load printers = no</code>
-<p><br><a name="localgroupmap"></a>
-<li><strong><strong>local group map (G)</strong></strong>
-<p><br>This option allows you to specify a file containing unique mappings
-of individual NT Local Group names (in any domain) to UNIX group
-names.  This allows NT Local groups (aliases) to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-<p><br>This option is used in conjunction with <a href="smb.conf.5.html#domaingroupmap"><strong>'domain group map'</strong></a>
-and <a href="smb.conf.5.html#domainusermap"><strong>'domain name map'</strong></a>.  The use of these three
-options is trivial and often unnecessary in the case where Samba
-is not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-<p><br>The map file is parsed line by line.  If any line begins with a <code>'#'</code>
-or a <code>';'</code> then it is ignored.  Each line should contain a single UNIX
-group name on the left then a single NT Local Group name on the right,
-separated by a tabstop or <code>'='</code>.  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-<p><br><code>  UNIXgroupname   \\DOMAIN_NAME\\LocalGroupName </code>
-<p><br>or:
-<p><br><code>  UNIXgroupname   LocalGroupName </code>
-<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
-or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
-<p><br>Any UNIX groups that are <em>NOT</em> specified in this map file are treated
-as either Local or Domain Groups depending on the role of the Samba Server.
-<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
-will present <em>ALL</em> unspecified UNIX groups as its own NT Domain
-Groups, with the same name, and <em>NOT</em> as Local Groups.
-<p><br>In the case where Samba is member of a domain using
-<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
-its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
-as if it was an NT Domain Group.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
-a local Workstation.
-<p><br>This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you <strong>want</strong> to get fancy, however, you can.
-<p><br>Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group <em>REQUIRES</em> the following:
-<p><br><ul>
-<p><br><li > that the UNIX group exists on the UNIX server.
-<p><br><li > that the NT Domain Group exists in the specified NT Domain
-<p><br><li > that the UNIX Server knows about the specified Domain; 
-<p><br><li > that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>.
-<p><br></ul>
-<p><br>Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
 <p><br><a name="localmaster"></a>
 <li><strong><strong>local master (G)</strong></strong>
 <p><br>This option allows <a href="nmbd.8.html"><strong>nmbd</strong></a> to try and become a
@@ -2308,6 +2444,11 @@ end.
 <p><br><a name="manglecase"></a>
 <li><strong><strong>mangle case (S)</strong></strong>
 <p><br>See the section on <a href="smb.conf.5.html#NAMEMANGLING"><strong>"NAME MANGLING"</strong></a>.
+<p><br><a name="manglelocks"></a>
+<li><strong><strong>mangle locks (S)</strong></strong>
+<p><br>This option is was introduced with Samba 2.0.4 and above and has been
+removed in Samba 2.0.6 as Samba now dynamically configures such things
+on 32 bit systems.
 <p><br><a name="mangledmap"></a>
 <li><strong><strong>mangled map (S)</strong></strong>
 <p><br>This is for those who want to directly map UNIX file names which can
@@ -2529,7 +2670,7 @@ never need to set this parameter.
 <p><br><strong>Default:</strong>
 <code> max mux = 50</code>
 <p><br><a name="maxopenfiles"></a>
-<li><strong><strong>maxopenfiles (G)</strong></strong>
+<li><strong><strong>max open files (G)</strong></strong>
 <p><br>This parameter limits the maximum number of open files that one
 <a href="smbd.8.html"><strong>smbd</strong></a> file serving process may have open for
 a client at any one time. The default for this parameter is set
@@ -2620,6 +2761,15 @@ job.
 <code> min print space = 0</code>
 <p><br><strong>Example:</strong>
 <code> min print space = 2000</code>
+<p><br><a name="minpasswdlength"></a>
+<li><strong><strong>min passwd length (G)</strong></strong>
+<p><br>This option sets the minimum length in characters of a plaintext password
+than smbd will accept when performing UNIX password changing.
+<p><br>See also <a href="smb.conf.5.html#unixpasswordsync"><strong>"unix password sync"</strong></a>,
+<a href="smb.conf.5.html#passwdprogram"><strong>"passwd program"</strong></a> and <a href="smb.conf.5.html#passwdchatdebug"><strong>"passwd chat
+debug"</strong></a>.
+<p><br><strong>Default:</strong>
+<code> min passwd length = 5</code>
 <p><br><a name="minwinsttl"></a>
 <li><strong><strong>min wins ttl (G)</strong></strong>
 <p><br>This option tells <a href="nmbd.8.html"><strong>nmbd</strong></a> when acting as a WINS
@@ -2639,10 +2789,15 @@ resolution options.
 names to be resolved as follows :
 <p><br><ul>
 <p><br><li > <strong>lmhosts</strong> : Lookup an IP address in the Samba lmhosts file.
+If the line in lmhosts has no name type attached to the NetBIOS
+name (see the <a href="lmhosts.5.html"><strong>lmhosts (5)</strong></a> for details) then
+any name type matches for lookup.
 <p><br><li > <strong>host</strong> : Do a standard host name to IP address resolution,
 using the system /etc/hosts, NIS, or DNS lookups. This method of name
 resolution is operating system depended for instance on IRIX or
 Solaris this may be controlled by the <em>/etc/nsswitch.conf</em> file).
+Note that this method is only used if the NetBIOS name type being
+queried is the 0x20 (server) name type, otherwise it is ignored.
 <p><br><li > <strong>wins</strong> : Query a name with the IP address listed in the
 <a href="smb.conf.5.html#winsserver"><strong>wins server</strong></a> parameter. If no WINS server has
 been specified this method will be ignored.
@@ -2709,6 +2864,14 @@ system and the Samba server with this option must also be a
 <code> nis homedir = false</code>
 <p><br><strong>Example:</strong>
 <code> nis homedir = true</code>
+<p><br><a name="ntaclsupport"></a>
+<li><strong><strong>nt acl support (G)</strong></strong>
+<p><br>This boolean parameter controls whether <a href="smbd.8.html"><strong>smbd</strong></a>
+will attempt to map UNIX permissions into Windows NT access control lists.
+<p><br><strong>Default:</strong>
+<code> nt acl support = yes</code>
+<p><br><strong>Example:</strong>
+<code> nt acl support = no</code>
 <p><br><a name="ntpipesupport"></a>
 <li><strong><strong>nt pipe support (G)</strong></strong>
 <p><br>This boolean parameter controls whether <a href="smbd.8.html"><strong>smbd</strong></a>
@@ -2787,21 +2950,47 @@ by the underlying operating system. This allows data synchronization between
 all access to oplocked files, whether it be via Samba or NFS or a local
 UNIX process. See the <a href="smb.conf.5.html#kerneloplocks"><strong>kernel oplocks</strong></a> parameter
 for details.
+<p><br>See also the <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> and
+<a href="smb.conf.5.html#level2oplocks"><strong>"level2 oplocks"</strong></a> parameters.
 <p><br><strong>Default:</strong>
 <code> oplocks = True</code>
 <p><br><strong>Example:</strong>
 <code> oplocks = False</code>
+<p><br><a name="oplockbreakwaittime"></a>
+<li><strong><strong>oplock break wait time (G)</strong></strong>
+<p><br>This is a tuning parameter added due to bugs in both Windows 9x and WinNT.
+If Samba responds to a client too quickly when that client issues an SMB that
+can cause an oplock break request, then the client redirector can fail and
+not respond to the break request. This tuning parameter (which is set in
+milliseconds) is the amount of time Samba will wait before sending an
+oplock break request to such (broken) clients.
+<p><br><em>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE</em>.
+<p><br><strong>Default:</strong>
+<code> oplock break wait time = 10</code>
+<p><br><a name="oplockcontentionlimit"></a>
+<li><strong><strong>oplock contention limit (S)</strong></strong>
+<p><br>This is a <em>very</em> advanced <a href="smbd.8.html"><strong>smbd</strong></a> tuning option to improve
+the efficiency of the granting of oplocks under multiple client contention for the same file.
+<p><br>In brief it specifies a number, which causes smbd not to grant an oplock even
+when requested if the approximate number of clients contending for an oplock on
+the same file goes over this limit. This causes <a href="smbd.8.html"><strong>smbd</strong></a> to
+behave in a similar way to Windows NT.
+<p><br><em>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE</em>.
+<p><br><strong>Default:</strong>
+<code> oplock contention limit = 2</code>
 <p><br><a name="oslevel"></a>
 <li><strong><strong>os level (G)</strong></strong>
 <p><br>This integer value controls what level Samba advertises itself as for
 browse elections. The value of this parameter determines whether
 <a href="nmbd.8.html"><strong>nmbd</strong></a> has a chance of becoming a local master
 browser for the <a href="smb.conf.5.html#workgroup"><strong>WORKGROUP</strong></a> in the local broadcast
-area. Setting this to zero will cause <a href="nmbd.8.html"><strong>nmbd</strong></a> to
-always lose elections to Windows machines. See BROWSING.txt in the
-Samba docs/ directory for details.
+area. The default is zero, which means <a href="nmbd.8.html"><strong>nmbd</strong></a> will
+lose elections to Windows machines. See BROWSING.txt in the Samba
+docs/ directory for details.
 <p><br><strong>Default:</strong>
-<code> os level = 32</code>
+<code> os level = 20</code>
 <p><br><strong>Example:</strong>
 <code> os level = 65    ; This will win against any NT Server</code>
 <p><br><a name="packetsize"></a>
@@ -2958,13 +3147,18 @@ better restrict them with hosts allow!
 <p><br>If the <a href="smb.conf.5.html#security"><strong>"security"</strong></a> parameter is set to
 <strong>"domain"</strong>, then the list of machines in this option must be a list
 of Primary or Backup Domain controllers for the
-<a href="smb.conf.5.html#workgroup"><strong>Domain</strong></a>, as the Samba server is cryptographicly
+<a href="smb.conf.5.html#workgroup"><strong>Domain</strong></a> or the character <code>*</code>, as the Samba server is cryptographicly
 in that domain, and will use cryptographicly authenticated RPC calls
 to authenticate the user logging on. The advantage of using
 <a href="smb.conf.5.html#securityequaldomain"><strong>"security=domain"</strong></a> is that if you list
 several hosts in the <strong>"password server"</strong> option then
 <a href="smbd.8.html"><strong>smbd</strong></a> will try each in turn till it finds one
 that responds. This is useful in case your primary server goes down.
+<p><br>If the <strong>"password server"</strong> option is set to the character <code>*</code>,
+then Samba will attempt to auto-locate the Primary or Backup Domain controllers
+to authenticate against by doing a query for the name <code>WORKGROUP&lt;1C&gt;</code>
+and then contacting each server returned in the list of IP addresses
+from the <a href="smb.conf.5.html#nameresolveorder"><strong>name resolution</strong></a> source.
 <p><br>If the <a href="smb.conf.5.html#security"><strong>"security"</strong></a> parameter is set to
 <a href="smb.conf.5.html#securityequalserver"><strong>"server"</strong></a>, then there are different
 restrictions that <a href="smb.conf.5.html#securityequaldomain"><strong>"security=domain"</strong></a>
@@ -2989,6 +3183,8 @@ workstation.
 <code> password server = &lt;empty string&gt;</code>
 <p><br><strong>Example:</strong>
 <code> password server = NT-PDC, NT-BDC1, NT-BDC2</code>
+<p><br><strong>Example:</strong>
+<code> password server = *</code>
 <p><br><a name="path"></a>
 <li><strong><strong>path (S)</strong></strong>
 <p><br>This parameter specifies a directory to which the user of the service
@@ -3047,11 +3243,19 @@ time they log in. Maybe a message of the day? Here is an example:
 </pre>
 
 <p><br>Of course, this could get annoying after a while :-)
-<p><br>See also <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>.
+<p><br>See also <a href="smb.conf.5.html#preexecclose"><strong>preexec close</strong></a> and <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>.
 <p><br><strong>Default:</strong>
 <code> none (no command executed)</code>
 <p><br><strong>Example:</strong>
 <code>        preexec = echo \"%u connected to %S from %m (%I)\" &gt;&gt; /tmp/log</code>
+<p><br><a name="preexecclose"></a>
+<li><strong><strong>preexec close (S)</strong></strong>
+<p><br>This boolean option controls whether a non-zero return code from
+<a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a> should close the service being connected to.
+<p><br><strong>Default:</strong>
+<code>         preexec close = no</code>
+<p><br><strong>Example:</strong>
+<code>         preexec close = yes</code>
 <p><br><a name="preferredmaster"></a>
 <li><strong><strong>preferred master (G)</strong></strong>
 <p><br>This boolean parameter controls if <a href="nmbd.8.html"><strong>nmbd</strong></a> is a
@@ -3061,8 +3265,7 @@ force an election, and it will have a slight advantage in winning the
 election.  It is recommended that this parameter is used in
 conjunction with <a href="smb.conf.5.html#domainmaster"><strong>"domain master = yes"</strong></a>, so
 that <a href="nmbd.8.html"><strong>nmbd</strong></a> can guarantee becoming a domain
-master. Indeed the default ("auto") enables "preferred master" if
-Samba is configured as the domain master browser.
+master.
 <p><br>Use this option with caution, because if there are several hosts
 (whether Samba servers, Windows 95 or NT) that are preferred master
 browsers on the same subnet, they will each periodically and
@@ -3071,7 +3274,7 @@ result in unnecessary broadcast traffic and reduced browsing
 capabilities.
 <p><br>See also <a href="smb.conf.5.html#oslevel"><strong>os level</strong></a>.
 <p><br><strong>Default:</strong>
-<code>         preferred master = auto</code>
+<code>         preferred master = no</code>
 <p><br><strong>Example:</strong>
 <code>         preferred master = yes</code>
 <p><br><a name="preferedmaster"></a>
@@ -3239,7 +3442,7 @@ in the docs/ directory, PRINTER_DRIVER.txt.
 find the printer driver files for the automatic installation of
 drivers for Windows 95 machines. If Samba is set up to serve printer
 drivers to Windows 95 machines, this should be set to
-<p><br><code>\\MACHINE\PRINTER$</code>
+<p><br><code>\\MACHINE\aPRINTER$</code>
 <p><br>Where MACHINE is the NetBIOS name of your Samba server, and PRINTER$
 is a share you set up for serving printer driver files. For more
 details on setting this up see the documentation file in the docs/
@@ -3391,13 +3594,13 @@ all the data has been read from disk.
 <p><br>This overlapping works best when the speeds of disk and network access
 are similar, having very little effect when the speed of one is much
 greater than the other.
-<p><br>The default value is 2048, but very little experimentation has been
+<p><br>The default value is 16384, but very little experimentation has been
 done yet to determine the optimal value, and it is likely that the
 best value will vary greatly between systems anyway. A value over
 65536 is pointless and will cause you to allocate memory
 unnecessarily.
 <p><br><strong>Default:</strong>
-<code> read size = 2048</code>
+<code> read size = 16384</code>
 <p><br><strong>Example:</strong>
 <code> read size = 8192</code>
 <p><br><a name="remoteannounce"></a>
@@ -3450,6 +3653,32 @@ master on it's segment.
 <code> remote browse sync = &lt;empty string&gt;</code>
 <p><br><strong>Example:</strong>
 <code> remote browse sync = 192.168.2.255 192.168.4.255</code>
+<p><br><a name="restrictanonymous"></a>
+<li><strong><strong>restrict anonymous (G)</strong></strong>
+<p><br>This is a boolean parameter.  If it is true, then anonymous access
+to the server will be restricted, namely in the case where the server
+is expecting the client to send a username, but it doesn't.  Setting
+it to true will force these anonymous connections to be denied, and
+the client will be required to always supply a username and password
+when connecting. Use of this parameter is only recommened for homogenous 
+NT client environments.
+<p><br>This parameter makes the use of macro expansions that rely
+on the username (%U, %G, etc) consistant.  NT 4.0 likes to use
+anonymous connections when refreshing the share list, and this
+is a way to work around that.
+<p><br>When restrict anonymous is true, all anonymous connections are denied
+no matter what they are for.  This can effect the ability of a machine
+to access the samba Primary Domain Controller to revalidate it's machine
+account after someone else has logged on the client interactively.  The
+NT client will display a message saying that the machine's account in 
+the domain doesn't exist or the password is bad.  The best way to deal 
+with this is to reboot NT client machines between interactive logons, 
+using "Shutdown and Restart", rather than "Close all programs and logon 
+as a different user".
+<p><br><strong>Default:</strong>
+<code>     restrict anonymous = false</code>
+<p><br><strong>Example:</strong>
+<code>     restrict anonymous = true</code>
 <p><br><a name="revalidate"></a>
 <li><strong><strong>revalidate (S)</strong></strong>
 <p><br>Note that this option only works with
@@ -3506,7 +3735,13 @@ filesystems (such as cdroms) after a connection is closed.
 <p><br>This is the same as the <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a> parameter except
 that the command is run as root. This is useful for mounting
 filesystems (such as cdroms) before a connection is finalized.
-<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>.
+<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>
+and <a href="smb.conf.5.html#rootpreexecclose"><strong>"root preexec close"</strong></a>.
+<p><br><a name="rootpreexecclose"></a>
+<li><strong><strong>root preexec close (S)</strong></strong>
+<p><br>This is the same as the <a href="smb.conf.5.html#preexecclose"><strong>"preexec close"</strong></a> parameter
+except that the command is run as root.
+<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>, <a href="smb.conf.5.html#preexecclose"><strong>"preexec close"</strong></a>.
 <p><br><a name="security"></a>
 <li><strong><strong>security (G)</strong></strong>
 <p><br>This option affects how clients respond to Samba and is one of the most
@@ -3662,7 +3897,7 @@ level security without allowing the server to automatically map unknown
 users into the <a href="smb.conf.5.html#guestaccount"><strong>"guest account"</strong></a>. See the
 <a href="smb.conf.5.html#maptoguest"><strong>"map to guest"</strong></a> parameter for details on
 doing this.
-<p><br>e,(BUG:) There is currently a bug in the implementation of
+<p><br><em>BUG:</em> There is currently a bug in the implementation of
 <strong>"security=domain</strong> with respect to multi-byte character
 set usernames. The communication with a Domain Controller
 must be done in UNICODE and Samba currently does not widen
@@ -3678,6 +3913,31 @@ and the <a href="smb.conf.5.html#encryptpasswords"><strong>"encrypted passwords"
 <code>         security = USER</code>
 <p><br><strong>Example:</strong>
 <code>         security = DOMAIN</code>
+<p><br><a name="securitymask"></a>
+<li><strong><strong>security mask (S)</strong></strong>
+<p><br>This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+file using the native NT security dialog box.
+<p><br>This parameter is applied as a mask (AND'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change.
+<p><br>If not set explicitly this parameter is set to the same value as the
+<a href="smb.conf.5.html#createmask"><strong>create mask</strong></a> parameter. To allow a user to
+modify all the user/group/world permissions on a file, set this
+parameter to 0777.
+<p><br><em>Note</em> that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0777.
+<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
+mode</strong></a>, <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security
+mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security
+mode</strong></a> parameters.
+<p><br><strong>Default:</strong>
+<code> security mask = &lt;same as create mask&gt;</code>
+<p><br><strong>Example:</strong>
+<code> security mask = 0777</code>
 <p><br><a name="serverstring"></a>
 <li><strong><strong>server string (G)</strong></strong>
 <p><br>This controls what string will show up in the printer comment box in
@@ -3726,12 +3986,14 @@ increase this parameter. Signs that this parameter is set too low are
 users reporting strange problems trying to save files (locking errors)
 and error messages in the smbd log looking like <code>"ERROR
 smb_shm_alloc : alloc of XX bytes failed"</code>.
+<p><br>If your OS refuses the size that Samba asks for then Samba will try a
+smaller size, reducing by a factor of 0.8 until the OS accepts it.
 <p><br><strong>Default:</strong>
 <code> shared mem size = 1048576</code>
 <p><br><strong>Example:</strong>
 <code> shared mem size = 5242880 ; Set to 5mb for a large number of files.</code>
 <p><br><a name="shortpreservecase"></a>
-<li><strong><strong>short preserve case (S)</strong></strong>
+<li><strong><strong>short preserve case (G)</strong></strong>
 <p><br>This boolean parameter controls if new files which conform to 8.3
 syntax, that is all in upper case and of suitable length, are created
 upper case, or if they are forced to be the <code>"default"</code> case. This
@@ -4100,9 +4362,11 @@ set to <code>"yes"</code> in order for this parameter to have any affect.
 <p><br>This parameter maps how Samba debug messages are logged onto the
 system syslog logging levels. Samba debug level zero maps onto syslog
 LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-to LOG_NOTICE, debug level three maps onto LOG_INFO.  The parameter
-sets the threshold for doing the mapping, all Samba debug messages
-above this threshold are mapped to syslog LOG_DEBUG messages.
+onto LOG_NOTICE, debug level three maps onto LOG_INFO. All higher 
+levels are mapped to LOG_DEBUG.
+<p><br>This paramter sets the threshold for sending messages to syslog. 
+Only messages with debug level less than this value will be sent 
+to syslog.
 <p><br><strong>Default:</strong>
 <code> syslog = 1</code>
 <p><br><a name="syslogonly"></a>
@@ -4283,15 +4547,6 @@ purposes. The most common is to map usernames that users use on DOS or
 Windows machines to those that the UNIX box uses. The other is to map
 multiple users to a single username so that they can more easily share
 files.
-<p><br>The use of this option, therefore, relates to UNIX usernames
-and not Windows (specifically NT Domain) usernames.  In other words,
-once a name has been mapped using this option, the Samba server uses
-the mapped name for internal <em>AND</em> external purposes.
-<p><br>This option is <em>DIFFERENT</em> from the <a href="smb.conf.5.html#domainusermap"><strong>"domain user map"</strong></a> 
-parameter, which maintains a one-to-one mapping between UNIX usernames
-and NT Domain Usernames: more specifically, the Samba server maintains
-a link between <em>BOTH</em> usernames, presenting the NT username to the
-external NT world, and using the UNIX username internally.
 <p><br>The map file is parsed line by line. Each line should contain a single
 UNIX username on the left then a <code>'='</code> followed by a list of
 usernames on the right. The list of usernames on the right may contain
@@ -4493,6 +4748,9 @@ may be followed by the server. Links that point to areas within the
 directory tree exported by the server are always allowed; this
 parameter controls access only to areas that are outside the directory
 tree being exported.
+<p><br>Note that setting this parameter can have a negative effect on your
+server performance due to the extra system calls that Samba has to
+do in order to perform the link checks.
 <p><br><strong>Default:</strong>
 <code>         wide links = yes</code>
 <p><br><strong>Example:</strong>
@@ -4509,7 +4767,7 @@ need to set this to <code>"yes"</code> for some older clients.
 <p><br>This specifies the IP address (or DNS name: IP address for preference)
 of the WINS server that <a href="nmbd.8.html"><strong>nmbd</strong></a> should register with.
 If you have a WINS server on your network then you should set this to
-the WINS server's IP.
+the WINS server's IP.        
 <p><br>You should point this at your WINS server if you have a
 multi-subnetted network.
 <p><br><em>NOTE</em>. You need to set up Samba to point to a WINS server if you
@@ -4520,6 +4778,32 @@ Samba source distribution.
 <code> wins server = </code>
 <p><br><strong>Example:</strong>
 <code> wins server = 192.9.200.1</code>
+<p><br><a name="winshook"></a>
+<li><strong><strong>wins hook (G)</strong></strong>
+<p><br>When Samba is running as a WINS server this allows you to call an
+external program for all changes to the WINS database. The primary use
+for this option is to allow the dynamic update of external name
+resolution databases such as dynamic DNS.
+<p><br>The wins hook parameter specifies the name of a script or executable
+that will be called as follows:
+<p><br>wins_hook operation name nametype ttl IP_list
+<p><br>The first argument is the operation and is one of "add", "delete",
+or "refresh". In most cases the operation can be ignored as the rest
+of the parameters provide sufficient information. Note that "refresh"
+may sometimes be called when the name has not previously been added,
+in that case it should be treated as an add.
+<p><br>The second argument is the netbios name. If the name is not a legal
+name then the wins hook is not called. Legal names contain only
+letters, digits, hyphens, underscores and periods.
+<p><br>The third argument is the netbios name type as a 2 digit hexadecimal
+number. 
+<p><br>The fourth argument is the TTL (time to live) for the name in seconds.
+<p><br>The fifth and subsequent arguments are the IP addresses currently
+registered for that name. If this list is empty then the name should
+be deleted.
+<p><br>An example script that calls the BIND dynamic DNS update program
+"nsupdate" is provided in the examples directory of the Samba source
+code. 
 <p><br><a name="winssupport"></a>
 <li><strong><strong>wins support (G)</strong></strong>
 <p><br>This boolean controls if the <a href="nmbd.8.html"><strong>nmbd</strong></a> process in
@@ -4543,7 +4827,6 @@ setting.
 <p><br><a name="writable"></a>
 <li><strong><strong>writable (S)</strong></strong>
 <p><br>Synonym for <a href="smb.conf.5.html#writeable"><strong>"writeable"</strong></a> for people who can't spell :-).
-Pronounced "ritter-bull".
 <p><br><a name="writelist"></a>
 <li><strong><strong>write list (S)</strong></strong>
 <p><br>This is a list of users that are given read-write access to a
@@ -4587,6 +4870,7 @@ permitting), but only via spooling operations.
 
 </pre>
 
+<p><br></ul>
 <p><br><a name="WARNINGS"></a>
 <h2>WARNINGS</h2>
     
index 45823a56f9c1063d948a070a2001278d68838880..a68538aa155673787edbe8b9809565b3b60cd421 100644 (file)
@@ -24,7 +24,7 @@
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
     
-<p><br><strong>smbclient</strong> <a href="smbclient.1.html#servicename">servicename</a> [<a href="smbclient.1.html#password">password</a>] [<a href="smbclient.1.html#minuss">-s smb.conf</a>] [<a href="smbclient.1.html#minusB">-B IP addr</a>] [<a href="smbclient.1.html#minusO">-O socket options</a>][<a href="smbclient.1.html#minusR">-R name resolve order</a>] [<a href="smbclient.1.html#minusM">-M NetBIOS name</a>] [<a href="smbclient.1.html#minusi">-i scope</a>] [<a href="smbclient.1.html#minusN">-N</a>] [<a href="smbclient.1.html#minusn">-n NetBIOS name</a>] [<a href="smbclient.1.html#minusd">-d debuglevel</a>] [<a href="smbclient.1.html#minusP">-P</a>] [<a href="smbclient.1.html#minusp">-p port</a>] [<a href="smbclient.1.html#minusl">-l log basename</a>] [<a href="smbclient.1.html#minush">-h</a>] [<a href="smbclient.1.html#minusI">-I dest IP</a>] [<a href="smbclient.1.html#minusE">-E</a>] [<a href="smbclient.1.html#minusU">-U username</a>] [<a href="smbclient.1.html#minusL">-L NetBIOS name</a>] [<a href="smbclient.1.html#minust">-t terminal code</a>] [<a href="smbclient.1.html#minusm">-m max protocol</a>] [<a href="smbclient.1.html#minusW">-W workgroup</a>] [<a href="smbclient.1.html#minusT">-T&lt;c|x&gt;IXFqgbNan</a>] [<a href="smbclient.1.html#minusD">-D directory</a>] [<a href="smbclient.1.html#minusc">-c command string</a>]
+<p><br><strong>smbclient</strong> <a href="smbclient.1.html#servicename">servicename</a> [<a href="smbclient.1.html#minuss">-s smb.conf</a>] [<a href="smbclient.1.html#minusO">-O socket options</a>][<a href="smbclient.1.html#minusR">-R name resolve order</a>] [<a href="smbclient.1.html#minusM">-M NetBIOS name</a>] [<a href="smbclient.1.html#minusi">-i scope</a>] [<a href="smbclient.1.html#minusN">-N</a>] [<a href="smbclient.1.html#minusn">-n NetBIOS name</a>] [<a href="smbclient.1.html#minusd">-d debuglevel</a>] [<a href="smbclient.1.html#minusP">-P</a>] [<a href="smbclient.1.html#minusp">-p port</a>] [<a href="smbclient.1.html#minusl">-l log basename</a>] [<a href="smbclient.1.html#minush">-h</a>] [<a href="smbclient.1.html#minusI">-I dest IP</a>] [<a href="smbclient.1.html#minusE">-E</a>] [<a href="smbclient.1.html#minusU">-U username</a>] [<a href="smbclient.1.html#minusL">-L NetBIOS name</a>] [<a href="smbclient.1.html#minust">-t terminal code</a>] [<a href="smbclient.1.html#minusm">-m max protocol</a>] [<a href="smbclient.1.html#minusb">-b buffersize</a>] [<a href="smbclient.1.html#minusW">-W workgroup</a>] [<a href="smbclient.1.html#minusT">-T&lt;c|x&gt;IXFqgbNan</a>] [<a href="smbclient.1.html#minusD">-D directory</a>] [<a href="smbclient.1.html#minusc">-c command string</a>]
 <p><br><a name="DESCRIPTION"></a>
 <h2>DESCRIPTION</h2>
     
@@ -74,8 +74,6 @@ rejected by these servers.
 Samba configuration file, smb.conf. This file controls all aspects of
 the Samba setup on the machine and smbclient also needs to read this
 file.
-<p><br><a name="minusB"></a>
-<li><strong><strong>-B IP addr</strong></strong> The IP address to use when sending a broadcast packet.
 <p><br><a name="minusO"></a>
 <li><strong><strong>-O socket options</strong></strong> TCP socket options to set on the client
 socket. See the <a href="smb.conf.5.html#socketoptions">socket options</a>
@@ -102,8 +100,7 @@ no WINS server has been specified this method will be ignored.
 listed in the <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a> parameter
 in the smb.conf file. This is the least reliable of the name resolution
 methods as it depends on the target host being on a locally connected
-subnet. To specify a particular broadcast address the <a href="smbclient.1.html#minusB"><strong>-B</strong></a> option 
-may be used.
+subnet. 
 <p><br></ul>
 <p><br>If this parameter is not set then the name resolve order defined
 in the <a href="smb.conf.5.html"><strong>smb.conf</strong></a> file parameter 
@@ -238,7 +235,7 @@ then the password as part of username will take precedence. Putting
 nothing before or nothing after the percent symbol will cause an empty
 username or an empty password to be used, respectively.
 <p><br>The password may also be specified by setting up an environment
-variable called <code>PASSWORD</code> that contains the users password. Note
+variable called <code>PASSWD</code> that contains the users password. Note
 that this may be very insecure on some systems but on others allows
 users to script smbclient commands without having a password appear in
 the command line of a process listing.
@@ -246,7 +243,7 @@ the command line of a process listing.
 on an uppercase password. Lowercase or mixed case passwords may be
 rejected by these servers.
 <p><br>Be cautious about including passwords in scripts or in the
-<code>PASSWORD</code> environment variable. Also, on many systems the command
+<code>PASSWD</code> environment variable. Also, on many systems the command
 line of a running process may be seen via the <code>ps</code> command to be
 safe always allow smbclient to prompt for a password and type it in
 directly.
@@ -273,6 +270,11 @@ Samba source code for the complete list.
 protocols level the server supports. This parameter is
 preserved for backwards compatibility, but any string
 following the <strong>-m</strong> will be ignored.
+<p><br><a name="minusb"></a>
+<li><strong><strong>-b buffersize</strong></strong> This option changes the transmit/send buffer
+size when getting or putting a file from/to the server. The default
+is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
+observed to speed up file transfers to and from a Win9x server.
 <p><br><a name="minusW"></a>
 <li><strong><strong>-W WORKGROUP</strong></strong> Override the default workgroup specified in the
 <a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a> parameter of the
@@ -535,7 +537,7 @@ LANMAN2 protocol or above.
 <p><br>The variable <strong>USER</strong> may contain the username of the person using the
 client.  This information is used only if the protocol level is high
 enough to support session-level passwords.
-<p><br>The variable <strong>PASSWORD</strong> may contain the password of the person using
+<p><br>The variable <strong>PASSWD</strong> may contain the password of the person using
 the client.  This information is used only if the protocol level is
 high enough to support session-level passwords.
 <p><br><a name="INSTALLATION"></a>
index 790c40639402bb3f9bb4a62b6abb39034a613996..8230d50f47b239cbe2862e023c5d7d4a8bb2315d 100644 (file)
@@ -24,7 +24,7 @@
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
     
-<p><br><strong>smbd</strong> [<a href="smbd.8.html#minusD">-D</a>] [<a href="smbd.8.html#minusa">-a</a>] [<a href="smbd.8.html#minuso">-o</a>] [<a href="smbd.8.html#minusd">-d debuglevel</a>] [<a href="smbd.8.html#minusl">-l log file</a>] [<a href="smbd.8.html#minusp">-p port number</a>] [<a href="smbd.8.html#minusO">-O socket options</a>] [<a href="smbd.8.html#minuss">-s configuration file</a>] [<a href="smbd.8.html#minusi">-i scope</a>] [<a href="smbd.8.html#minusP">-P</a>] [<a href="smbd.8.html#minush">-h</a>]
+<p><br><strong>smbd</strong> [<a href="smbd.8.html#minusD">-D</a>] [<a href="smbd.8.html#minusa">-a</a>] [<a href="smbd.8.html#minuso">-o</a>] [<a href="smbd.8.html#minusP">-P</a>] [<a href="smbd.8.html#minush">-h</a>] [<a href="smbd.8.html#minusV">-V</a>] [<a href="smbd.8.html#minusd">-d debuglevel</a>] [<a href="smbd.8.html#minusl">-l log file</a>] [<a href="smbd.8.html#minusp">-p port number</a>] [<a href="smbd.8.html#minusO">-O socket options</a>] [<a href="smbd.8.html#minuss">-s configuration file</a>] [<a href="smbd.8.html#minusi">-i scope</a>]
 <p><br><a name="DESCRIPTION"></a>
 <h2>DESCRIPTION</h2>
     
@@ -75,6 +75,13 @@ append log messages to the log file.  This is the default.
 <li><strong><strong>-o</strong></strong> If this parameter is specified, the log files will be
 overwritten when opened.  By default, the log files will be appended
 to.
+<p><br><a name="minusP"></a>
+<li><strong><strong>-P</strong></strong> Passive option. Causes smbd not to send any network traffic
+out. Used for debugging by the developers only.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>smbd</strong>.
+<p><br><a name="minusV"></a>
+<li><strong><strong>-V</strong></strong> Prints the version number for <strong>smbd</strong>.
 <p><br><a name="minusd"></a>
 <li><strong><strong>-d debuglevel</strong></strong> debuglevel is an integer from 0 to 10.
 <p><br>The default value if this parameter is not specified is zero.
@@ -133,11 +140,6 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
 are <em>very</em> rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
-<p><br><a name="minush"></a>
-<li><strong><strong>-h</strong></strong> Prints the help information (usage) for smbd.
-<p><br><a name="minusP"></a>
-<li><strong><strong>-P</strong></strong> Passive option. Causes smbd not to send any network traffic
-out. Used for debugging by the developers only.
 <p><br></ul>
 <p><br><a name="FILES"></a>
 <h2>FILES</h2>
@@ -357,16 +359,11 @@ performance.
 <p><br><a name="SEEALSO"></a>
 <h2>SEE ALSO</h2>
     
-<p><br><strong>hosts_access (5)</strong>,
-<strong>inetd (8)</strong>,
-<a href="nmbd.8.html"><strong>nmbd (8)</strong></a>,
-<a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a>,
-<a href="smbclient.1.html"><strong>smbclient (1)</strong></a>,
-<a href="testparm.1.html"><strong>testparm (1)</strong></a>,
-<a href="testprns.1.html"><strong>testprns (1)</strong></a>,
-<a href="rpcclient.1.html"><strong>rpcclient (1)</strong></a>,
-and the Internet RFC's <strong>rfc1001.txt</strong>, <strong>rfc1002.txt</strong>.
-In addition the CIFS (formerly SMB)
+<p><br><strong>hosts_access (5)</strong>, <strong>inetd (8)</strong>, <a href="nmbd.8.html"><strong>nmbd (8)</strong></a>,
+<a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a>, <a href="smbclient.1.html"><strong>smbclient
+(1)</strong></a>, <a href="testparm.1.html"><strong>testparm (1)</strong></a>,
+<a href="testprns.1.html"><strong>testprns (1)</strong></a>, and the Internet RFC's
+<strong>rfc1001.txt</strong>, <strong>rfc1002.txt</strong>. In addition the CIFS (formerly SMB)
 specification is available as a link from the Web page :
 <a href="http://samba.org/cifs/">http://samba.org/cifs/</a>.
 <p><br><a name="AUTHOR"></a>
index 4a854a5c4d9259f69f1d7d92ad535dae4f7f671f..1cc65e81587d116058d64a47b4e23b8c5de31ab5 100644 (file)
@@ -36,7 +36,7 @@ connections.
     
 <p><br><ul>
 <p><br><a name="minusP"></a>
-<li><strong><strong>-P</strong></strong> If samba has been compiled with the profiling option, 
+<li><strong><strong>-P</strong></strong> If samba has been compiled with the profiling option,
 print only the contents of the profiling shared memory area.
 <p><br><a name="minusb"></a>
 <li><strong><strong>-b</strong></strong> gives brief output.
index 0d43dd494bf2514db632ae1abfe67494fe2bf959..3a29f17ab5e6dd4dd05e3da542080eb9490fa9a7 100644 (file)
@@ -20,7 +20,7 @@
     
 <p><br><a name="NAME"></a>
 <h2>NAME</h2>
-    swat - swat - Samba Web Administration Tool
+    swat - Samba Web Administration Tool
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
     
index 00db2316266aded52fe42c7cf6e8b0f91c4a2ffc..1e0396af33788518ee79a39aa902b860c157a8af 100644 (file)
@@ -24,7 +24,7 @@
 <p><br><a name="SYNOPSIS"></a>
 <h2>SYNOPSIS</h2>
      
-<p><br><strong>testparm</strong> [<a href="testparm.1.html#minuss">-s</a>] [<a href="testparm.1.html#configfilename">configfilename</a>] [<a href="testparm.1.html#hostname">hostname</a> <a href="testparm.1.html#hostIP">hostIP</a>]
+<p><br><strong>testparm</strong> [<a href="testparm.1.html#minuss">-s</a>] [<a href="testparm.1.html#minush">-h</a>] [<a href="testparm.1.html#minusL">-L servername</a>] [<a href="testparm.1.html#configfilename">configfilename</a>] [<a href="testparm.1.html#hostname">hostname</a> <a href="testparm.1.html#hostIP">hostIP</a>]
 <p><br><a name="DESCRIPTION"></a>
 <h2>DESCRIPTION</h2>
     
@@ -39,6 +39,10 @@ configuration file will be available or will operate as expected.
 <p><br>If the optional host name and host IP address are specified on the
 command line, this test program will run through the service entries
 reporting whether the specified host has access to each service.
+<p><br>If <strong>testparm</strong> finds an error in the <a href="smb.conf.5.html"><strong>smb.conf</strong></a>
+file it returns an exit code of 1 to the calling program, else it returns
+an exit code of 0. This allows shell scripts to test the output from
+<strong>testparm</strong>.
 <p><br><a name="OPTIONS"></a>
 <h2>OPTIONS</h2>
     
@@ -47,6 +51,11 @@ reporting whether the specified host has access to each service.
 <li><strong><strong>-s</strong></strong> Without this option, <strong>testparm</strong> will prompt for a
 carriage return after printing the service names and before dumping
 the service definitions.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Print usage message
+<p><br><a name="minusL"></a>
+<li><strong><strong>-L servername</strong></strong> Sets the value of the %L macro to servername. This
+is useful for testing include files specified with the %L macro.
 <p><br><a name="configfilename"></a>
 <li><strong><strong>configfilename</strong></strong> This is the name of the configuration file to
 check. If this parameter is not present then the default
index 2c880faa427e21ec32d1e4bdaab3e58f60395e31..72aeaf14a77aa8bf55a08b212e5f28bc0f5a9172 100644 (file)
@@ -6,7 +6,7 @@ naming services to clients
 .PP 
 .SH "SYNOPSIS" 
 .PP 
-\fBnmbd\fP [-D] [-o] [-a] [-H lmhosts file] [-d debuglevel] [-l log file basename] [-n primary NetBIOS name] [-p port number] [-s configuration file] [-i NetBIOS scope] [-h]
+\fBnmbd\fP [-D] [-a] [-o] [-h] [-V] [-H lmhosts file] [-d debuglevel] [-l log file basename] [-n primary NetBIOS name] [-p port number] [-s configuration file] [-i NetBIOS scope]
 .PP 
 .SH "DESCRIPTION" 
 .PP 
@@ -59,6 +59,12 @@ If this parameter is specified, the log files will be
 overwritten when opened\&.  By default, the log files will be appended
 to\&.
 .IP 
+.IP "\fB-h\fP" 
+Prints the help information (usage) for \fBnmbd\fP\&.
+.IP 
+.IP "\fB-V\fP" 
+Prints the version number for \fBnmbd\fP\&.
+.IP 
 .IP "\fB-H filename\fP" 
 NetBIOS lmhosts file\&.
 .IP 
@@ -138,9 +144,6 @@ are \fIvery\fP rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with\&.
 .IP 
-.IP "\fB-h\fP" 
-Prints the help information (usage) for \fBnmbd\fP\&.
-.IP 
 .PP 
 .SH "FILES" 
 .PP 
index 04f24d0ef537c6500a0ce3a8846cd489de6b23b7..a542e6d50740015ba021d35d1df6295ea997f87a 100644 (file)
@@ -5,7 +5,7 @@ nmblookup \- NetBIOS over TCP/IP client used to lookup NetBIOS names
 .PP 
 .SH "SYNOPSIS" 
 .PP 
-\fBnmblookup\fP [-M] [-R] [-S] [-r] [-A] [-h] [-B broadcast address] [-U unicast address] [-d debuglevel] [-s smb config file] [-i NetBIOS scope] name
+\fBnmblookup\fP [-M] [-R] [-S] [-r] [-A] [-h] [-B broadcast address] [-U unicast address] [-d debuglevel] [-s smb config file] [-i NetBIOS scope] [-T] name
 .PP 
 .SH "DESCRIPTION" 
 .PP 
@@ -20,8 +20,9 @@ or to a particular machine\&. All queries are done over UDP\&.
 .PP 
 .IP 
 .IP "\fB-M\fP" 
-Searches for a master browser\&. This is done by doing a
-broadcast lookup on the special name \f(CW__MSBROWSE__\fP\&.
+Searches for a master browser by looking up the 
+NetBIOS name \fBname\fP with a type of 0x1d\&. If \fBname\fP
+is \f(CW"-"\fP then it does a lookup on the special name \f(CW__MSBROWSE__\fP\&.
 .IP 
 .IP "\fB-R\fP" 
 Set the recursion desired bit in the packet to do a
@@ -55,8 +56,8 @@ Print a help (usage) message\&.
 .IP "\fB-B broadcast address\fP" 
 Send the query to the given broadcast
 address\&. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the primary network
-interface as either auto-detected or defined in the 
+send the query to the broadcast address of the network
+interfaces as either auto-detected or defined in the 
 \fBinterfaces\fP parameter of the 
 \fBsmb\&.conf (5)\fP file\&.
 .IP 
@@ -97,6 +98,12 @@ are \fIvery\fP rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with\&.
 .IP 
+.IP "\fB-T\fP" 
+This causes any IP addresses found in the lookup to be
+looked up via a reverse DNS lookup into a DNS name, and printed out
+before each \f(CW"IP address   NetBIOS name"\fP pair that is the normal
+output\&.
+.IP 
 .IP "\fBname\fP" 
 This is the NetBIOS name being queried\&. Depending upon
 the previous options this may be a NetBIOS name or IP address\&. If a
index 03ab0863407127a343a93ceb7b7ba7a0f7876bfb..96975f34c261d2f34ab892d4797156a6a188cda9 100644 (file)
@@ -50,18 +50,6 @@ servers (such as Windows NT), and can also be used to allow a UNIX box
 to print to a printer attached to any SMB server (such as a PC running
 Windows NT)\&.
 .IP 
-.IP "\fBrpcclient\fP" 
-.br 
-.br 
-The \fBrpcclient\fP
-(1) program is a client that can \'talk\' to an
-SMB/CIFS MSRPC server\&.  Operations include things like managing a SAM
-Database (users, groups and aliases) in the same way as the Windows NT
-programs \fBUser Manager for Domains\fP and \fBServer Manager for Domains\fP;
-managing a remote registry in the same way as the Windows NT programs
-\fBREGEDT32\&.EXE\fP and \fBREGEDIT\&.EXE\fP; viewing a remote event log (same
-as \fBEVENTVWR\&.EXE\fP)\&.
-.IP 
 .IP "\fBtestparm\fP" 
 .br 
 .br 
index a3a58e38996268c7268e395600476bc9ec9059d3..da873317697180e8f3636364b61d0ac9e962968e 100644 (file)
@@ -242,6 +242,7 @@ would look like this:
 
        [printers]
                path = /usr/spool/public
+               writeable = no
                guest ok = yes
                printable = yes 
 
@@ -490,6 +491,12 @@ parameter for details\&.  Note that some are synonyms\&.
 .PP 
 .IP 
 .IP o 
+\fBadd user script\fP
+.IP 
+.IP o 
+\fBallow trusted domains\fP
+.IP 
+.IP o 
 \fBannounce as\fP
 .IP 
 .IP o 
@@ -523,9 +530,18 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBdeadtime\fP
 .IP 
 .IP o 
+\fBdebug hires timestamp\fP
+.IP 
+.IP o 
+\fBdebug pid\fP
+.IP 
+.IP o 
 \fBdebug timestamp\fP
 .IP 
 .IP o 
+\fBdebug uid\fP
+.IP 
+.IP o 
 \fBdebuglevel\fP
 .IP 
 .IP o 
@@ -535,6 +551,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBdefault service\fP
 .IP 
 .IP o 
+\fBdelete user script\fP
+.IP 
+.IP o 
 \fBdfree command\fP
 .IP 
 .IP o 
@@ -550,9 +569,6 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBdomain controller\fP
 .IP 
 .IP o 
-\fBdomain group map\fP
-.IP 
-.IP o 
 \fBdomain groups\fP
 .IP 
 .IP o 
@@ -568,9 +584,6 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBdomain master\fP
 .IP 
 .IP o 
-\fBdomain user map\fP
-.IP 
-.IP o 
 \fBencrypt passwords\fP
 .IP 
 .IP o 
@@ -592,13 +605,16 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBkernel oplocks\fP
 .IP 
 .IP o 
-\fBldap bind as\fP
+\fBldap filter\fP
 .IP 
 .IP o 
-\fBldap passwd file\fP
+\fBldap port\fP
 .IP 
 .IP o 
-\fBldap port\fP
+\fBldap root\fP
+.IP 
+.IP o 
+\fBldap root passwd\fP
 .IP 
 .IP o 
 \fBldap server\fP
@@ -616,9 +632,6 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBload printers\fP
 .IP 
 .IP o 
-\fBlocal group map\fP
-.IP 
-.IP o 
 \fBlocal master\fP
 .IP 
 .IP o 
@@ -655,6 +668,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBmangled stack\fP
 .IP 
 .IP o 
+\fBmap to guest\fP
+.IP 
+.IP o 
 \fBmax disk size\fP
 .IP 
 .IP o 
@@ -682,6 +698,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBmessage command\fP
 .IP 
 .IP o 
+\fBmin passwd length\fP
+.IP 
+.IP o 
 \fBmin wins ttl\fP
 .IP 
 .IP o 
@@ -697,6 +716,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBnis homedir\fP
 .IP 
 .IP o 
+\fBnt acl support\fP
+.IP 
+.IP o 
 \fBnt pipe support\fP
 .IP 
 .IP o 
@@ -709,6 +731,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBole locking compatibility\fP
 .IP 
 .IP o 
+\fBoplock break wait time\fP
+.IP 
+.IP o 
 \fBos level\fP
 .IP 
 .IP o 
@@ -772,6 +797,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBremote browse sync\fP
 .IP 
 .IP o 
+\fBrestrict anonymous\fP
+.IP 
+.IP o 
 \fBroot\fP
 .IP 
 .IP o 
@@ -895,6 +923,9 @@ parameter for details\&.  Note that some are synonyms\&.
 \fBwins server\fP
 .IP 
 .IP o 
+\fBwins hook\fP
+.IP 
+.IP o 
 \fBwins support\fP
 .IP 
 .IP o 
@@ -971,6 +1002,9 @@ parameter for details\&. Note that some are synonyms\&.
 \fBdirectory mode\fP
 .IP 
 .IP o 
+\fBdirectory security mask\fP
+.IP 
+.IP o 
 \fBdont descend\fP
 .IP 
 .IP o 
@@ -998,9 +1032,15 @@ parameter for details\&. Note that some are synonyms\&.
 \fBforce directory mode\fP
 .IP 
 .IP o 
+\fBforce directory security mode\fP
+.IP 
+.IP o 
 \fBforce group\fP
 .IP 
 .IP o 
+\fBforce security mode\fP
+.IP 
+.IP o 
 \fBforce user\fP
 .IP 
 .IP o 
@@ -1037,6 +1077,9 @@ parameter for details\&. Note that some are synonyms\&.
 \fBinvalid users\fP
 .IP 
 .IP o 
+\fBlevel2 oplocks\fP
+.IP 
+.IP o 
 \fBlocking\fP
 .IP 
 .IP o 
@@ -1061,6 +1104,9 @@ parameter for details\&. Note that some are synonyms\&.
 \fBmangle case\fP
 .IP 
 .IP o 
+\fBmangle locks\fP
+.IP 
+.IP o 
 \fBmangled map\fP
 .IP 
 .IP o 
@@ -1079,9 +1125,6 @@ parameter for details\&. Note that some are synonyms\&.
 \fBmap system\fP
 .IP 
 .IP o 
-\fBmap to guest\fP
-.IP 
-.IP o 
 \fBmax connections\fP
 .IP 
 .IP o 
@@ -1097,6 +1140,9 @@ parameter for details\&. Note that some are synonyms\&.
 \fBoplocks\fP
 .IP 
 .IP o 
+\fBoplock contention limit\fP
+.IP 
+.IP o 
 \fBpath\fP
 .IP 
 .IP o 
@@ -1109,6 +1155,9 @@ parameter for details\&. Note that some are synonyms\&.
 \fBpreexec\fP
 .IP 
 .IP o 
+\fBpreexec close\fP
+.IP 
+.IP o 
 \fBpreserve case\fP
 .IP 
 .IP o 
@@ -1160,6 +1209,12 @@ parameter for details\&. Note that some are synonyms\&.
 \fBroot preexec\fP
 .IP 
 .IP o 
+\fBsecurity mask\fP
+.IP 
+.IP o 
+\fBroot preexec close\fP
+.IP 
+.IP o 
 \fBset directory\fP
 .IP 
 .IP o 
@@ -1220,6 +1275,54 @@ parameter for details\&. Note that some are synonyms\&.
 .SH "EXPLANATION OF EACH PARAMETER" 
 .PP 
 .IP 
+.IP "\fBadd user script (G)\fP" 
+.IP 
+This is the full pathname to a script that will be run \fIAS ROOT\fP by
+\fBsmbd (8)\fP under special circumstances decribed
+below\&.
+.IP 
+Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server\&. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task\&. This option allows \fBsmbd\fP to create
+the required UNIX users \fION DEMAND\fP when a user accesses the Samba
+server\&.
+.IP 
+In order to use this option, \fBsmbd\fP must be set to
+\fBsecurity=server\fP or
+\fBsecurity=domain\fP and \fB"add user script"\fP
+must be set to a full pathname for a script that will create a UNIX user
+given one argument of \fB%u\fP, which expands into the UNIX user name to
+create\&.
+.IP 
+When the Windows user attempts to access the Samba server, at
+\fI"login"\fP(session setup in the SMB protocol) time,
+\fBsmbd\fP contacts the \fBpassword
+server\fP and attempts to authenticate the given user
+with the given password\&. If the authentication succeeds then
+\fBsmbd\fP attempts to find a UNIX user in the UNIX
+password database to map the Windows user into\&. If this lookup fails,
+and \fB"add user script"\fP is set then \fBsmbd\fP will
+call the specified script \fIAS ROOT\fP, expanding any \fB%u\fP argument
+to be the user name to create\&.
+.IP 
+If this script successfully creates the user then
+\fBsmbd\fP will continue on as though the UNIX user
+already existed\&. In this way, UNIX users are dynamically created to
+match existing Windows NT accounts\&.
+.IP 
+See also \fBsecurity=server\fP,
+\fBsecurity=domain\fP, \fBpassword
+server\fP, \fBdelete user
+script\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW  add user script = <empty string>\fP
+.IP 
+\fBExample:\fP
+\f(CW  add user script = /usr/local/samba/bin/add_user %u\fP
+.IP 
 .IP "\fBadmin users (S)\fP" 
 .IP 
 This is a list of users who will be granted administrative privileges
@@ -1240,63 +1343,29 @@ file permissions\&.
 .IP 
 .IP "\fBallow hosts (S)\fP" 
 .IP 
-A synonym for this parameter is \fB\'hosts allow\'\fP
-.IP 
-This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service\&.
+Synonym for \fBhosts allow\fP\&.
 .IP 
-If specified in the \fB[global]\fP section then it will
-apply to all services, regardless of whether the individual service
-has a different setting\&.
+.IP "\fBallow trusted domains (G)\fP" 
 .IP 
-You can specify the hosts by name or IP number\&. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like \f(CW"allow hosts = 150\&.203\&.5\&."\fP\&. The full syntax of the list is
-described in the man page \fBhosts_access (5)\fP\&. Note that this man
-page may not be present on your system, so a brief description will
-be given here also\&.
+This option only takes effect when the \fBsecurity\fP
+option is set to \fBserver\fP or \fBdomain\fP\&.  If it is set to no,
+then attempts to connect to a resource from a domain or workgroup other than
+the one which smbd is running in will fail, even if that domain
+is trusted by the remote server doing the authentication\&.
 .IP 
-\fINOTE:\fP IF you wish to allow the \fBsmbpasswd
-(8)\fP program to be run by local users to change
-their Samba passwords using the local \fBsmbd (8)\fP
-daemon, then you \fIMUST\fP ensure that the localhost is listed in your
-\fBallow hosts\fP list, as \fBsmbpasswd (8)\fP runs
-in client-server mode and is seen by the local
-\fBsmbd\fP process as just another client\&.
-.IP 
-You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups\&. The \fIEXCEPT\fP keyword can also
-be used to limit a wildcard list\&. The following examples may provide
-some help:
-.IP 
-\fBExample 1\fP: allow localhost and all IPs in 150\&.203\&.*\&.* except one
-.IP 
-\f(CW  hosts allow = localhost, 150\&.203\&. EXCEPT 150\&.203\&.6\&.66\fP
-.IP 
-\fBExample 2\fP: allow localhost and hosts that match the given network/netmask
-.IP 
-\f(CW  hosts allow = localhost, 150\&.203\&.15\&.0/255\&.255\&.255\&.0\fP
-.IP 
-\fBExample 3\fP: allow a localhost plus a couple of hosts
-.IP 
-\f(CW  hosts allow = localhost, lapland, arvidsjaur\fP
-.IP 
-\fBExample 4\fP: allow only hosts in NIS netgroup "foonet" or localhost, but 
-deny access from one particular host
-.IP 
-\f(CW  hosts allow = @foonet, localhost\fP
-\f(CW  hosts deny = pirate\fP
-.IP 
-Note that access still requires suitable user-level passwords\&.
-.IP 
-See \fBtestparm (1)\fP for a way of testing your
-host access to see if it does what you expect\&.
+This is useful if you only want your Samba server to serve resources
+to users in the domain it is a member of\&. As an example, suppose that there are
+two domains DOMA and DOMB\&.  DOMB is trusted by DOMA, which contains
+the Samba server\&.  Under normal circumstances, a user with an account
+in DOMB can then access the resources of a UNIX account with the same
+account name on the Samba server even if they do not have an account
+in DOMA\&.  This can make implementing a security boundary difficult\&.
 .IP 
 \fBDefault:\fP
-\f(CW  none (i\&.e\&., all hosts permitted access)\fP
+\f(CW     allow trusted domains = Yes\fP
 .IP 
 \fBExample:\fP
-\f(CW  allow hosts = 150\&.203\&.5\&. localhost myhost\&.mynet\&.edu\&.au\fP
+\f(CW     allow trusted domains = No\fP
 .IP 
 .IP "\fBalternate permissions (S)\fP" 
 .IP 
@@ -1310,14 +1379,15 @@ regardless if the owner of the file is the currently logged on user or not\&.
 .IP 
 This specifies what type of server \fBnmbd\fP will
 announce itself as, to a network neighborhood browse list\&. By default
-this is set to Windows NT\&. The valid options are : "NT", "Win95" or
-"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
-respectively\&. Do not change this parameter unless you have a specific
-need to stop Samba appearing as an NT server as this may prevent Samba
-servers from participating as browser servers correctly\&.
+this is set to Windows NT\&. The valid options are : "NT", which is a
+synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
+"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
+and Windows for Workgroups respectively\&. Do not change this parameter
+unless you have a specific need to stop Samba appearing as an NT server
+as this may prevent Samba servers from participating as browser servers correctly\&.
 .IP 
 \fBDefault:\fP
-\f(CW  announce as = NT\fP
+\f(CW  announce as = NT Server\fP
 .IP 
 \fBExample\fP
 \f(CW  announce as = Win95\fP
@@ -1396,11 +1466,16 @@ should not use this parameter for machines that are serving PPP or
 other intermittent or non-broadcast network interfaces as it will not
 cope with non-permanent interfaces\&.
 .IP 
-In addition, to change a users SMB password, the
-\fBsmbpasswd\fP by default connects to the
-\fI"localhost" - 127\&.0\&.0\&.1\fP address as an SMB client to issue the
-password change request\&. If \fB"bind interfaces only"\fP is set then
-unless the network address \fI127\&.0\&.0\&.1\fP is added to the
+If \fB"bind interfaces only"\fP is set then unless the network address
+\fI127\&.0\&.0\&.1\fP is added to the \fB\'interfaces\'\fP parameter
+list \fBsmbpasswd\fP and
+\fBswat\fP may not work as expected due to the
+reasons covered below\&.
+.IP 
+To change a users SMB password, the \fBsmbpasswd\fP
+by default connects to the \fI"localhost" - 127\&.0\&.0\&.1\fP address as an SMB
+client to issue the password change request\&. If \fB"bind interfaces only"\fP
+is set then unless the network address \fI127\&.0\&.0\&.1\fP is added to the
 \fB\'interfaces\'\fP parameter list then
 \fBsmbpasswd\fP will fail to connect in it\'s
 default mode\&. \fBsmbpasswd\fP can be forced to
@@ -1409,6 +1484,14 @@ use the primary IP interface of the local host by using its
 \fB"remote machine"\fP set to the IP name of the primary interface
 of the local host\&.
 .IP 
+The \fBswat\fP status page tries to connect with
+\fBsmbd\fP and \fBnmbd\fP at the address 
+\fI127\&.0\&.0\&.1\fP to determine if they are running\&.  Not adding \fI127\&.0\&.0\&.1\fP  will cause
+\fBsmbd\fP and \fBnmbd\fP to always show
+"not running" even if they really are\&.  This can prevent
+\fBswat\fP from starting/stopping/restarting
+\fBsmbd\fP and \fBnmbd\fP\&.
+.IP 
 \fBDefault:\fP
 \f(CW  bind interfaces only = False\fP
 .IP 
@@ -1462,11 +1545,11 @@ shares in a net view and in the browse list\&.
 \fBExample:\fP
 \f(CW  browseable = No\fP
 .IP 
-.IP "\fBcase sensitive (S)\fP" 
+.IP "\fBcase sensitive (G)\fP" 
 .IP 
 See the discussion in the section \fBNAME MANGLING\fP\&.
 .IP 
-.IP "\fBcasesignames (S)\fP" 
+.IP "\fBcasesignames (G)\fP" 
 .IP 
 Synonym for \fB"case sensitive"\fP\&.
 .IP 
@@ -1514,7 +1597,14 @@ correctly\&.
 .IP o 
 \fBISO8859-5\fP Russian Cyrillic UNIX character set\&. The parameter
 \fBclient code page\fP \fIMUST\fP be set to code
-page 866 if the \fBcharacter set\fP parameter is set to ISO8859-2
+page 866 if the \fBcharacter set\fP parameter is set to ISO8859-5
+in order for the conversion to the UNIX character set to be done
+correctly\&. 
+.IP 
+.IP o 
+\fBISO8859-7\fP Greek UNIX character set\&. The parameter
+\fBclient code page\fP \fIMUST\fP be set to code
+page 737 if the \fBcharacter set\fP parameter is set to ISO8859-7
 in order for the conversion to the UNIX character set to be done
 correctly\&. 
 .IP 
@@ -1766,6 +1856,21 @@ performed\&.
 \fBExample:\fP
 \f(CW  deadtime = 15\fP
 .IP 
+.IP "\fBdebug hires timestamp (G)\fP" 
+.IP 
+Sometimes the timestamps in the log messages are needed with a
+resolution of higher that seconds, this boolean parameter adds
+microsecond resolution to the timestamp message header when turned on\&.
+.IP 
+Note that the parameter \fBdebug timestamp\fP
+must be on for this to have an effect\&.
+.IP 
+\fBDefault:\fP
+\f(CW debug hires timestamp = No\fP
+.IP 
+\fBExample:\fP
+\f(CW debug hires timestamp = Yes\fP
+.IP 
 .IP "\fBdebug timestamp (G)\fP" 
 .IP 
 Samba2\&.0 debug log messages are timestamped by default\&. If you are
@@ -1779,6 +1884,37 @@ off\&.
 \fBExample:\fP
 \f(CW  debug timestamp = No\fP
 .IP 
+.IP "\fBdebug pid (G)\fP" 
+.IP 
+When using only one log file for more then one forked smbd-process
+there may be hard to follow which process outputs which message\&.
+This boolean parameter is adds the process-id to the timestamp message
+headers in the logfile when turned on\&.
+.IP 
+Note that the parameter \fBdebug timestamp\fP
+must be on for this to have an effect\&.
+.IP 
+\fBDefault:\fP
+\f(CW  debug pid = No\fP
+.IP 
+\fBExample:\fP
+\f(CW  debug pid = Yes\fP
+.IP 
+.IP "\fBdebug uid (G)\fP" 
+.IP 
+Samba is sometimes run as root and sometime run as the connected
+user, this boolean parameter inserts the current euid, egid, uid
+and gid to the timestamp message headers in the log file if turned on\&.
+.IP 
+Note that the parameter \fBdebug timestamp\fP
+must be on for this to have an effect\&.
+.IP 
+\fBDefault:\fP
+\f(CW  debug uid = No\fP
+.IP 
+\fBExample:\fP
+\f(CW  debug uid = Yes\fP
+.IP 
 .IP "\fBdebug level (G)\fP" 
 .IP 
 The value of the parameter (an integer) allows the debug level
@@ -1835,6 +1971,59 @@ interesting things\&.
 .DE 
  
 
+.IP 
+.IP "\fBdelete user script (G)\fP" 
+.IP 
+This is the full pathname to a script that will be run \fIAS ROOT\fP by
+\fBsmbd (8)\fP under special circumstances decribed
+below\&.
+.IP 
+Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server\&. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task\&. This option allows \fBsmbd\fP to delete
+the required UNIX users \fION DEMAND\fP when a user accesses the Samba
+server and the Windows NT user no longer exists\&.
+.IP 
+In order to use this option, \fBsmbd\fP must be set to
+\fBsecurity=domain\fP and \fB"delete user
+script"\fP must be set to a full pathname for a script that will delete
+a UNIX user given one argument of \fB%u\fP, which expands into the UNIX
+user name to delete\&. \fINOTE\fP that this is different to the
+\fBadd user script\fP which will work with the
+\fBsecurity=server\fP option as well as
+\fBsecurity=domain\fP\&. The reason for this
+is only when Samba is a domain member does it get the information
+on an attempted user logon that a user no longer exists\&. In the
+\fBsecurity=server\fP mode a missing user
+is treated the same as an invalid password logon attempt\&. Deleting
+the user in this circumstance would not be a good idea\&.
+.IP 
+When the Windows user attempts to access the Samba server, at
+\fI"login"\fP(session setup in the SMB protocol) time,
+\fBsmbd\fP contacts the \fBpassword
+server\fP and attempts to authenticate the given user
+with the given password\&. If the authentication fails with the specific
+Domain error code meaning that the user no longer exists then
+\fBsmbd\fP attempts to find a UNIX user in the UNIX
+password database that matches the Windows user account\&. If this lookup succeeds,
+and \fB"delete user script"\fP is set then \fBsmbd\fP will
+call the specified script \fIAS ROOT\fP, expanding any \fB%u\fP argument
+to be the user name to delete\&.
+.IP 
+This script should delete the given UNIX username\&. In this way, UNIX
+users are dynamically deleted to match existing Windows NT accounts\&.
+.IP 
+See also \fBsecurity=domain\fP,
+\fBpassword server\fP, \fBadd user
+script\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW  delete user script = <empty string>\fP
+.IP 
+\fBExample:\fP
+\f(CW  delete user script = /usr/local/samba/bin/del_user %u\fP
 .IP 
 .IP "\fBdelete readonly (S)\fP" 
 .IP 
@@ -1880,16 +2069,7 @@ See also the \fBveto files\fP parameter\&.
 .IP 
 .IP "\fBdeny hosts (S)\fP" 
 .IP 
-The opposite of \fB\'allow hosts\'\fP - hosts listed
-here are \fINOT\fP permitted access to services unless the specific
-services have their own lists to override this one\&. Where the lists
-conflict, the \fB\'allow\'\fP list takes precedence\&.
-.IP 
-\fBDefault:\fP
-\f(CW  none (i\&.e\&., no hosts specifically excluded)\fP
-.IP 
-\fBExample:\fP
-\f(CW  deny hosts = 150\&.203\&.4\&. badhost\&.mynet\&.edu\&.au\fP
+Synonym for \fBhosts deny\fP\&.
 .IP 
 .IP "\fBdfree command (G)\fP" 
 .IP 
@@ -1980,7 +2160,8 @@ See the \fB"force directory mode"\fP parameter
 to cause particular mode bits to always be set on created directories\&.
 .IP 
 See also the \fB"create mode"\fP parameter for masking
-mode bits on created files\&.
+mode bits on created files, and the \fB"directory security mask"\fP
+parameter\&.
 .IP 
 \fBDefault:\fP
 \f(CW  directory mask = 0755\fP
@@ -1992,6 +2173,38 @@ mode bits on created files\&.
 .IP 
 Synonym for \fBdirectory mask\fP\&.
 .IP 
+.IP "\fBdirectory security mask (S)\fP" 
+.IP 
+This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+directory using the native NT security dialog box\&.
+.IP 
+This parameter is applied as a mask (AND\'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified\&. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change\&.
+.IP 
+If not set explicitly this parameter is set to the same value as the
+\fBdirectory mask\fP parameter\&. To allow a user to
+modify all the user/group/world permissions on a directory, set this
+parameter to 0777\&.
+.IP 
+\fINote\fP that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems\&.  Administrators of
+most normal systems will probably want to set it to 0777\&.
+.IP 
+See also the \fBforce directory security
+mode\fP, \fBsecurity
+mask\fP, \fBforce security mode\fP
+parameters\&.
+.IP 
+\fBDefault:\fP
+\f(CW  directory security mask = <same as directory mask>\fP
+.IP 
+\fBExample:\fP
+\f(CW  directory security mask = 0777\fP
+.IP 
 .IP "\fBdns proxy (G)\fP" 
 .IP 
 Specifies that \fBnmbd\fP when acting as a WINS
@@ -2015,7 +2228,7 @@ See also the parameter \fBwins support\fP\&.
 \fBdomain admin group (G)\fP
 .IP 
 This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&.  It has been removed as of November 98\&.
+Samba NT Domain Controller Code\&. It may be removed in a later release\&.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2024,7 +2237,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
 .IP "\fBdomain admin users (G)\fP" 
 .IP 
 This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
+Samba NT Domain Controller Code\&. It may be removed in a later release\&.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2036,91 +2249,10 @@ This is a \fBDEPRECATED\fP parameter\&. It is currently not used within
 the Samba source and should be removed from all current smb\&.conf
 files\&. It is left behind for compatibility reasons\&.
 .IP 
-.IP "\fBdomain group map (G)\fP" 
-.IP 
-This option allows you to specify a file containing unique mappings
-of individual NT Domain Group names (in any domain) to UNIX group
-names\&.  This allows NT domain groups to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX\&.  The reader is advised to become familiar
-with the NT Domain system and its administration\&.
-.IP 
-This option is used in conjunction with \fB\'local group map\'\fP
-and \fB\'domain user map\'\fP\&.  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers)\&.
-.IP 
-The map file is parsed line by line\&.  If any line begins with a \f(CW\'#\'\fP
-or a \f(CW\';\'\fP then it is ignored\&.  Each line should contain a single UNIX
-group name on the left then a single NT Domain Group name on the right,
-separated by a tabstop or \f(CW\'=\'\fP\&.  If either name contains spaces then
-it should be enclosed in quotes\&.
-The line can be either of the form:
-.IP 
-\f(CW  UNIXgroupname   \e\eDOMAIN_NAME\e\eDomainGroupName \fP
-.IP 
-or:
-.IP 
-\f(CW  UNIXgroupname   DomainGroupName \fP
-.IP 
-In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
-or it is a member of a domain using \fB"security = domain"\fP,
-the latter format can be used: the default Domain name is the Samba Server\'s
-Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
-.IP 
-Any UNIX groups that are \fINOT\fP specified in this map file are assumed to
-be either Local or Domain Groups, depending on the role of the Samba Server\&.
-.IP 
-In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
-will present \fIALL\fP such unspecified UNIX groups as its own NT Domain
-Groups, with the same name\&.
-.IP 
-In the case where Samba is member of a domain using
-\fB"security = domain"\fP, Samba will check the UNIX name with
-its Domain Controller (see \fB"password server"\fP)
-as if it was an NT Domain Group\&.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server\'s local SAM database\&.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
-Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
-a local Workstation\&.
-.IP 
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all\&.  If you \fBwant\fP to get fancy, however, you can\&.
-.IP 
-Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group \fIREQUIRES\fP the following:
-.IP 
-.IP 
-.IP o 
-that the UNIX group exists on the UNIX server\&.
-.IP 
-.IP o 
-that the NT Domain Group exists in the specified NT Domain
-.IP 
-.IP o 
-that the UNIX Server knows about the specified Domain; 
-.IP 
-.IP o 
-that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using \fB\'domain user map\'\fP\&.
-.IP 
-.IP 
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users\&.
-.IP 
 .IP "\fBdomain groups (G)\fP" 
 .IP 
 This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
+Samba NT Domain Controller Code\&. It may be removed in a later release\&.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2129,7 +2261,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
 .IP "\fBdomain guest group (G)\fP" 
 .IP 
 This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
+Samba NT Domain Controller Code\&. It may be removed in a later release\&.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2138,7 +2270,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
 .IP "\fBdomain guest users (G)\fP" 
 .IP 
 This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
+Samba NT Domain Controller Code\&. It may be removed in a later release\&.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2184,95 +2316,9 @@ special name for a \fBworkgroup\fP before a Windows NT
 PDC is able to do so then cross subnet browsing will behave strangely
 and may fail\&.
 .IP 
-By default ("auto") Samba will attempt to become the domain master
-browser only if it is the Primary Domain Controller\&.
-.IP 
 \fBDefault:\fP
-\f(CW  domain master = auto\fP
-.IP 
-\fBExample:\fP
 \f(CW  domain master = no\fP
 .IP 
-.IP "\fBdomain user map (G)\fP" 
-.IP 
-This option allows you to specify a file containing unique mappings
-of individual NT Domain User names (in any domain) to UNIX user
-names\&.  This allows NT domain users to be presented correctly to
-NT systems, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX\&.  The reader is advised to become familiar
-with the NT Domain system and its administration\&.
-.IP 
-This option is used in conjunction with \fB\'local group map\'\fP
-and \fB\'domain group map\'\fP\&.  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers)\&.
-.IP 
-This option, which provides (and maintains) a one-to-one link between
-UNIX and NT users, is \fIDIFFERENT\fP from \fB\'username map\'\fP, which does \fINOT\fP maintain a distinction between the
-name(s) it can map to and the name it maps\&.
-.IP 
-The map file is parsed line by line\&.  If any line begins with a \f(CW\'#\'\fP
-or a \f(CW\';\'\fP then the line is ignored\&.  Each line should contain a single UNIX
-user name on the left then a single NT Domain User name on the right,
-separated by a tabstop or \f(CW\'=\'\fP\&.  If either name contains spaces then
-it should be enclosed in quotes\&.
-The line can be either of the form:
-.IP 
-\f(CW  UNIXusername    \e\eDOMAIN_NAME\e\eDomainUserName \fP
-.IP 
-or:
-.IP 
-\f(CW  UNIXusername    DomainUserName \fP
-.IP 
-In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
-or it is a member of a domain using \fB"security = domain"\fP,
-the latter format can be used: the default Domain name is the Samba Server\'s
-Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
-.IP 
-Any UNIX users that are \fINOT\fP specified in this map file are assumed
-to be either Domain or Workstation Users, depending on the role of the
-Samba Server\&.
-.IP 
-In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
-will present \fIALL\fP such unspecified UNIX users as its own NT Domain
-Users, with the same name\&.
-.IP 
-In the case where Samba is a member of a domain using
-\fB"security = domain"\fP, Samba will check the UNIX name with
-its Domain Controller (see \fB"password server"\fP)
-as if it was an NT Domain User\&.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX users which also are not NT Domain
-Users are treated as Local Users in the Samba Server\'s local SAM database\&.
-NT Administrators will recognise these as Workstation Users,
-which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
-Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
-a local Workstation\&.
-.IP 
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all\&.  If you \fBwant\fP to get fancy, however, you can\&.
-.IP 
-Note that adding an entry to map an arbitrary NT User in an arbitrary
-Domain to an arbitrary UNIX user \fIREQUIRES\fP the following:
-.IP 
-.IP 
-.IP o 
-that the UNIX user exists on the UNIX server\&.
-.IP 
-.IP o 
-that the NT Domain User exists in the specified NT Domain\&.
-.IP 
-.IP o 
-that the UNIX Server knows about the specified Domain\&.
-.IP 
-.IP 
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users\&.
-.IP 
 .IP "\fBdont descend (S)\fP" 
 .IP 
 There are certain directories on some systems (e\&.g\&., the \f(CW/proc\fP tree
@@ -2470,6 +2516,38 @@ would force all created directories to have read and execute
 permissions set for \'group\' and \'other\' as well as the
 read/write/execute bits set for the \'user\'\&.
 .IP 
+.IP "\fBforce directory security mode (S)\fP" 
+.IP 
+This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a directory
+using the native NT security dialog box\&.
+.IP 
+This parameter is applied as a mask (OR\'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on\&. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a directory,
+the user has always set to be \'on\'\&.
+.IP 
+If not set explicitly this parameter is set to the same value as the
+\fBforce directory mode\fP parameter\&. To allow
+a user to modify all the user/group/world permissions on a directory,
+with restrictions set this parameter to 000\&.
+.IP 
+\fINote\fP that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems\&.  Administrators of
+most normal systems will probably want to set it to 0000\&.
+.IP 
+See also the \fBdirectory security mask\fP,
+\fBsecurity mask\fP, \fBforce security
+mode\fP parameters\&.
+.IP 
+\fBDefault:\fP
+\f(CW  force directory security mode = <same as force directory mode>\fP
+.IP 
+\fBExample:\fP
+\f(CW  force directory security mode = 0\fP
+.IP 
 .IP "\fBforce group (S)\fP" 
 .IP 
 This specifies a UNIX group name that will be assigned as the default
@@ -2480,12 +2558,63 @@ permissions for this group to the files and directories within this
 service the Samba administrator can restrict or allow sharing of these
 files\&.
 .IP 
+In Samba 2\&.0\&.5 and above this parameter has extended functionality in the following
+way\&. If the group name listed here has a \'+\' character prepended to it
+then the current user accessing the share only has the primary group 
+default assigned to this group if they are already assigned as a member
+of that group\&. This allows an administrator to decide that only users
+who are already in a particular group will create files with group 
+ownership set to that group\&. This gives a finer granularity of ownership
+assignment\&. For example, the setting \f(CWforce group = +sys\fP means
+that only users who are already in group sys will have their default
+primary group assigned to sys when accessing this Samba share\&. All
+other users will retain their ordinary primary group\&.
+.IP 
+If the \fB"force user"\fP parameter is also set the
+group specified in \fBforce group\fP will override the primary group
+set in \fB"force user"\fP\&.
+.IP 
+See also \fB"force user"\fP
+.IP 
 \fBDefault:\fP
 \f(CW  no forced group\fP
 .IP 
 \fBExample:\fP
 \f(CW  force group = agroup\fP
 .IP 
+.IP "\fBforce security mode (S)\fP" 
+.IP 
+This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a file
+using the native NT security dialog box\&.
+.IP 
+This parameter is applied as a mask (OR\'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on\&. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a file, the
+user has always set to be \'on\'\&.
+.IP 
+If not set explicitly this parameter is set to the same value as the
+\fBforce create mode\fP parameter\&. To allow
+a user to modify all the user/group/world permissions on a file,
+with no restrictions set this parameter to 000\&.
+.IP 
+\fINote\fP that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems\&.  Administrators of
+most normal systems will probably want to set it to 0000\&.
+.IP 
+See also the \fBforce directory security
+mode\fP, \fBdirectory security
+mask\fP, \fBsecurity mask\fP
+parameters\&.
+.IP 
+\fBDefault:\fP
+\f(CW  force security mode = <same as force create mode>\fP
+.IP 
+\fBExample:\fP
+\f(CW  force security mode = 0\fP
+.IP 
 .IP "\fBforce user (S)\fP" 
 .IP 
 This specifies a UNIX user name that will be assigned as the default
@@ -2500,6 +2629,13 @@ password\&. Once connected, all file operations will be performed as the
 .IP 
 This can be very useful\&.
 .IP 
+In Samba 2\&.0\&.5 and above this parameter also causes the primary
+group of the forced user to be used as the primary group for all
+file activity\&. Prior to 2\&.0\&.5 the primary group was left as the
+primary group of the connecting user (this was a bug)\&.
+.IP 
+See also \fB"force group"\fP
+.IP 
 \fBDefault:\fP
 \f(CW  no forced user\fP
 .IP 
@@ -2671,11 +2807,72 @@ logons\fP\&.
 .IP 
 .IP "\fBhosts allow (S)\fP" 
 .IP 
-Synonym for \fBallow hosts\fP\&.
+A synonym for this parameter is \fB\'allow hosts\'\fP
+.IP 
+This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service\&.
+.IP 
+If specified in the \fB[global]\fP section then it will
+apply to all services, regardless of whether the individual service
+has a different setting\&.
+.IP 
+You can specify the hosts by name or IP number\&. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like \f(CW"allow hosts = 150\&.203\&.5\&."\fP\&. The full syntax of the list is
+described in the man page \fBhosts_access (5)\fP\&. Note that this man
+page may not be present on your system, so a brief description will
+be given here also\&.
+.IP 
+Note that the localhost address 127\&.0\&.0\&.1 will always be allowed
+access unless specifically denied by a "hosts deny" option\&.
+.IP 
+You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups\&. The \fIEXCEPT\fP keyword can also
+be used to limit a wildcard list\&. The following examples may provide
+some help:
+.IP 
+\fBExample 1\fP: allow all IPs in 150\&.203\&.*\&.* except one
+.IP 
+\f(CW  hosts allow = 150\&.203\&. EXCEPT 150\&.203\&.6\&.66\fP
+.IP 
+\fBExample 2\fP: allow hosts that match the given network/netmask
+.IP 
+\f(CW  hosts allow = 150\&.203\&.15\&.0/255\&.255\&.255\&.0\fP
+.IP 
+\fBExample 3\fP: allow a couple of hosts
+.IP 
+\f(CW  hosts allow = lapland, arvidsjaur\fP
+.IP 
+\fBExample 4\fP: allow only hosts in NIS netgroup "foonet", but 
+deny access from one particular host
+.IP 
+\f(CW  hosts allow = @foonet\fP
+.IP 
+\f(CW  hosts deny = pirate\fP
+.IP 
+Note that access still requires suitable user-level passwords\&.
+.IP 
+See \fBtestparm (1)\fP for a way of testing your
+host access to see if it does what you expect\&.
+.IP 
+\fBDefault:\fP
+\f(CW  none (i\&.e\&., all hosts permitted access)\fP
+.IP 
+\fBExample:\fP
+\f(CW  allow hosts = 150\&.203\&.5\&. myhost\&.mynet\&.edu\&.au\fP
 .IP 
 .IP "\fBhosts deny (S)\fP" 
 .IP 
-Synonym for \fBdenyhosts\fP\&.
+The opposite of \fB\'hosts allow\'\fP - hosts listed
+here are \fINOT\fP permitted access to services unless the specific
+services have their own lists to override this one\&. Where the lists
+conflict, the \fB\'allow\'\fP list takes precedence\&.
+.IP 
+\fBDefault:\fP
+\f(CW  none (i\&.e\&., no hosts specifically excluded)\fP
+.IP 
+\fBExample:\fP
+\f(CW  hosts deny = 150\&.203\&.4\&. badhost\&.mynet\&.edu\&.au\fP
 .IP 
 .IP "\fBhosts equiv (G)\fP" 
 .IP 
@@ -2683,7 +2880,7 @@ If this global parameter is a non-null string, it specifies the name
 of a file to read for the names of hosts and users who will be allowed
 access without specifying a password\&.
 .IP 
-This is not be confused with \fBallow hosts\fP which
+This is not be confused with \fBhosts allow\fP which
 is about hosts access to services and is more useful for guest
 services\&. \fBhosts equiv\fP may be useful for NT clients which will not
 supply passwords to samba\&.
@@ -2711,28 +2908,38 @@ It takes the standard substitutions, except \fB%u\fP,
 .IP 
 .IP "\fBinterfaces (G)\fP" 
 .IP 
-This option allows you to setup multiple network interfaces, so that
-Samba can properly handle browsing on all interfaces\&.
+This option allows you to override the default network interfaces list
+that Samba will use for browsing, name registration and other NBT
+traffic\&. By default Samba will query the kernel for the list of all
+active interfaces and use any interfaces except 127\&.0\&.0\&.1 that are
+broadcast capable\&.
 .IP 
-The option takes a list of ip/netmask pairs\&. The netmask may either be
-a bitmask, or a bitlength\&.
+The option takes a list of interface strings\&. Each string can be in
+any of the following forms:
 .IP 
-For example, the following line:
-.IP 
-\f(CWinterfaces = 192\&.168\&.2\&.10/24 192\&.168\&.3\&.10/24\fP
+.IP o 
+a network interface name (such as eth0)\&. This may include
+shell-like wildcards so eth* will match any interface starting
+with the substring "eth"
+if() a IP address\&. In this case the netmask is determined
+from the list of interfaces obtained from the kernel
+if() a IP/mask pair\&. 
+if() a broadcast/mask pair\&. 
 .IP 
-would configure two network interfaces with IP addresses 192\&.168\&.2\&.10
-and 192\&.168\&.3\&.10\&. The netmasks of both interfaces would be set to
-255\&.255\&.255\&.0\&.
+The "mask" parameters can either be a bit length (such as 24 for a C
+class network) or a full netmask in dotted decmal form\&.
 .IP 
-You could produce an equivalent result by using:
+The "IP" parameters above can either be a full dotted decimal IP
+address or a hostname which will be looked up via the OSes normal
+hostname resolution mechanisms\&.
 .IP 
-\f(CWinterfaces = 192\&.168\&.2\&.10/255\&.255\&.255\&.0 192\&.168\&.3\&.10/255\&.255\&.255\&.0\fP
+For example, the following line:
 .IP 
-if you prefer that format\&.
+\f(CWinterfaces = eth0 192\&.168\&.2\&.10/24 192\&.168\&.3\&.10/255\&.255\&.255\&.0\fP
 .IP 
-If this option is not set then Samba will attempt to find a primary
-interface, but won\'t attempt to configure more than one interface\&.
+would configure three network interfaces corresponding to the eth0
+device and IP addresses 192\&.168\&.2\&.10 and 192\&.168\&.3\&.10\&. The netmasks of
+the latter two interfaces would be set to 255\&.255\&.255\&.0\&.
 .IP 
 See also \fB"bind interfaces only"\fP\&.
 .IP 
@@ -2781,10 +2988,10 @@ options"\fP)\&. Basically you should only use this option
 if you strike difficulties\&.
 .IP 
 \fBDefault:\fP
-\f(CW  keep alive = 0\fP
+\f(CW  keepalive = 0\fP
 .IP 
 \fBExample:\fP
-\f(CW  keep alive = 60\fP
+\f(CW  keepalive = 60\fP
 .IP 
 .IP "\fBkernel oplocks (G)\fP" 
 .IP 
@@ -2802,52 +3009,72 @@ This parameter defaults to \fI"On"\fP on systems that have the support,
 and \fI"off"\fP on systems that don\'t\&. You should never need to touch
 this parameter\&.
 .IP 
-.IP "\fBldap bind as (G)\fP" 
+See also the \fB"oplocks"\fP and \fB"level2 oplocks"\fP
+parameters\&.
+.IP 
+.IP "\fBldap filter (G)\fP" 
 .IP 
 This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server\&. These options are only
-available if your version of Samba was configured with the \fB--with-ldap\fP
-option\&.
+password database stored on an LDAP server back-end\&. These options
+are only available if your version of Samba was configured with
+the \fB--with-ldap\fP option\&.
 .IP 
-This parameter specifies the entity to bind to an LDAP directory as\&.
-Usually it should be safe to use the LDAP root account; for larger
-installations it may be preferable to restrict Samba\'s access\&. See also
-\fBldap passwd file\fP\&.
+This parameter specifies an LDAP search filter used to search for a
+user name in the LDAP database\&. It must contain the string
+\fB%u\fP which will be replaced with the user being
+searched for\&.
 .IP 
 \fBDefault:\fP
-\f(CW  none (bind anonymously)\fP
-.IP 
-\fBExample:\fP
-\f(CW  ldap bind as = "uid=root, dc=mydomain, dc=org"\fP
+\f(CW  empty string\&.\fP
 .IP 
-.IP "\fBldap passwd file (G)\fP" 
+.IP "\fBldap port (G)\fP" 
 .IP 
 This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server\&. These options are only
-available if your version of Samba was configured with the \fB--with-ldap\fP
-option\&.
+password database stored on an LDAP server back-end\&. These options
+are only available if your version of Samba was configured with
+the \fB--with-ldap\fP option\&.
 .IP 
-This parameter specifies a file containing the password with which
-Samba should bind to an LDAP server\&. For obvious security reasons
-this file must be set to mode 700 or less\&.
+This parameter specifies the TCP port number to use to contact
+the LDAP server on\&.
 .IP 
 \fBDefault:\fP
-\f(CW  none (bind anonymously)\fP
+\f(CW  ldap port = 389\&.\fP
 .IP 
-\fBExample:\fP
-\f(CW  ldap passwd file = /usr/local/samba/private/ldappasswd\fP
+.IP "\fBldap root (G)\fP" 
 .IP 
-.IP "\fBldap port (G)\fP" 
+This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
+password database stored on an LDAP server back-end\&. These options
+are only available if your version of Samba was configured with
+the \fB--with-ldap\fP option\&.
+.IP 
+This parameter specifies the entity to bind to the LDAP server
+as (essentially the LDAP username) in order to be able to perform
+queries and modifications on the LDAP database\&.
+.IP 
+See also \fBldap root passwd\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW  empty string (no user defined)\fP
+.IP 
+.IP "\fBldap root passwd (G)\fP" 
 .IP 
 This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server\&. These options are only
-available if your version of Samba was configured with the \fB--with-ldap\fP
-option\&.
+password database stored on an LDAP server back-end\&. These options
+are only available if your version of Samba was configured with
+the \fB--with-ldap\fP option\&.
+.IP 
+This parameter specifies the password for the entity to bind to the
+LDAP server as (the password for this LDAP username) in order to be
+able to perform queries and modifications on the LDAP database\&.
 .IP 
-This parameter specifies the TCP port number of the LDAP server\&.
+\fIBUGS:\fP This parameter should \fINOT\fP be a readable parameter
+in the \fBsmb\&.conf\fP file and will be removed once a correct
+storage place is found\&.
+.IP 
+See also \fBldap root\fP\&.
 .IP 
 \fBDefault:\fP
-\f(CW  ldap port = 389\&.\fP
+\f(CW  empty string\&.\fP
 .IP 
 .IP "\fBldap server (G)\fP" 
 .IP 
@@ -2857,8 +3084,7 @@ are only available if your version of Samba was configured with
 the \fB--with-ldap\fP option\&.
 .IP 
 This parameter specifies the DNS name of the LDAP server to use
-when storing and retrieving information about Samba users and
-groups\&.
+for SMB/CIFS authentication purposes\&.
 .IP 
 \fBDefault:\fP
 \f(CW  ldap server = localhost\fP
@@ -2870,15 +3096,52 @@ password database stored on an LDAP server back-end\&. These options
 are only available if your version of Samba was configured with
 the \fB--with-ldap\fP option\&.
 .IP 
-This parameter specifies the node of the LDAP tree beneath which
-Samba should store its information\&. This parameter MUST be provided
-when using LDAP with Samba\&.
+This parameter specifies the \f(CW"dn"\fP or LDAP \fI"distinguished name"\fP
+that tells \fBsmbd\fP to start from when searching
+for an entry in the LDAP password database\&.
 .IP 
 \fBDefault:\fP
-\f(CW  none\fP
+\f(CW  empty string\&.\fP
+.IP 
+.IP "\fBlevel2 oplocks (S)\fP" 
+.IP 
+This parameter (new in Samba 2\&.0\&.5) controls whether Samba supports
+level2 (read-only) oplocks on a share\&. In Samba 2\&.0\&.4 this parameter
+defaults to "False" as the code is new, but will default to "True"
+in a later release\&.
+.IP 
+Level2, or read-only oplocks allow Windows NT clients that have an
+oplock on a file to downgrade from a read-write oplock to a read-only
+oplock once a second client opens the file (instead of releasing all
+oplocks on a second open, as in traditional, exclusive oplocks)\&. This
+allows all openers of the file that support level2 oplocks to cache
+the file for read-ahead only (ie\&. they may not cache writes or lock
+requests) and increases performance for many acesses of files that
+are not commonly written (such as application \&.EXE files)\&.
+.IP 
+Once one of the clients which have a read-only oplock writes to
+the file all clients are notified (no reply is needed or waited
+for) and told to break their oplocks to "none" and delete any
+read-ahead caches\&.
+.IP 
+It is recommended that this parameter be turned on to speed access
+to shared executables (and also to test the code :-)\&.
+.IP 
+For more discussions on level2 oplocks see the CIFS spec\&.
+.IP 
+Currently, if \fB"kernel oplocks"\fP are supported
+then level2 oplocks are not granted (even if this parameter is set
+to \f(CW"true"\fP)\&. Note also, the \fB"oplocks"\fP parameter must
+be set to "true" on this share in order for this parameter to have any
+effect\&.
+.IP 
+See also the \fB"oplocks"\fP and \fB"kernel oplocks"\fP parameters\&.
+.IP 
+\fBDefault:\fP
+\f(CW level2 oplocks = False\fP
 .IP 
 \fBExample:\fP
-\f(CW  ldap suffix = "dc=mydomain, dc=org"\fP
+\f(CW level2 oplocks = True\fP
 .IP 
 .IP "\fBlm announce (G)\fP" 
 .IP 
@@ -2931,87 +3194,6 @@ will be loaded for browsing by default\&. See the
 \fBExample:\fP
 \f(CW  load printers = no\fP
 .IP 
-.IP "\fBlocal group map (G)\fP" 
-.IP 
-This option allows you to specify a file containing unique mappings
-of individual NT Local Group names (in any domain) to UNIX group
-names\&.  This allows NT Local groups (aliases) to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX\&.  The reader is advised to become familiar
-with the NT Domain system and its administration\&.
-.IP 
-This option is used in conjunction with \fB\'domain group map\'\fP
-and \fB\'domain name map\'\fP\&.  The use of these three
-options is trivial and often unnecessary in the case where Samba
-is not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers)\&.
-.IP 
-The map file is parsed line by line\&.  If any line begins with a \f(CW\'#\'\fP
-or a \f(CW\';\'\fP then it is ignored\&.  Each line should contain a single UNIX
-group name on the left then a single NT Local Group name on the right,
-separated by a tabstop or \f(CW\'=\'\fP\&.  If either name contains spaces then
-it should be enclosed in quotes\&.
-The line can be either of the form:
-.IP 
-\f(CW  UNIXgroupname   \e\eDOMAIN_NAME\e\eLocalGroupName \fP
-.IP 
-or:
-.IP 
-\f(CW  UNIXgroupname   LocalGroupName \fP
-.IP 
-In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
-or it is a member of a domain using \fB"security = domain"\fP,
-the latter format can be used: the default Domain name is the Samba Server\'s
-Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
-.IP 
-Any UNIX groups that are \fINOT\fP specified in this map file are treated
-as either Local or Domain Groups depending on the role of the Samba Server\&.
-.IP 
-In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
-will present \fIALL\fP unspecified UNIX groups as its own NT Domain
-Groups, with the same name, and \fINOT\fP as Local Groups\&.
-.IP 
-In the case where Samba is member of a domain using
-\fB"security = domain"\fP, Samba will check the UNIX name with
-its Domain Controller (see \fB"password server"\fP)
-as if it was an NT Domain Group\&.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server\'s local SAM database\&.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
-Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
-a local Workstation\&.
-.IP 
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all\&.  If you \fBwant\fP to get fancy, however, you can\&.
-.IP 
-Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group \fIREQUIRES\fP the following:
-.IP 
-.IP 
-.IP o 
-that the UNIX group exists on the UNIX server\&.
-.IP 
-.IP o 
-that the NT Domain Group exists in the specified NT Domain
-.IP 
-.IP o 
-that the UNIX Server knows about the specified Domain; 
-.IP 
-.IP o 
-that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using \fB\'domain user map\'\fP\&.
-.IP 
-.IP 
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users\&.
-.IP 
 .IP "\fBlocal master (G)\fP" 
 .IP 
 This option allows \fBnmbd\fP to try and become a
@@ -3416,6 +3598,12 @@ Magic scripts are \fIEXPERIMENTAL\fP and should \fINOT\fP be relied upon\&.
 .IP 
 See the section on \fB"NAME MANGLING"\fP\&.
 .IP 
+.IP "\fBmangle locks (S)\fP" 
+.IP 
+This option is was introduced with Samba 2\&.0\&.4 and above and has been
+removed in Samba 2\&.0\&.6 as Samba now dynamically configures such things
+on 32 bit systems\&.
+.IP 
 .IP "\fBmangled map (S)\fP" 
 .IP 
 This is for those who want to directly map UNIX file names which can
@@ -3708,7 +3896,7 @@ never need to set this parameter\&.
 \fBDefault:\fP
 \f(CW  max mux = 50\fP
 .IP 
-.IP "\fBmaxopenfiles (G)\fP" 
+.IP "\fBmax open files (G)\fP" 
 .IP 
 This parameter limits the maximum number of open files that one
 \fBsmbd\fP file serving process may have open for
@@ -3837,6 +4025,18 @@ See also the \fBprinting\fP parameter\&.
 \fBExample:\fP
 \f(CW  min print space = 2000\fP
 .IP 
+.IP "\fBmin passwd length (G)\fP" 
+.IP 
+This option sets the minimum length in characters of a plaintext password
+than smbd will accept when performing UNIX password changing\&.
+.IP 
+See also \fB"unix password sync"\fP,
+\fB"passwd program"\fP and \fB"passwd chat
+debug"\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW  min passwd length = 5\fP
+.IP 
 .IP "\fBmin wins ttl (G)\fP" 
 .IP 
 This option tells \fBnmbd\fP when acting as a WINS
@@ -3861,12 +4061,17 @@ names to be resolved as follows :
 .IP 
 .IP o 
 \fBlmhosts\fP : Lookup an IP address in the Samba lmhosts file\&.
+If the line in lmhosts has no name type attached to the NetBIOS
+name (see the \fBlmhosts (5)\fP for details) then
+any name type matches for lookup\&.
 .IP 
 .IP o 
 \fBhost\fP : Do a standard host name to IP address resolution,
 using the system /etc/hosts, NIS, or DNS lookups\&. This method of name
 resolution is operating system depended for instance on IRIX or
 Solaris this may be controlled by the \fI/etc/nsswitch\&.conf\fP file)\&.
+Note that this method is only used if the NetBIOS name type being
+queried is the 0x20 (server) name type, otherwise it is ignored\&.
 .IP 
 .IP o 
 \fBwins\fP : Query a name with the IP address listed in the
@@ -3955,6 +4160,17 @@ system and the Samba server with this option must also be a
 \fBExample:\fP
 \f(CW  nis homedir = true\fP
 .IP 
+.IP "\fBnt acl support (G)\fP" 
+.IP 
+This boolean parameter controls whether \fBsmbd\fP
+will attempt to map UNIX permissions into Windows NT access control lists\&.
+.IP 
+\fBDefault:\fP
+\f(CW  nt acl support = yes\fP
+.IP 
+\fBExample:\fP
+\f(CW  nt acl support = no\fP
+.IP 
 .IP "\fBnt pipe support (G)\fP" 
 .IP 
 This boolean parameter controls whether \fBsmbd\fP
@@ -4052,24 +4268,58 @@ all access to oplocked files, whether it be via Samba or NFS or a local
 UNIX process\&. See the \fBkernel oplocks\fP parameter
 for details\&.
 .IP 
+See also the \fB"kernel oplocks"\fP and
+\fB"level2 oplocks"\fP parameters\&.
+.IP 
 \fBDefault:\fP
 \f(CW  oplocks = True\fP
 .IP 
 \fBExample:\fP
 \f(CW  oplocks = False\fP
 .IP 
+.IP "\fBoplock break wait time (G)\fP" 
+.IP 
+This is a tuning parameter added due to bugs in both Windows 9x and WinNT\&.
+If Samba responds to a client too quickly when that client issues an SMB that
+can cause an oplock break request, then the client redirector can fail and
+not respond to the break request\&. This tuning parameter (which is set in
+milliseconds) is the amount of time Samba will wait before sending an
+oplock break request to such (broken) clients\&.
+.IP 
+\fIDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW  oplock break wait time = 10\fP
+.IP 
+.IP "\fBoplock contention limit (S)\fP" 
+.IP 
+This is a \fIvery\fP advanced \fBsmbd\fP tuning option to improve
+the efficiency of the granting of oplocks under multiple client contention for the same file\&.
+.IP 
+In brief it specifies a number, which causes smbd not to grant an oplock even
+when requested if the approximate number of clients contending for an oplock on
+the same file goes over this limit\&. This causes \fBsmbd\fP to
+behave in a similar way to Windows NT\&.
+.IP 
+\fIDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE\fP\&.
+.IP 
+\fBDefault:\fP
+\f(CW oplock contention limit = 2\fP
+.IP 
 .IP "\fBos level (G)\fP" 
 .IP 
 This integer value controls what level Samba advertises itself as for
 browse elections\&. The value of this parameter determines whether
 \fBnmbd\fP has a chance of becoming a local master
 browser for the \fBWORKGROUP\fP in the local broadcast
-area\&. Setting this to zero will cause \fBnmbd\fP to
-always lose elections to Windows machines\&. See BROWSING\&.txt in the
-Samba docs/ directory for details\&.
+area\&. The default is zero, which means \fBnmbd\fP will
+lose elections to Windows machines\&. See BROWSING\&.txt in the Samba
+docs/ directory for details\&.
 .IP 
 \fBDefault:\fP
-\f(CW  os level = 32\fP
+\f(CW  os level = 20\fP
 .IP 
 \fBExample:\fP
 \f(CW  os level = 65    ; This will win against any NT Server\fP
@@ -4276,7 +4526,7 @@ better restrict them with hosts allow!
 If the \fB"security"\fP parameter is set to
 \fB"domain"\fP, then the list of machines in this option must be a list
 of Primary or Backup Domain controllers for the
-\fBDomain\fP, as the Samba server is cryptographicly
+\fBDomain\fP or the character \f(CW*\fP, as the Samba server is cryptographicly
 in that domain, and will use cryptographicly authenticated RPC calls
 to authenticate the user logging on\&. The advantage of using
 \fB"security=domain"\fP is that if you list
@@ -4284,6 +4534,12 @@ several hosts in the \fB"password server"\fP option then
 \fBsmbd\fP will try each in turn till it finds one
 that responds\&. This is useful in case your primary server goes down\&.
 .IP 
+If the \fB"password server"\fP option is set to the character \f(CW*\fP,
+then Samba will attempt to auto-locate the Primary or Backup Domain controllers
+to authenticate against by doing a query for the name \f(CWWORKGROUP<1C>\fP
+and then contacting each server returned in the list of IP addresses
+from the \fBname resolution\fP source\&.
+.IP 
 If the \fB"security"\fP parameter is set to
 \fB"server"\fP, then there are different
 restrictions that \fB"security=domain"\fP
@@ -4316,6 +4572,9 @@ See also the \fB"security"\fP parameter\&.
 \fBExample:\fP
 \f(CW  password server = NT-PDC, NT-BDC1, NT-BDC2\fP
 .IP 
+\fBExample:\fP
+\f(CW  password server = *\fP
+.IP 
 .IP "\fBpath (S)\fP" 
 .IP 
 This parameter specifies a directory to which the user of the service
@@ -4397,7 +4656,7 @@ time they log in\&. Maybe a message of the day? Here is an example:
 .IP 
 Of course, this could get annoying after a while :-)
 .IP 
-See also \fBpostexec\fP\&.
+See also \fBpreexec close\fP and \fBpostexec\fP\&.
 .IP 
 \fBDefault:\fP
 \f(CW  none (no command executed)\fP
@@ -4405,6 +4664,17 @@ See also \fBpostexec\fP\&.
 \fBExample:\fP
 \f(CW        preexec = echo \e"%u connected to %S from %m (%I)\e" >> /tmp/log\fP
 .IP 
+.IP "\fBpreexec close (S)\fP" 
+.IP 
+This boolean option controls whether a non-zero return code from
+\fB"preexec"\fP should close the service being connected to\&.
+.IP 
+\fBDefault:\fP
+\f(CW  preexec close = no\fP
+.IP 
+\fBExample:\fP
+\f(CW  preexec close = yes\fP
+.IP 
 .IP "\fBpreferred master (G)\fP" 
 .IP 
 This boolean parameter controls if \fBnmbd\fP is a
@@ -4415,8 +4685,7 @@ force an election, and it will have a slight advantage in winning the
 election\&.  It is recommended that this parameter is used in
 conjunction with \fB"domain master = yes"\fP, so
 that \fBnmbd\fP can guarantee becoming a domain
-master\&. Indeed the default ("auto") enables "preferred master" if
-Samba is configured as the domain master browser\&.
+master\&.
 .IP 
 Use this option with caution, because if there are several hosts
 (whether Samba servers, Windows 95 or NT) that are preferred master
@@ -4428,7 +4697,7 @@ capabilities\&.
 See also \fBos level\fP\&.
 .IP 
 \fBDefault:\fP
-\f(CW  preferred master = auto\fP
+\f(CW  preferred master = no\fP
 .IP 
 \fBExample:\fP
 \f(CW  preferred master = yes\fP
@@ -4648,7 +4917,7 @@ find the printer driver files for the automatic installation of
 drivers for Windows 95 machines\&. If Samba is set up to serve printer
 drivers to Windows 95 machines, this should be set to
 .IP 
-\f(CW\e\eMACHINE\ePRINTER$\fP
+\f(CW\e\eMACHINE\eaPRINTER$\fP
 .IP 
 Where MACHINE is the NetBIOS name of your Samba server, and PRINTER$
 is a share you set up for serving printer driver files\&. For more
@@ -4859,14 +5128,14 @@ This overlapping works best when the speeds of disk and network access
 are similar, having very little effect when the speed of one is much
 greater than the other\&.
 .IP 
-The default value is 2048, but very little experimentation has been
+The default value is 16384, but very little experimentation has been
 done yet to determine the optimal value, and it is likely that the
 best value will vary greatly between systems anyway\&. A value over
 65536 is pointless and will cause you to allocate memory
 unnecessarily\&.
 .IP 
 \fBDefault:\fP
-\f(CW  read size = 2048\fP
+\f(CW  read size = 16384\fP
 .IP 
 \fBExample:\fP
 \f(CW  read size = 8192\fP
@@ -4938,6 +5207,37 @@ master on it\'s segment\&.
 \fBExample:\fP
 \f(CW  remote browse sync = 192\&.168\&.2\&.255 192\&.168\&.4\&.255\fP
 .IP 
+.IP "\fBrestrict anonymous (G)\fP" 
+.IP 
+This is a boolean parameter\&.  If it is true, then anonymous access
+to the server will be restricted, namely in the case where the server
+is expecting the client to send a username, but it doesn\'t\&.  Setting
+it to true will force these anonymous connections to be denied, and
+the client will be required to always supply a username and password
+when connecting\&. Use of this parameter is only recommened for homogenous 
+NT client environments\&.
+.IP 
+This parameter makes the use of macro expansions that rely
+on the username (%U, %G, etc) consistant\&.  NT 4\&.0 likes to use
+anonymous connections when refreshing the share list, and this
+is a way to work around that\&.
+.IP 
+When restrict anonymous is true, all anonymous connections are denied
+no matter what they are for\&.  This can effect the ability of a machine
+to access the samba Primary Domain Controller to revalidate it\'s machine
+account after someone else has logged on the client interactively\&.  The
+NT client will display a message saying that the machine\'s account in 
+the domain doesn\'t exist or the password is bad\&.  The best way to deal 
+with this is to reboot NT client machines between interactive logons, 
+using "Shutdown and Restart", rather than "Close all programs and logon 
+as a different user"\&.
+.IP 
+\fBDefault:\fP
+\f(CW     restrict anonymous = false\fP
+.IP 
+\fBExample:\fP
+\f(CW     restrict anonymous = true\fP
+.IP 
 .IP "\fBrevalidate (S)\fP" 
 .IP 
 Note that this option only works with
@@ -5008,7 +5308,15 @@ This is the same as the \fB"preexec"\fP parameter except
 that the command is run as root\&. This is useful for mounting
 filesystems (such as cdroms) before a connection is finalized\&.
 .IP 
-See also \fB"preexec"\fP\&.
+See also \fB"preexec"\fP
+and \fB"root preexec close"\fP\&.
+.IP 
+.IP "\fBroot preexec close (S)\fP" 
+.IP 
+This is the same as the \fB"preexec close"\fP parameter
+except that the command is run as root\&.
+.IP 
+See also \fB"preexec"\fP, \fB"preexec close"\fP\&.
 .IP 
 .IP "\fBsecurity (G)\fP" 
 .IP 
@@ -5208,7 +5516,7 @@ users into the \fB"guest account"\fP\&. See the
 \fB"map to guest"\fP parameter for details on
 doing this\&.
 .IP 
-e,(BUG:) There is currently a bug in the implementation of
+\fIBUG:\fP There is currently a bug in the implementation of
 \fB"security=domain\fP with respect to multi-byte character
 set usernames\&. The communication with a Domain Controller
 must be done in UNICODE and Samba currently does not widen
@@ -5229,6 +5537,38 @@ and the \fB"encrypted passwords"\fP parameter\&.
 \fBExample:\fP
 \f(CW  security = DOMAIN\fP
 .IP 
+.IP "\fBsecurity mask (S)\fP" 
+.IP 
+This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+file using the native NT security dialog box\&.
+.IP 
+This parameter is applied as a mask (AND\'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified\&. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change\&.
+.IP 
+If not set explicitly this parameter is set to the same value as the
+\fBcreate mask\fP parameter\&. To allow a user to
+modify all the user/group/world permissions on a file, set this
+parameter to 0777\&.
+.IP 
+\fINote\fP that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems\&.  Administrators of
+most normal systems will probably want to set it to 0777\&.
+.IP 
+See also the \fBforce directory security
+mode\fP, \fBdirectory security
+mask\fP, \fBforce security
+mode\fP parameters\&.
+.IP 
+\fBDefault:\fP
+\f(CW  security mask = <same as create mask>\fP
+.IP 
+\fBExample:\fP
+\f(CW  security mask = 0777\fP
+.IP 
 .IP "\fBserver string (G)\fP" 
 .IP 
 This controls what string will show up in the printer comment box in
@@ -5294,13 +5634,16 @@ users reporting strange problems trying to save files (locking errors)
 and error messages in the smbd log looking like \f(CW"ERROR
 smb_shm_alloc : alloc of XX bytes failed"\fP\&.
 .IP 
+If your OS refuses the size that Samba asks for then Samba will try a
+smaller size, reducing by a factor of 0\&.8 until the OS accepts it\&.
+.IP 
 \fBDefault:\fP
 \f(CW  shared mem size = 1048576\fP
 .IP 
 \fBExample:\fP
 \f(CW  shared mem size = 5242880 ; Set to 5mb for a large number of files\&.\fP
 .IP 
-.IP "\fBshort preserve case (S)\fP" 
+.IP "\fBshort preserve case (G)\fP" 
 .IP 
 This boolean parameter controls if new files which conform to 8\&.3
 syntax, that is all in upper case and of suitable length, are created
@@ -5796,9 +6139,12 @@ See also the \fB"strict sync"\fP parameter\&.
 This parameter maps how Samba debug messages are logged onto the
 system syslog logging levels\&. Samba debug level zero maps onto syslog
 LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-to LOG_NOTICE, debug level three maps onto LOG_INFO\&.  The parameter
-sets the threshold for doing the mapping, all Samba debug messages
-above this threshold are mapped to syslog LOG_DEBUG messages\&.
+onto LOG_NOTICE, debug level three maps onto LOG_INFO\&. All higher 
+levels are mapped to LOG_DEBUG\&.
+.IP 
+This paramter sets the threshold for sending messages to syslog\&. 
+Only messages with debug level less than this value will be sent 
+to syslog\&.
 .IP 
 \fBDefault:\fP
 \f(CW  syslog = 1\fP
@@ -6031,17 +6377,6 @@ Windows machines to those that the UNIX box uses\&. The other is to map
 multiple users to a single username so that they can more easily share
 files\&.
 .IP 
-The use of this option, therefore, relates to UNIX usernames
-and not Windows (specifically NT Domain) usernames\&.  In other words,
-once a name has been mapped using this option, the Samba server uses
-the mapped name for internal \fIAND\fP external purposes\&.
-.IP 
-This option is \fIDIFFERENT\fP from the \fB"domain user map"\fP 
-parameter, which maintains a one-to-one mapping between UNIX usernames
-and NT Domain Usernames: more specifically, the Samba server maintains
-a link between \fIBOTH\fP usernames, presenting the NT username to the
-external NT world, and using the UNIX username internally\&.
-.IP 
 The map file is parsed line by line\&. Each line should contain a single
 UNIX username on the left then a \f(CW\'=\'\fP followed by a list of
 usernames on the right\&. The list of usernames on the right may contain
@@ -6315,6 +6650,10 @@ directory tree exported by the server are always allowed; this
 parameter controls access only to areas that are outside the directory
 tree being exported\&.
 .IP 
+Note that setting this parameter can have a negative effect on your
+server performance due to the extra system calls that Samba has to
+do in order to perform the link checks\&.
+.IP 
 \fBDefault:\fP
 \f(CW  wide links = yes\fP
 .IP 
@@ -6335,7 +6674,7 @@ need to set this to \f(CW"yes"\fP for some older clients\&.
 This specifies the IP address (or DNS name: IP address for preference)
 of the WINS server that \fBnmbd\fP should register with\&.
 If you have a WINS server on your network then you should set this to
-the WINS server\'s IP\&.
+the WINS server\'s IP\&.        
 .IP 
 You should point this at your WINS server if you have a
 multi-subnetted network\&.
@@ -6352,6 +6691,41 @@ Samba source distribution\&.
 \fBExample:\fP
 \f(CW  wins server = 192\&.9\&.200\&.1\fP
 .IP 
+.IP "\fBwins hook (G)\fP" 
+.IP 
+When Samba is running as a WINS server this allows you to call an
+external program for all changes to the WINS database\&. The primary use
+for this option is to allow the dynamic update of external name
+resolution databases such as dynamic DNS\&.
+.IP 
+The wins hook parameter specifies the name of a script or executable
+that will be called as follows:
+.IP 
+wins_hook operation name nametype ttl IP_list
+.IP 
+The first argument is the operation and is one of "add", "delete",
+or "refresh"\&. In most cases the operation can be ignored as the rest
+of the parameters provide sufficient information\&. Note that "refresh"
+may sometimes be called when the name has not previously been added,
+in that case it should be treated as an add\&.
+.IP 
+The second argument is the netbios name\&. If the name is not a legal
+name then the wins hook is not called\&. Legal names contain only
+letters, digits, hyphens, underscores and periods\&.
+.IP 
+The third argument is the netbios name type as a 2 digit hexadecimal
+number\&. 
+.IP 
+The fourth argument is the TTL (time to live) for the name in seconds\&.
+.IP 
+The fifth and subsequent arguments are the IP addresses currently
+registered for that name\&. If this list is empty then the name should
+be deleted\&.
+.IP 
+An example script that calls the BIND dynamic DNS update program
+"nsupdate" is provided in the examples directory of the Samba source
+code\&. 
+.IP 
 .IP "\fBwins support (G)\fP" 
 .IP 
 This boolean controls if the \fBnmbd\fP process in
@@ -6380,7 +6754,6 @@ workgroup = MYGROUP
 .IP "\fBwritable (S)\fP" 
 .IP 
 Synonym for \fB"writeable"\fP for people who can\'t spell :-)\&.
-Pronounced "ritter-bull"\&.
 .IP 
 .IP "\fBwrite list (S)\fP" 
 .IP 
@@ -6441,51 +6814,52 @@ permitting), but only via spooling operations\&.
  
 
 .IP 
+.PP 
 .SH "WARNINGS" 
-.I
+.P
 Although the configuration file permits service names to contain
 spaces, your client software may not\&. Spaces will be ignored in
 comparisons anyway, so it shouldn\'t be a problem - but be aware of the
 possibility\&.
-.I
+.P
 On a similar note, many clients - especially DOS clients - limit
 service names to eight characters\&. \fBSmbd\fP has no
 such limitation, but attempts to connect from such clients will fail
 if they truncate the service names\&.  For this reason you should
 probably keep your service names down to eight characters in length\&.
-.I
+.P
 Use of the \fB[homes]\fP and \fB[printers]\fP
 special sections make life for an administrator easy, but the various
 combinations of default attributes can be tricky\&. Take extreme care
 when designing these sections\&. In particular, ensure that the
 permissions on spool directories are correct\&.
-.I
+.P
 .SH "VERSION" 
-.I
+.P
 This man page is correct for version 2\&.0 of the Samba suite\&.
-.I
+.P
 .SH "SEE ALSO" 
-.I
+.P
 \fBsmbd (8)\fP, \fBsmbclient (1)\fP,
 \fBnmbd (8)\fP, \fBtestparm (1)\fP,
 \fBtestprns (1)\fP, \fBSamba\fP,
 \fBnmblookup (1)\fP, \fBsmbpasswd (5)\fP,
 \fBsmbpasswd (8)\fP\&.
-.I
+.P
 .SH "AUTHOR" 
-.I
+.P
 The original Samba software and related utilities were created by
 Andrew Tridgell \fIsamba-bugs@samba\&.org\fP\&. Samba is now developed
 by the Samba Team as an Open Source project similar to the way the
 Linux kernel is developed\&.
-.I
+.P
 The original Samba man pages were written by Karl Auer\&. The man page
 sources were converted to YODL format (another excellent piece of Open
 Source software, available at
 \fBftp://ftp\&.icce\&.rug\&.nl/pub/unix/\fP)
 and updated for the Samba2\&.0 release by Jeremy Allison\&.
 \fIsamba-bugs@samba\&.org\fP\&.
-.I
+.P
 See \fBsamba (7)\fP to find out how to get a full
 list of contributors and details on how to submit bug reports,
 comments etc\&.
index 6d93c3cd51e2adcf26dfd50801f4de30fb00579a..4346629adbd7abd1bd0ca82a7e3fb0fa5b2861e9 100644 (file)
@@ -5,7 +5,7 @@ smbclient \- ftp-like client to access SMB/CIFS resources on servers
 .PP 
 .SH "SYNOPSIS" 
 .PP 
-\fBsmbclient\fP servicename [password] [-s smb\&.conf] [-B IP addr] [-O socket options][-R name resolve order] [-M NetBIOS name] [-i scope] [-N] [-n NetBIOS name] [-d debuglevel] [-P] [-p port] [-l log basename] [-h] [-I dest IP] [-E] [-U username] [-L NetBIOS name] [-t terminal code] [-m max protocol] [-W workgroup] [-T<c|x>IXFqgbNan] [-D directory] [-c command string]
+\fBsmbclient\fP servicename [-s smb\&.conf] [-O socket options][-R name resolve order] [-M NetBIOS name] [-i scope] [-N] [-n NetBIOS name] [-d debuglevel] [-P] [-p port] [-l log basename] [-h] [-I dest IP] [-E] [-U username] [-L NetBIOS name] [-t terminal code] [-m max protocol] [-b buffersize] [-W workgroup] [-T<c|x>IXFqgbNan] [-D directory] [-c command string]
 .PP 
 .SH "DESCRIPTION" 
 .PP 
@@ -65,9 +65,6 @@ Samba configuration file, smb\&.conf\&. This file controls all aspects of
 the Samba setup on the machine and smbclient also needs to read this
 file\&.
 .IP 
-.IP "\fB-B IP addr\fP" 
-The IP address to use when sending a broadcast packet\&.
-.IP 
 .IP "\fB-O socket options\fP" 
 TCP socket options to set on the client
 socket\&. See the socket options
@@ -104,8 +101,7 @@ no WINS server has been specified this method will be ignored\&.
 listed in the \fBinterfaces\fP parameter
 in the smb\&.conf file\&. This is the least reliable of the name resolution
 methods as it depends on the target host being on a locally connected
-subnet\&. To specify a particular broadcast address the \fB-B\fP option 
-may be used\&.
+subnet\&. 
 .IP 
 .IP 
 If this parameter is not set then the name resolve order defined
@@ -284,7 +280,7 @@ nothing before or nothing after the percent symbol will cause an empty
 username or an empty password to be used, respectively\&.
 .IP 
 The password may also be specified by setting up an environment
-variable called \f(CWPASSWORD\fP that contains the users password\&. Note
+variable called \f(CWPASSWD\fP that contains the users password\&. Note
 that this may be very insecure on some systems but on others allows
 users to script smbclient commands without having a password appear in
 the command line of a process listing\&.
@@ -294,7 +290,7 @@ on an uppercase password\&. Lowercase or mixed case passwords may be
 rejected by these servers\&.
 .IP 
 Be cautious about including passwords in scripts or in the
-\f(CWPASSWORD\fP environment variable\&. Also, on many systems the command
+\f(CWPASSWD\fP environment variable\&. Also, on many systems the command
 line of a running process may be seen via the \f(CWps\fP command to be
 safe always allow smbclient to prompt for a password and type it in
 directly\&.
@@ -326,6 +322,12 @@ protocols level the server supports\&. This parameter is
 preserved for backwards compatibility, but any string
 following the \fB-m\fP will be ignored\&.
 .IP 
+.IP "\fB-b buffersize\fP" 
+This option changes the transmit/send buffer
+size when getting or putting a file from/to the server\&. The default
+is 65520 bytes\&. Setting this value smaller (to 1200 bytes) has been
+observed to speed up file transfers to and from a Win9x server\&.
+.IP 
 .IP "\fB-W WORKGROUP\fP" 
 Override the default workgroup specified in the
 \fBworkgroup\fP parameter of the
@@ -717,7 +719,7 @@ The variable \fBUSER\fP may contain the username of the person using the
 client\&.  This information is used only if the protocol level is high
 enough to support session-level passwords\&.
 .PP 
-The variable \fBPASSWORD\fP may contain the password of the person using
+The variable \fBPASSWD\fP may contain the password of the person using
 the client\&.  This information is used only if the protocol level is
 high enough to support session-level passwords\&.
 .PP 
index 7e6c03b5ffdc8b54c94ae7c1f483ec0a6db8e793..5efd67947871d4b8382a4e759829c558fa5772f0 100644 (file)
@@ -5,7 +5,7 @@ smbd \- server to provide SMB/CIFS services to clients
 .PP 
 .SH "SYNOPSIS" 
 .PP 
-\fBsmbd\fP [-D] [-a] [-o] [-d debuglevel] [-l log file] [-p port number] [-O socket options] [-s configuration file] [-i scope] [-P] [-h]
+\fBsmbd\fP [-D] [-a] [-o] [-P] [-h] [-V] [-d debuglevel] [-l log file] [-p port number] [-O socket options] [-s configuration file] [-i scope]
 .PP 
 .SH "DESCRIPTION" 
 .PP 
@@ -65,6 +65,16 @@ If this parameter is specified, the log files will be
 overwritten when opened\&.  By default, the log files will be appended
 to\&.
 .IP 
+.IP "\fB-P\fP" 
+Passive option\&. Causes smbd not to send any network traffic
+out\&. Used for debugging by the developers only\&.
+.IP 
+.IP "\fB-h\fP" 
+Prints the help information (usage) for \fBsmbd\fP\&.
+.IP 
+.IP "\fB-V\fP" 
+Prints the version number for \fBsmbd\fP\&.
+.IP 
 .IP "\fB-d debuglevel\fP" 
 debuglevel is an integer from 0 to 10\&.
 .IP 
@@ -135,13 +145,6 @@ are \fIvery\fP rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with\&.
 .IP 
-.IP "\fB-h\fP" 
-Prints the help information (usage) for smbd\&.
-.IP 
-.IP "\fB-P\fP" 
-Passive option\&. Causes smbd not to send any network traffic
-out\&. Used for debugging by the developers only\&.
-.IP 
 .PP 
 .SH "FILES" 
 .PP 
@@ -409,16 +412,11 @@ performance\&.
 .PP 
 .SH "SEE ALSO" 
 .PP 
-\fBhosts_access (5)\fP,
-\fBinetd (8)\fP,
-\fBnmbd (8)\fP,
-\fBsmb\&.conf (5)\fP,
-\fBsmbclient (1)\fP,
-\fBtestparm (1)\fP,
-\fBtestprns (1)\fP,
-\fBrpcclient (1)\fP,
-and the Internet RFC\'s \fBrfc1001\&.txt\fP, \fBrfc1002\&.txt\fP\&.
-In addition the CIFS (formerly SMB)
+\fBhosts_access (5)\fP, \fBinetd (8)\fP, \fBnmbd (8)\fP,
+\fBsmb\&.conf (5)\fP, \fBsmbclient
+(1)\fP, \fBtestparm (1)\fP,
+\fBtestprns (1)\fP, and the Internet RFC\'s
+\fBrfc1001\&.txt\fP, \fBrfc1002\&.txt\fP\&. In addition the CIFS (formerly SMB)
 specification is available as a link from the Web page :
 http://samba\&.org/cifs/\&.
 .PP 
index e0db6edae3d7916ea020b76a0097649121f82f6a..e8cc1f2cd9cc1651e41745bbbf31d83ba4c5b0c2 100644 (file)
@@ -1,96 +1,37 @@
-.TH SMBMNT 8 "13 Nov 1998" "smbmnt 2.0.0-beta1"
-.SH NAME
-smbmnt \- mount smb file system
-.SH SYNOPSIS
-.B smbmnt
-.B mount-point
-[
-.B -u
-.I uid
-] [
-.B -g
-.I gid
-] [
-.B -f
-.I file mode
-] [
-.B -d
-.I dir mode
-]
-
-.SH DESCRIPTION
-.B smbmnt 
-is a helper application used by the 
-.BI smbmount (8)
-program to do the actual mounting.
-.B smbmnt
-is meant to be installed setuid root so that normal users can mount
-their smb shares. It checks whether the user has write permissions
-on the mount point and then mounts the directory.
-
-The
-.B smbmnt
-program is normally invoked by a mount command to
-.BI smbmount ,
-and the command line arguments are passed directly to
-.B smbmnt.
-
-.SH OPTIONS
-.B -u
-.I uid,
-.B -g
-.I gid
-.RS 3
-A Lan Manager server does not tell us anything about the owner of a
-file, but Unix requires that each file have an owner and a group it belongs
-to. With 
-.B -u
-and
-.B -g
-you can tell smbmount which id's it should assign to the files in the
-mounted directory.
-
-The defaults for these values are the current uid and gid.
-.RE
-
-.B -f
-.I file mode,
-.B -d
-.I dir mode
-.RS 3
-Like 
-.B -u
-and
-.B -g,
-these options are also used to bridge differences in concepts between
-Lan Manager and Unix. Lan Manager does not know anything about file
-permissions, so
-.B smbmnt
-must be told which permissions it should assign to the mounted files
-and directories.
-
-The values must be given as octal numbers. The default values are taken
-from the current umask, where the file mode is the current umask,
-and the dir mode adds execute permissions where the file mode gives
-read permissions.
-
-Note that these permissions can differ from the rights the server
-gives to us. If you do not have write permissions on the server,
-you should choose a file mode that matches your actual permissions.
-This certainly cannot override the restrictions imposed by the server.
-
-In addition to specifying the file mode, the
-.B -f
-argument can be used to specify certain bug-fix workarounds.
-This allows bug fixes to be enabled on a per mount-point basis,
-rather than being compiled into the kernel.
-The required bug fixes are specified by prepending an (octal) value
-to the file mode.
-For information on the available bug workarounds, refer to the
-.B smbfs.txt
-file in the Linux kernel Documentation directory. 
-.RE
-
-.SH SEE ALSO
-.B smbmount(8)
-
+.TH "smbmnt " "1" "25 September 1999" "Samba" "SAMBA" 
+.PP 
+.SH "NAME" 
+smbmnt \- helper utility for mounting SMB filesystems
+.PP 
+.SH "SYNOPSIS" 
+\fBsmbmnt\fP mount-point [ -s share ] [ -r ] [ -u uid ] [ -g gid ] [ -f mask ] [ -d mask ] 
+.PP 
+.SH "DESCRIPTION" 
+.PP 
+smbmnt is a helper application used by the smbmount program to do the
+actual mounting of SMB shares\&. smbmnt is meant to be installed setuid
+root so that normal users can mount their smb shares\&. It checks
+whether the user has write permissions on the mount point and then
+mounts the directory\&.
+.PP 
+The smbmnt program is normally invoked by smbmount\&. It should not be
+invoked directly by users\&.
+.PP 
+.IP "\fB-r\fP" 
+mount the filesystem read-only
+.PP 
+.IP "\fB-u uid\fP" 
+specify the uid that the files will be owned by
+.PP 
+.IP "\fB-g gid\fP" 
+specify the gid that the files will be owned by
+.PP 
+.IP "\fB-f mask\fP" 
+specify the octal file mask applied 
+.PP 
+.IP "\fB-d mask\fP" 
+specify the octal directory mask applied 
+.PP 
+.SH "AUTHOR" 
+The maintainer of smbfs, smbmnt and smbmount is Andrew Tridgell
+\fItridge@samba\&.org\fP
index 4ac7267395b76dd4bfee231ed2b1d67cf41004a5..457a940ddba92889f861292e5271ab31014bf034 100644 (file)
@@ -1,44 +1,87 @@
-.TH SMBMOUNT 8 "13 Nov 1998" "smbmount 2.0.0-beta1"
-.SH NAME
-smbmount \- mount smb file system
-.SH SYNOPSIS
-.B smbmount
-[
-.B options
-]
-
-.SH DESCRIPTION
-.B smbmount 
-is a stripped-down version of the 
-.BI smbclient (1)
-program used to mount smbfs shares. It implements only the mount command,
-which then calls the
-.BI smbmnt (8)
-program to do the actual mount.
-.B smbmount
-itself accepts most of the options that
-.B smbclient
-does. See the
-.BI smbclient (1)
-manpage for details.
-
-To mount an smb file system, I suggest using the option
-.B -c
-for smbmount to pass the mount command. For example, use
-
-smbmount '\\\\server\\tmp' -c 'mount /mnt -u 123 -g 456'
-
-to mount the tmp share of server on /mnt, giving it a local uid 123
-and a local gid 456.
-
-The arguments supplied to the mount command are passed directly to the
-.B smbmnt
-utility for processing.
-Refer to the
-.BI smbmnt (8)
-manpage for details.
-
-.SH SEE ALSO
-.BI smbmnt (8),
-.BI smbclient (1)
-
+.TH "smbmount " "1" "25 September 1999" "Samba" "SAMBA" 
+.PP 
+.SH "NAME" 
+smbmount \- mount an SMB filesystem
+.PP 
+.SH "SYNOPSIS" 
+\fBsmbmount\fP service mountpoint [ -o options ]
+.PP 
+.SH "DESCRIPTION" 
+.PP 
+smbmount mounts a SMB filesystem\&. It is usually invoked as mount\&.smb
+from the mount(8) command when using the "-t smb" option\&. The kernel
+must support the smbfs filesystem\&.
+.PP 
+Options to smbmount are specified as a comma separated list of
+key=value pairs\&. 
+.PP 
+NOTE: smbmount calls smbmnt to do the actual mount\&. You must make sure
+that smbmnt is in the path so that it can be found\&.
+.PP 
+.IP "\fBusername=<arg>\fP" 
+specifies the username to connect as\&. If this is
+not given then the environment variable USER is used\&. This option can
+also take the form user%password or user/workgroup or
+user/workgroup%password to allow the password and workgroup to be
+specified as part of the username\&.
+.IP 
+.IP "\fBpassword=<arg>\fP" 
+specifies the SMB password\&. If not given then
+smbmount will prompt for a passeword, unless the guest option is
+given\&.
+.IP 
+.IP "\fBnetbiosname=<arg>\fP" 
+sets the source NetBIOS name\&. It defaults to
+the local hostname\&.
+.IP 
+.IP "\fBuid=<arg>\fP" 
+sets the uid that files will be mounted as\&. It may be
+specified as either a username or a numeric uid\&.
+.IP 
+.IP "\fBgid=<arg>\fP" 
+sets the gid that files will be mounted as\&. It may be
+specified as either a groupname or a numeric gid\&.
+.IP 
+.IP "\fBport=<arg>\fP" 
+sets the remote SMB port number\&. The default is 139\&.
+.IP 
+.IP "\fBfmask=<arg>\fP" 
+sets the file mask\&. This deterines the permissions
+that remote files have in the local filesystem\&. The default is based
+on the current umask\&.
+.IP 
+.IP "\fBdmask=<arg>\fP" 
+sets the directory mask\&. This deterines the
+permissions that remote directories have in the local filesystem\&. The
+default is based on the current umask\&.
+.IP 
+.IP "\fBdebug=<arg>\fP" 
+sets the debug level\&. This is useful for tracking
+down SMB connection problems\&.
+.IP 
+.IP "\fBip=<arg>\fP" 
+sets the destination host or IP address\&.
+.IP 
+.IP "\fBworkgroup=<arg>\fP" 
+sets the workgroup on the destination
+.IP 
+.IP "\fBsockopt=<arg>\fP" 
+sets the TCP socket options\&. See the smb\&.conf
+"socket options" option\&.
+.IP 
+.IP "\fBscope=<arg>\fP" 
+sets the NetBIOS scope
+.IP 
+.IP "\fBguest\fP" 
+don\'t prompt for a password
+.IP 
+.IP "\fBro\fP" 
+mount read-only
+.IP 
+.IP "\fBrw\fP" 
+mount read-write
+.IP 
+.PP 
+.SH "AUTHOR" 
+The maintainer of smbfs, smbmnt and smbmount is Andrew Tridgell
+\fItridge@samba\&.org\fP
index 9013987b3f1f0a7fbabd840abef1ee8e58cb4ea0..7899344d7fbb90388302004f60360cfb5fb9033c 100644 (file)
@@ -18,7 +18,7 @@ connections\&.
 .PP 
 .IP 
 .IP "\fB-P\fP" 
-If samba has been compiled with the profiling option, 
+If samba has been compiled with the profiling option,
 print only the contents of the profiling shared memory area\&.
 .IP 
 .IP "\fB-b\fP" 
index 4f9c6cbedbb222d1a8082f8b5306121e32977a65..724684a2214b61574d1688ddbb39b3394b640f01 100644 (file)
@@ -1,4 +1,4 @@
-.TH SMBUMOUNT 8 "13 Nov 1998" "smbumount 2.0.0-beta1"
+.TH SMBUMOUNT 8 "18 May 1999" "smbumount 2.0.4"
 .SH NAME
 smbumount \- umount for normal users
 .SH SYNOPSIS
index a9e876aaf292660d8bbaf2c39084f5900c0ba27e..8798c0a566e32360b9fbc825d3d4b184f1c5a856 100644 (file)
@@ -1,7 +1,7 @@
 .TH "swat " "8" "23 Oct 1998" "Samba" "SAMBA" 
 .PP 
 .SH "NAME" 
-swat \- swat - Samba Web Administration Tool
+swat \- Samba Web Administration Tool
 .PP 
 .SH "SYNOPSIS" 
 .PP 
index b75590aa9ad8ecd85973af50894907a6b84fcbbb..2d4c03a1641e383ebbf3a4b6b00e2358ef256af6 100644 (file)
@@ -5,7 +5,7 @@ testparm \- check an smb\&.conf configuration file for internal correctness
 .PP 
 .SH "SYNOPSIS" 
 .PP 
-\fBtestparm\fP [-s] [configfilename] [hostname hostIP]
+\fBtestparm\fP [-s] [-h] [-L servername] [configfilename] [hostname hostIP]
 .PP 
 .SH "DESCRIPTION" 
 .PP 
@@ -24,6 +24,11 @@ If the optional host name and host IP address are specified on the
 command line, this test program will run through the service entries
 reporting whether the specified host has access to each service\&.
 .PP 
+If \fBtestparm\fP finds an error in the \fBsmb\&.conf\fP
+file it returns an exit code of 1 to the calling program, else it returns
+an exit code of 0\&. This allows shell scripts to test the output from
+\fBtestparm\fP\&.
+.PP 
 .SH "OPTIONS" 
 .PP 
 .IP 
@@ -32,6 +37,13 @@ Without this option, \fBtestparm\fP will prompt for a
 carriage return after printing the service names and before dumping
 the service definitions\&.
 .IP 
+.IP "\fB-h\fP" 
+Print usage message
+.IP 
+.IP "\fB-L servername\fP" 
+Sets the value of the %L macro to servername\&. This
+is useful for testing include files specified with the %L macro\&.
+.IP 
 .IP "\fBconfigfilename\fP" 
 This is the name of the configuration file to
 check\&. If this parameter is not present then the default
index c69add4d8edf2c61720571c81aa7171deb5b63a8..fa10333683a6b9e5141c7e31726b0c2594cf3160 100644 (file)
@@ -1,14 +1,14 @@
 Begin2
 Title        = Samba
-Version      = 2.0
+Version      = 1.8.0
 Desc1        = Samba is a SMB based file and print server for unix. It
 Desc2        = provides access to unix file and print services from
 Desc3        = SMB compatible clients such as WinNT, WfWg, OS/2
 Desc4        = and Pathworks. It also includes a ftp-style unix client
 Desc5        = and a netbios nameserver.
-Author       = Samba Team
+Author       = Andrew Tridgell
 AuthorEmail  = samba-bugs@samba.org
-Maintainer   = Samba Team
+Maintainer   = Andrew Tridgell
 MaintEmail   = samba-bugs@samba.org
 Site1        = samba.org
 Path1        = pub/samba/
@@ -18,8 +18,9 @@ Required1    = Ansi-C compiler and a TCP/IP network.
 CopyPolicy1  = GNU Public License
 Keywords     = LanManager, SMB, Networking
 Comment1     = To join the Samba mailing list send mail to 
-Comment2     = listproc@samba.org with a body of
+Comment2     = listproc@listproc.anu.edu.au with a body of
 Comment3     = "subscribe samba Your Name"
-Entered      = November 1998
+Entered      = October 1994
 EnteredBy    = Andrew Tridgell
 End
+
index 0149b17e6d91fff9dec0f2fd9a62261d9a440d09..be07cfe0621711b97cd081570742d89190573f8a 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Application_Serving.txt for Samba release 2.1.0prealpha 981204
+!== Application_Serving.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributed:   January 7, 1997
 Updated:       March 24, 1998
index 2811f026596155b3cc9a66b387e6761d0c3a7b7c..a27cf7401dc5e8d5c069cc75c52e93d43ec6bbaf 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== BROWSING-Config.txt for Samba release 2.1.0prealpha 981204
+!== BROWSING-Config.txt for Samba release 2.0.4 18 May 1999
 !==
 Date:          July 5, 1998
 Contributor:   John H Terpstra <jht@samba.org>
index 2ed2369f08200a1070584f2f4f40c46f33540c07..ae18382bd917b8b3aa31026dfb1d4c3b42d2eb6c 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== BROWSING.txt for Samba release 2.1.0prealpha 981204
+!== BROWSING.txt for Samba release 2.0.4 18 May 1999
 !==
 Author/s:      Many (Thanks to Luke, Jeremy, Andrew, etc.)
 Updated:       July 5, 1998
index db3a5484507f7a5ba184e62ce11886284944921c..14a77f4cb444bd1e7db96ca9c1df8bbe5fc23c6e 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== BUGS.txt for Samba release 2.1.0prealpha 981204
+!== BUGS.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Samba Team
 Updated:       June 27, 1997
index 6fec05eae5491331d9dc551e6b5a345f6e054d75..c854d3fe33ebab02fe7a57e99960096ef3c6bb74 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== CVS_ACCESS.txt for Samba release 2.1.0prealpha 981204
+!== CVS_ACCESS.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:    Modified from the Web pages by Jeremy Allison.
 Date:           23 Dec 1997
index 52ecf2d9b002514792799d8a3b0e3d6b211bf4ed..72afd85e59438178767f69d2372af908bc2012aa 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== DHCP-Server-Configuration.txt for Samba release 2.1.0prealpha 981204
+!== DHCP-Server-Configuration.txt for Samba release 2.0.4 18 May 1999
 !==
 Subject:       DHCP Server Configuration for SMB Clients
 Date:          March 1, 1998
index e490fb81ebbc5d57bb34af1f88746c375e4419f3..ce514004643f8c34c5c91a679a27402d2b8ef254 100644 (file)
@@ -1,8 +1,8 @@
 !==
-!== DIAGNOSIS.txt for Samba release 2.1.0prealpha 981204
+!== DIAGNOSIS.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Andrew Tridgell
-Updated:       October 14, 1997
+Updated:       November 1, 1999
 
 Subject:       DIAGNOSING YOUR SAMBA SERVER
 ===========================================================================
@@ -16,9 +16,6 @@ You should do ALL the tests, in the order shown. I have tried to
 carefully choose them so later tests only use capabilities verified in
 the earlier tests.
 
-I would welcome additions to this set of tests. Please mail them to
-samba-bugs@samba.org
-
 If you send me an email saying "it doesn't work" and you have not
 followed this test procedure then you should not be surprised if I
 ignore your email.
@@ -28,9 +25,10 @@ ASSUMPTIONS
 -----------
 
 In all of the tests I assume you have a Samba server called BIGSERVER
-and a PC called ACLIENT. I also assume the PC is running windows for
-workgroups with a recent copy of the microsoft tcp/ip stack. Alternatively,
-your PC may be running Windows 95 or Windows NT (Workstation or Server).
+and a PC called ACLIENT both in workgroup TESTGROUP. I also assume the
+PC is running windows for workgroups with a recent copy of the
+microsoft tcp/ip stack. Alternatively, your PC may be running Windows
+95 or Windows NT (Workstation or Server).
 
 The procedure is similar for other types of clients.
 
@@ -44,7 +42,7 @@ smb.conf. I will assume this share is called "tmp". You can add a
  read only = yes
 
 
-THESE TESTS ASSUME VERSION 1.9.16 OR LATER OF THE SAMBA SUITE. SOME
+THESE TESTS ASSUME VERSION 2.0.6 OR LATER OF THE SAMBA SUITE. SOME
 COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS
 
 Please pay attention to the error messages you receive. If any error message
@@ -102,7 +100,7 @@ valid. Check what your guest account is using "testparm" and
 temporarily remove any "hosts allow", "hosts deny", "valid users" or
 "invalid users" lines.
 
-If you get a "connection refused" response then the smbd server could
+If you get a "connection refused" response then the smbd server may
 not be running. If you installed it in inetd.conf then you probably edited
 that file incorrectly. If you installed it as a daemon then check that
 it is running, and check that the netbios-ssn port is in a LISTEN
@@ -170,6 +168,9 @@ You should get the PCs IP address back. If you don't then the client
 software on the PC isn't installed correctly, or isn't started, or you
 got the name of the PC wrong. 
 
+If ACLIENT doesn't resolve via DNS then use the IP address of the
+client in the above test.
+
 
 TEST 6:
 -------
@@ -199,11 +200,15 @@ not correct. (Refer to TEST 3 notes above).
 TEST 7:
 -------
 
-Run the command "smbclient '\\BIGSERVER\TMP'". You should then be
+Run the command "smbclient //BIGSERVER/TMP". You should then be
 prompted for a password. You should use the password of the account
 you are logged into the unix box with. If you want to test with
-another account then add the -U <accountname> option to the command
-line. 
+another account then add the -U <accountname> option to the end of
+the command line.  eg: smbclient //bigserver/tmp -Ujohndoe
+
+Note: It is possible to specify the password along with the username
+as follows:
+       smbclient //bigserver/tmp -Ujohndoe%secret
 
 Once you enter the password you should get the "smb>" prompt. If you
 don't then look at the error message. If it says "invalid network
@@ -250,6 +255,12 @@ same fixes apply as they did for the "smbclient -L" test above. In
 particular, make sure your "hosts allow" line is correct (see the man
 pages)
 
+Also, do not overlook that fact that when the workstation requests the
+connection to the samba server it will attempt to connect using the 
+name with which you logged onto your Windows machine. You need to make
+sure that an account exists on your Samba server with that exact same
+name and password.
+
 If you get "specified computer is not receiving requests" or similar
 it probably means that the host is not contactable via tcp services.
 Check to see if the host is running tcp wrappers, and if so add an entry in
@@ -271,10 +282,23 @@ USERNAME" to the [tmp] section of smb.conf where "USERNAME" is the
 username corresponding to the password you typed. If you find this
 fixes things you may need the username mapping option.
 
-
 TEST 10:
 --------
 
+Run the command "nmblookup -M TESTGROUP" where TESTGROUP is the name
+of the workgroup that your Samba server and Windows PCs belong to. You
+should get back the IP address of the master browser for that
+workgroup.
+
+If you don't then the election process has failed. Wait a minute to
+see if it is just being slow then try again. If it still fails after
+that then look at the browsing options you have set in smb.conf. Make
+sure you have "preferred master = yes" to ensure that an election is
+held at startup.
+
+TEST 11:
+--------
+
 From file manager try to browse the server. Your samba server should
 appear in the browse list of your local workgroup (or the one you
 specified in smb.conf). You should be able to double click on the name
index 4c1fcbde31a374beae01729f5b9be8dc9ea1ac04..f209f046182d8977c690c48d80cb036303590c4d 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== DNIX.txt for Samba release 2.1.0prealpha 981204
+!== DNIX.txt for Samba release 2.0.4 18 May 1999
 !==
 DNIX has a problem with seteuid() and setegid(). These routines are
 needed for Samba to work correctly, but they were left out of the DNIX
index f5b85ea28fbfaeb45d7a6f84ba9a8fe85ef799d0..d16f3aa55dc78b79e4f526e1906e8cbf5ea1add4 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== DOMAIN.txt for Samba release 2.1.0prealpha 981204
+!== DOMAIN.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Samba Team
 Updated:       December 4, 1998 (John H Terpstra)
index ac3f61850158724003b665208dc5a03fbdf41cf6..dd4afa347598f8933b34232c94b1eb038ccbadf4 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== DOMAIN_CONTROL.txt for Samba release 2.1.0prealpha 981204
+!== DOMAIN_CONTROL.txt for Samba release 2.0.4 18 May 1999
 !==
 Initial Release:       August 22, 1996
 Contributor:           John H Terpstra <samba-bugs@samba.org>
index 3238fde179b0279a14f3b8e5310636c5de605ba9..53fd6d94f94159c066aff1beef1d53a4210d6d7e 100644 (file)
@@ -1,7 +1,7 @@
 
 TITLE INFORMATION: Joining an NT Domain with Samba 2.0 
 AUTHOR INFORMATION: Jeremy Allison, Samba Team 
-DATE INFORMATION: 11th November 1998 
+DATE INFORMATION: 7th October 1999 
 
 Contents 
 
@@ -11,7 +11,8 @@ Joining an NT Domain with Samba 2.0
 In order for a Samba-2 server to join an NT domain, you must first add
 the NetBIOS name of the Samba server to the NT domain on the PDC using
 Server Manager for Domains.  This creates the machine account in the
-domain (PDC) SAM.
+domain (PDC) SAM. Note that you should add the Samba server as a "Windows
+NT Workstation or Server", NOT as a Primary or backup domain controller.
 
 Assume you have a Samba-2 server with a NetBIOS name of SERV1 and are
 joining an NT domain called DOM, which has a PDC with a NetBIOS name
@@ -75,6 +76,10 @@ workgroup = DOM
 
 as this is the name of the domain we are joining. 
 
+You must also have the parameter "encrypt passwords"
+set to "yes" in order for your users to authenticate to the
+NT PDC.
+
 Finally, add (or modify) a:
 
 "password server ="
@@ -89,19 +94,15 @@ each of these servers in order, so you may want to rearrange this list
 in order to spread out the authentication load among domain
 controllers.
 
-Currently, Samba requires that a defined list of domain controllers be
-listed in this parameter in order to authenticate with domain-level
-security. NT does not use this method, and will either broadcast or
-use a WINS database in order to find domain controllers to
-authenticate against.
+Alternatively, if you want smbd to automatically determine the
+list of Domain controllers to use for authentication, you may set this line to be :
 
-Originally, I considered this idea for Samba, but dropped it because
-it seemed so insecure.  However several Samba-2 alpha users have
-requested that this feature be added to make Samba more NT-like, so
-I'll probably add a special name of '*' (which means: act like NT
-when looking for domain controllers) in a future release of the
-code. At present, however, you need to know where your domain
-controllers are.
+password server = *
+
+This method, which is new in Samba 2.0.6 and above, allows Samba
+to use exactly the same mechanism that NT does. This method either broadcasts or
+uses a WINS database in order to find domain controllers to
+authenticate against.
 
 Finally, restart your Samba daemons and get ready for clients to begin
 using domain security!
index ace8ef88bda689750627aa736aa60d2194df1048..89f30b0d53a354408b43b9f53dcffe5900cb4a42 100644 (file)
@@ -1,8 +1,8 @@
 !==
-!== ENCRYPTION.txt for Samba release 2.1.0prealpha 981204
+!== ENCRYPTION.txt for Samba release 2.0.5a 22 Jul 1999
 !==
 Contributor:   Jeremy Allison <samba-bugs@samba.org>
-Updated:       March 19, 1998
+Updated:       April 19, 1999
 Note:          Please refer to WinNT.txt also
 
 Subject:       LanManager / Samba Password Encryption.
@@ -22,7 +22,7 @@ How does it work ?
 
 LanManager encryption is somewhat similar to UNIX password
 encryption. The server uses a file containing a hashed value of a
-users password.  This is created by taking the users plaintext
+user's password.  This is created by taking the user's plaintext
 password, capitalising it, and either truncating to 14 bytes (or
 padding to 14 bytes with null bytes). This 14 byte value is used as
 two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
@@ -30,7 +30,7 @@ two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
 be known as the *hashed password*.
 
 Windows NT encryption is a higher quality mechanism, consisting
-of doing an MD4 hash on a Unicode version of the users password. This
+of doing an MD4 hash on a Unicode version of the user's password. This
 also produces a 16 byte hash value that is non-reversible.
 
 When a client (LanManager, Windows for WorkGroups, Windows 95 or
@@ -51,10 +51,10 @@ In the SMB call SMBsessionsetupX (when user level security is
 selected) or the call SMBtconX (when share level security is selected)
 the 24 byte response is returned by the client to the Samba server.
 For Windows NT protocol levels the above calculation is done on
-both hashes of the users password and both responses are returned
+both hashes of the user's password and both responses are returned
 in the SMB call, giving two 24 byte values.
 
-The Samba server then reproduces the above calculation, using it's own
+The Samba server then reproduces the above calculation, using its own
 stored value of the 16 byte hashed password (read from the smbpasswd
 file - described later) and the challenge value that it kept from the
 negotiate protocol reply. It then checks to see if the 24 byte value it
@@ -62,11 +62,11 @@ calculates matches the 24 byte value returned to it from the client.
 
 If these values match exactly, then the client knew the correct
 password (or the 16 byte hashed value - see security note below) and
-is this allowed access. If not then the client did not know the
+is thus allowed access. If not, then the client did not know the
 correct password and is denied access.
 
 Note that the Samba server never knows or stores the cleartext of the
-users password - just the 16 byte hashed values derived from it. Also
+user's password - just the 16 byte hashed values derived from it. Also
 note that the cleartext password or 16 byte hashed values are never
 transmitted over the network - thus increasing security.
 
@@ -79,7 +79,7 @@ typically sends clear text passwords over the nextwork when logging
 in. This is bad. The SMB encryption scheme never sends the cleartext
 password over the network but it does store the 16 byte hashed values
 on disk. This is also bad. Why? Because the 16 byte hashed values are a
-"password equivalent". You cannot derive the users password from them,
+"password equivalent". You cannot derive the user's password from them,
 but they could potentially be used in a modified client to gain access
 to a server. This would require considerable technical knowledge on
 behalf of the attacker but is perfectly possible. You should thus
@@ -106,7 +106,7 @@ a network sniffer cannot just record passwords going to the SMB server.
 
 - WinNT doesn't like talking to a server that isn't using SMB
 encrypted passwords. It will refuse to browse the server if the server
-is also in user level security mode. It will insist on promting the
+is also in user level security mode. It will insist on prompting the
 user for the password on each connection, which is very annoying. The
 only things you can do to stop this is to use SMB encryption.
 
@@ -135,7 +135,7 @@ The smbpasswd file.
 In order for Samba to participate in the above protocol it must
 be able to look up the 16 byte hashed values given a user name.
 Unfortunately, as the UNIX password value is also a one way hash
-function (ie. it is impossible to retrieve the cleartext of the users
+function (ie. it is impossible to retrieve the cleartext of the user's
 password given the UNIX hash of it) then a separate password file
 containing this 16 byte value must be kept. To minimise problems with
 these two password files, getting out of sync, the UNIX /etc/passwd and
@@ -177,10 +177,11 @@ chmod 600 smbpasswd.
 
 The format of the smbpasswd file is
 
-username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
+username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[Account type]:LCT-<last-change-time>:Long name
 
-Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-sections are significant and are looked at in the Samba code.
+Although only the username, uid, XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
+[Account type] and last-change-time sections are significant and
+are looked at in the Samba code.
 
 It is *VITALLY* important that there by 32 'X' characters between the
 two ':' characters in the XXX sections - the smbpasswd and Samba code 
@@ -192,7 +193,7 @@ When the password file is created all users have password entries
 consisting of 32 'X' characters. By default this disallows any access
 as this user. When a user has a password set, the 'X' characters change
 to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
-representation of the 16 byte hashed value of a users password.
+representation of the 16 byte hashed value of a user's password.
 
 To set a user to have no password (not recommended), edit the file
 using vi, and replace the first 11 characters with the asci text
@@ -202,7 +203,7 @@ NO PASSWORD
 Eg. To clear the password for user bob, his smbpasswd file entry would
 look like :
 
-bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
+bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U          ]:LCT-00000000:Bob's full name:/bobhome:/bobshell
 
 If you are allowing users to use the smbpasswd command to set their own
 passwords, you may want to give users NO PASSWORD initially so they do
@@ -214,7 +215,7 @@ that user with no password. Enable this by adding the line :
 null passwords = true
 
 to the [global] section of the smb.conf file (this is why the
-above scenario is not recommended). Preferebly, allocate your
+above scenario is not recommended). Preferably, allocate your
 users a default password to begin with, so you do not have
 to enable this on your server.
 
@@ -236,16 +237,16 @@ setuid root (the new smbpasswd code enforces this restriction so
 it cannot be run this way by accident).
 
 smbpasswd now works in a client-server mode where it contacts
-the local smbd to change the users password on its behalf. This
+the local smbd to change the user's password on its behalf. This
 has enormous benefits - as follows.
 
-1). smbpasswd no longer has to be setuid root - an enourmous
+1). smbpasswd no longer has to be setuid root - an enormous
 range of potential security problems is eliminated.
 
 2). smbpasswd now has the capability to change passwords
 on Windows NT servers (this only works when the request is
 sent to the NT Primary Domain Controller if you are changing 
-an NT Domain users password).
+an NT Domain user's password).
 
 To run smbpasswd as a normal user just type :
 
@@ -313,7 +314,7 @@ If this fails then you will find that you will need entries that look
 like this:
 
 # SMB password file.
-tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
+tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U          ]:LCT-00000000:Andrew Tridgell:/home/tridge:/bin/tcsh
 
 note that the uid and username fields must be right. Also, you must get
 the number of X's right (there should be 32).
index 7c21e96c6f6f285af5ed0c29ef8e7ea39f0f0132..426cbfcee3e6f9af77732cd5d518c4cb5ec349f0 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Faxing.txt for Samba release 2.1.0prealpha 981204
+!== Faxing.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:    Gerhard Zuber <zuber@berlin.snafu.de>
 Date:                  August 5th 1997.
index 356da2eeace6689da10c8273762a0d71e9c6f7ca..023e33b1ce99c0924a29b43b3b48a5cf05ecd5c2 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== GOTCHAS.txt for Samba release 2.1.0prealpha 981204
+!== GOTCHAS.txt for Samba release 2.0.4 18 May 1999
 !==
 This file lists Gotchas to watch out for:
 =========================================================================
index 93a2263d97f68792a86249b8eb690f7d74a1f884..87a77dacc19762572220352937bc879e505beea0 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== HINTS.txt for Samba release 2.1.0prealpha 981204
+!== HINTS.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Many
 Updated:       Not for a long time!
index 9b7c8ab23a8cbb9c5244aba54f8cf5e7c7fb8f98..a133f261c53903f9e9bb369d6d522d05cd6781a0 100755 (executable)
@@ -1,5 +1,5 @@
 !==
-!== MIRRORS.txt for Samba release 2.1.0prealpha 981204
+!== MIRRORS.txt for Samba release 2.0.4 18 May 1999
 !==
 
 For a list of web and ftp mirrors please see 
index 15ccce829e95bc4cf0a16b2644bd8d995847b306..2af6e213d127194fc38052cc7f623b6619f613dd 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Macintosh_Clients.txt for Samba release 2.1.0prealpha 981204
+!== Macintosh_Clients.txt for Samba release 2.0.4 18 May 1999
 !==
 > Are there any Macintosh clients for Samba?
 
index f1207582bdcc058ca6fb7021373e737abbdc3f00..8408acb979a4d653199136564fc9180e2ab257f3 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== NTDOMAIN.txt for Samba release 2.1.0prealpha 981204
+!== NTDOMAIN.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Luke Kenneth Casson Leighton (samba-bugs@samba.org)
                Copyright (C) 1997 Luke Kenneth Casson Leighton
index ff4acd5e984afdc7d6bcc2f2642f64da3e45e76d..9295f5c4bdce3db55102564e08a65de985fe4240 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== NetBIOS.txt for Samba release 2.1.0prealpha 981204
+!== NetBIOS.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:    lkcl - samba-bugs@arvidsjaur.anu.edu.au
                 Copyright 1997  Luke Kenneth Casson Leighton 
index bc687c22ce13e85136e5b1386bc81ab17c7796c6..4413d387eb7d47dd5c47f768f8672a733ad37f27 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== OS2-Client-HOWTO.txt for Samba release 2.1.0prealpha 981204
+!== OS2-Client-HOWTO.txt for Samba release 2.0.4 18 May 1999
 !==
 
 
index 63befa9e7f86d7451da3d974dccc991d334afb82..5bf82e0cfe4cd66656bfc71e7c7d5899b6dc9caf 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== PRINTER_DRIVER.txt for Samba release 2.1.0prealpha 981204
+!== PRINTER_DRIVER.txt for Samba release 2.0.4 18 May 1999
 !==
 ==========================================================================
        Supporting the famous PRINTER$ share
index e0d271bd05ed36b1951647b6359f292376bcaef2..af9f99a0028e7bd5a66f6b1caabaafa023173cdf 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== PROFILES.txt for Samba release 2.1.0prealpha 981204
+!== PROFILES.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributors:  Bruce Cook <BC3-AU@bigfoot.com>
                Copyright (C) 1998 Bruce Cook
index ec633ee1b536be33f4ae13a67448982b509c0371..f86827367f065699bdb812a6633a5f10e7eb87fa 100644 (file)
@@ -1,8 +1,8 @@
 !==
-!== Passwords.txt for Samba release 2.1.0prealpha 981204
+!== Passwords.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Unknown
-Date:          Unknown
+Date:          Updated April 19th 1999.
 Status:                Current
 
 Subject:       NOTE ABOUT PASSWORDS
@@ -37,8 +37,8 @@ Unix password checking method you are using.  Note that the AFS code is
 only written and tested for AFS 3.3 and later.
 
 
-SECURITY = SERVER
-=================
+SECURITY = SERVER or DOMAIN
+===========================
 
 Samba can use a remote server to do its username/password
 validation. This allows you to have one central machine (for example a
index 3e894e68e54bde8a5857d185ab7c262798cbf46a..358eab3b602a267dbd34c853a8c0892c4c82c33b 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Printing.txt for Samba release 2.1.0prealpha 981204
+!== Printing.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Unknown <samba-bugs@samba.org>
 Date:          Unknown
@@ -54,7 +54,7 @@ might be:
 
 then you print a file and look at the /tmp/tmp.print file to see what
 is produced. Try printing this file with lpr. Does it work? If not
-then your problem with with your lpr system, not with Samba. Often
+then the problem is with your lpr system, not with Samba. Often
 people have problems with their /etc/printcap file or permissions on
 various print queues. 
 
@@ -95,18 +95,32 @@ If the above debug tips don't help, then maybe you need to bring in
 the bug gun, system tracing. See Tracing.txt in this directory.
 
 =====================================================================
-From Caldera Inc., the following documentation has been contributed:
+From Caldera Inc., the following documentation has been
+contributed. Note that it contains stuff that is only relevant on some
+systems (specifically Caldera OpenLinux systems).
 
 
 8.6 Setting up a raw SAMBA printer.
 
-Note: this is not a guide on setting up SAMBA. It merely addresses creating a printer configuration that will allow the output of regular (i.e. not PostScript) Windows printer drivers to print through SAMBA.
+Note: this is not a guide on setting up SAMBA. It merely addresses
+creating a printer configuration that will allow the output of regular
+(i.e. not PostScript) Windows printer drivers to print through SAMBA.
 
-Regular Windows printer drivers can be used to print via SAMBA, but you must set up a raw printer entry in "/etc/printcap" to accomplish this. Also, a print command will need to be specified in "/etc/smb.conf" that forces binary printing.
+Regular Windows printer drivers can be used to print via SAMBA, but
+you must set up a raw printer entry in "/etc/printcap" to accomplish
+this. Also, a print command will need to be specified in
+"/etc/smb.conf" that forces binary printing.
 
-The best way to start is to use printtool under X to create a new entry specifically for this printer. All you really need for it to do is create the necessary directories and set the permissions correctly, so don't worry about setting up a filter for a specific printer.  Filters are not going to be used at all for this entry.
+The best way to start is to use printtool under X to create a new
+entry specifically for this printer. All you really need for it to do
+is create the necessary directories and set the permissions correctly,
+so don't worry about setting up a filter for a specific printer.
+Filters are not going to be used at all for this entry.
 
-Next, go into "/etc" and edit the printcap entry you just created, changing it to look like this (if you named it something other than raw, the entry name and spool directory should be changed here to match):
+Next, go into "/etc" and edit the printcap entry you just created,
+changing it to look like this (if you named it something other than
+raw, the entry name and spool directory should be changed here to
+match):
 
 raw:\
        :rw:sh: \
@@ -114,12 +128,15 @@ raw:\
        :sd=/var/spool/lpd/raw: \
        :fx=flp:
 
-When this is done and saved, edit the section of the smb.conf file that applies to the printer. Make sure the name of the section (enclosed in brackets) matches the name of the raw printer you just set up, then go down a line or two and add this line:
+When this is done and saved, edit the section of the smb.conf file
+that applies to the printer. Make sure the name of the section
+(enclosed in brackets) matches the name of the raw printer you just
+set up, then go down a line or two and add this line:
  
 print command = lpr -b -P%p %s
 
-Save the file, change to "/etc/rc.d/init.d", and type the following commands
-to restart the necessary daemons:
+Save the file, change to "/etc/rc.d/init.d", and type the following
+commands to restart the necessary daemons:
 
 ./lpd stop
 ./lpd start
index b0e96d3c9629988fb8a2b93221430d138ff4b540..64af51a7a80420269985d06f3ddc69e8a83d6923 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Recent-FAQs.txt for Samba release 2.1.0prealpha 981204
+!== Recent-FAQs.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Samba-bugs@samba.org
 Date:          July 5, 1998
index fb170319d8c7857cccc7f61bfe95aa6c899ebbca..35a185052fb9f3428173a68c117af3fbf8b22749 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== RoutedNetworks.txt for Samba release 2.1.0prealpha 981204
+!== RoutedNetworks.txt for Samba release 2.0.4 18 May 1999
 !==
 #NOFNR Flag in LMHosts to Communicate Across Routers\r
 \r
index b9d1240306b1ff7e212efe1bf2b066f3cca56124..d723a1488905600897536d8d8f23eb5dab45164d 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== SCO.txt for Samba release 2.1.0prealpha 981204
+!== SCO.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Geza Makay <makayg@math.u-szeged.hu>
 Date:          Unknown
index 99ce214e3fe44f7bae1f1c0440fa154f9126c65d..981e35e4ef6864c315cb112589710ac37b5eb60f 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== SSLeay.txt for Samba release 2.1.0prealpha 981204
+!== SSLeay.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor: Christian Starkjohann <cs@obdev.at>
 Date:        May 29, 1998
index 73681f1ce2e8b3ffe1d249b9e9bd1ca80afc9459..b2fcd15cda4d085c367e48be17c8274d79c996ab 100644 (file)
@@ -1,9 +1,6 @@
 !==
-!== Speed.txt for Samba release 2.1.0prealpha 981204
+!== Speed.txt for Samba release 2.0.4b 20 May 1999
 !==
-Contributor:   Andrew Tridgell
-Date:          January 1995
-Status:                Current
 
 Subject:       Samba performance issues
 ============================================================================
@@ -63,6 +60,21 @@ option has been left in the code for backwards compatibility reasons
 but it's use is now deprecated. A short summary of what the old
 code did follows.
 
+LEVEL2 OPLOCKS
+--------------
+
+With Samba 2.0.5 a new capability - level2 (read only) oplocks is
+supported (although the option is off by default - see the smb.conf
+man page for details). Turning on level2 oplocks (on a share-by-share basis)
+by setting the parameter :
+
+level2 oplocks = true 
+
+should speed concurrent access to files that are not commonly written
+to, such as application serving shares (ie. shares that contain common
+.EXE files - such as a Microsoft Office share) as it allows clients to
+read-ahread cache copies of these files.
+
 Old 'fake oplocks' option - deprecated.
 ---------------------------------------
 
index 2a5baa144ab38df1a47c98c4959cf09c9f00b7ff..057f8e6bf34ab8133d3f9733f42d57521230c674 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Speed2.txt for Samba release 2.1.0prealpha 981204
+!== Speed2.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Paul Cochrane <paulc@dth.scot.nhs.uk>
 Organization:  Dundee Limb Fitting Centre
index af5a9e0c46c759956599a63dbd5400639bdcd016..ff342e3eac223659c05a93ea5a8f68cae48ebfbe 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Support.txt for Samba release 2.1.0prealpha 981204
+!== Support.txt for Samba release 2.0.4 18 May 1999
 !==
 The Samba Consultants List
 ==========================
index 31aef9bfc1eec24a7a14431008d9985a641d9569..d156b34633ead177e871aa1fa27195ed8d234f2d 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Tracing.txt for Samba release 2.1.0prealpha 981204
+!== Tracing.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Andrew Tridgell <samba-bugs@samba.org>
 Date:          Old
index cea6001ff228484a809d841c65cafc2ff80dbd7a..7d597af654b0e9f8e38cafd84bb5a9fa57654ef0 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== UNIX-SMB.txt for Samba release 2.1.0prealpha 981204
+!== UNIX-SMB.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Andrew Tridgell <samba-bugs@samba.org>
 Date:          April 1995
index bc9d1c50b4011190b6c2bd4414e484ae37847e15..1de821e1520990e0504ea5a97a5d66bfc624a717 100644 (file)
@@ -1,14 +1,5 @@
-!==
-!== UNIX_INSTALL.txt for Samba release 2.1.0prealpha 981204
-!==
-Contributor:   Andrew Tridgell <samba-bugs@samba.org>
-Date:          Unknown
-Status:                Current
-Updated:       November 13, 1998       <jra@samba.org>
-
-Subject:       HOW TO INSTALL AND TEST SAMBA
-===============================================================================
-
+HOW TO INSTALL AND TEST SAMBA
+=============================
 
 STEP 0. Read the man pages. They contain lots of useful info that will
 help to get you started. If you don't know how to read man pages then
index 59a955ff7e3b53176c132607cd12a71428258113..1a610d8e4c7717d91ee8ec6583a3d9bc24c49dac 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== UNIX_SECURITY.txt for Samba release 2.1.0prealpha 981204
+!== UNIX_SECURITY.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   John H Terpstra <jht@samba.org>
 Date:          July 5, 1998
index c75edeefdde2bbf9a70f60efd5a4d4fd2b1e494e..417fe012204d001ddb0c1825061b01ffa3b9c35c 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== Win95.txt for Samba release 2.1.0prealpha 981204
+!== Win95.txt for Samba release 2.0.4 18 May 1999
 !==
 Copyright (C) 1997 - Samba-Team
 Contributed Date:      August 20, 1997
index b0f614bbad245b5ee26a99b44fc06a7ffb5291b6..4894936aa9b9469fe8a89683f23f4e4b198d20cd 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== WinNT.txt for Samba release 2.1.0prealpha 981204
+!== WinNT.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributors:  Various
                Password Section - Copyright (C) 1997 - John H Terpstra
index 782267b780891630f7f334342929a5067e6d8a40..ba6e0c46be32b89a7f3af69c087a23709fd984dc 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== cifsntdomain.txt for Samba release 2.1.0prealpha 981204
+!== cifsntdomain.txt for Samba release 2.0.4 18 May 1999
 !==
 NT Domain Authentication
 ------------------------
index 87e0e38d485233f0b48cc210f99549bd966440a9..9c4680ebe11f3bea7e3575158303de2b78309f7c 100644 (file)
@@ -1,5 +1,5 @@
 !==
-!== security_level.txt for Samba release 2.1.0prealpha 981204
+!== security_level.txt for Samba release 2.0.4 18 May 1999
 !==
 Contributor:   Andrew Tridgell
 Updated:       June 27, 1997
@@ -59,16 +59,16 @@ maintain multiple authentication contexts in this way (WinDD is an
 example of an application that does this)
 
 
-Ok, now for share level security. In share level security (the default
-with samba) the client authenticates itself separately for each
-share. It will send a password along with each "tree connection"
-(share mount). It does not explicitly send a username with this
-operation. The client is expecting a password to be associated with
-each share, independent of the user. This means that samba has to work
-out what username the client probably wants to use. It is never
-explicitly sent the username. Some commercial SMB servers such as NT actually
-associate passwords directly with shares in share level security, but
-samba always uses the unix authentication scheme where it is a
+Ok, now for share level security. In share level security the client
+authenticates itself separately for each share. It will send a
+password along with each "tree connection" (share mount). It does not
+explicitly send a username with this operation. The client is
+expecting a password to be associated with each share, independent of
+the user. This means that samba has to work out what username the
+client probably wants to use. It is never explicitly sent the
+username. Some commercial SMB servers such as NT actually associate
+passwords directly with shares in share level security, but samba
+always uses the unix authentication scheme where it is a
 username/password that is authenticated, not a "share/password".
 
 Many clients send a "session setup" even if the server is in share
index 2b05c0e814876c4a4a3f56d373ee2b18c28a780a..f52b6ab97c29c46477761525f0414edcfd1f6269 100644 (file)
@@ -1,6 +1,6 @@
 mailto(samba-bugs@samba.org)
 
-article(Joining an NT Domain with Samba 2.0)(Jeremy Allison, Samba Team)(11th November 1998)
+article(Joining an NT Domain with Samba 2.0)(Jeremy Allison, Samba Team)(7th October 1999)
 
 center(Joining an NT Domain with Samba 2.0)
 center(-----------------------------------)
@@ -8,7 +8,8 @@ center(-----------------------------------)
 In order for a Samba-2 server to join an NT domain, you must first add
 the NetBIOS name of the Samba server to the NT domain on the PDC using
 Server Manager for Domains.  This creates the machine account in the
-domain (PDC) SAM.
+domain (PDC) SAM. Note that you should add the Samba server as a "Windows
+NT Workstation or Server", em(NOT) as a Primary or backup domain controller.
 
 Assume you have a Samba-2 server with a NetBIOS name of tt(SERV1) and are
 joining an NT domain called tt(DOM), which has a PDC with a NetBIOS name
@@ -21,7 +22,7 @@ command
 tt(smbpasswd -j DOM -r DOMPDC)
 
 as we are joining the domain DOM and the PDC for that domain (the only
-machine that has write access to the domain SAM database). If this is
+machine that has write access to the domain SAM database) is DOMPDC. If this is
 successful you will see the message:
 
 tt(smbpasswd: Joined domain DOM.)
@@ -31,8 +32,8 @@ man page for more details.
 
 This command goes through the machine account password change
 protocol, then writes the new (random) machine account password for
-this Samba server into the a file in the same directory in which an
-smbpasswd file would be stored (normally :
+this Samba server into a file in the same directory in which an
+smbpasswd file would be stored normally :
 
 tt(/usr/local/samba/private)
 
@@ -72,6 +73,10 @@ tt(workgroup = DOM)
 
 as this is the name of the domain we are joining. 
 
+You must also have the parameter url(bf("encrypt passwords"))(smb.conf.5.html#encryptpasswords)
+set to tt("yes") in order for your users to authenticate to the
+NT PDC.
+
 Finally, add (or modify) a:
 
 url(bf("password server ="))(smb.conf.5.html#passwordserver)
@@ -86,19 +91,15 @@ each of these servers in order, so you may want to rearrange this list
 in order to spread out the authentication load among domain
 controllers.
 
-Currently, Samba requires that a defined list of domain controllers be
-listed in this parameter in order to authenticate with domain-level
-security. NT does not use this method, and will either broadcast or
-use a WINS database in order to find domain controllers to
-authenticate against.
+Alternatively, if you want smbd to automatically determine the
+list of Domain controllers to use for authentication, you may set this line to be :
 
-Originally, I considered this idea for Samba, but dropped it because
-it seemed so insecure.  However several Samba-2 alpha users have
-requested that this feature be added to make Samba more NT-like, so
-I'll probably add a special name of tt('*') (which means: act like NT
-when looking for domain controllers) in a future release of the
-code. At present, however, you need to know where your domain
-controllers are.
+tt(password server = *)
+
+This method, which is new in Samba 2.0.6 and above, allows Samba
+to use exactly the same mechanism that NT does. This method either broadcasts or
+uses a WINS database in order to find domain controllers to
+authenticate against.
 
 Finally, restart your Samba daemons and get ready for clients to begin
 using domain security!
index bf9a5f8b78cc4ccc945c7acb7f9ead269d42640b..596b42dd69f7b939f94ab6eab5615bb5e225c5bf 100644 (file)
@@ -9,7 +9,7 @@ naming services to clients)
 label(SYNOPSIS)
 manpagesynopsis()
 
-bf(nmbd) [link(-D)(minusD)] [link(-o)(minuso)] [link(-a)(minusa)] [link(-H lmhosts file)(minusH)] [link(-d debuglevel)(minusd)] [link(-l log file basename)(minusl)] [link(-n primary NetBIOS name)(minusn)] [link(-p port number)(minusp)] [link(-s configuration file)(minuss)] [link(-i NetBIOS scope)(minusi)] [link(-h)(minush)]
+bf(nmbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-h)(minush)] [link(-V)(minusV)] [link(-H lmhosts file)(minusH)] [link(-d debuglevel)(minusd)] [link(-l log file basename)(minusl)] [link(-n primary NetBIOS name)(minusn)] [link(-p port number)(minusp)] [link(-s configuration file)(minuss)] [link(-i NetBIOS scope)(minusi)]
 
 label(DESCRIPTION)
 manpagedescription()
@@ -65,6 +65,12 @@ dit(bf(-o)) If this parameter is specified, the log files will be
 overwritten when opened.  By default, the log files will be appended
 to.
 
+label(minush)
+dit(bf(-h)) Prints the help information (usage) for bf(nmbd).
+
+label(minusV)
+dit(bf(-V)) Prints the version number for bf(nmbd).
+
 label(minusH)
 dit(bf(-H filename)) NetBIOS lmhosts file.
 
@@ -144,9 +150,6 @@ are em(very) rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
 
-label(minush)
-dit(bf(-h)) Prints the help information (usage) for bf(nmbd).
-
 endit()
 
 label(FILES)
index 6293fd01e5e028cd195d41817473ca4fb4804401..80ec850be240a8c776966aa43bbdab50fc2a9de8 100644 (file)
@@ -8,7 +8,7 @@ manpagename(nmblookup)(NetBIOS over TCP/IP client used to lookup NetBIOS names)
 label(SYNOPSIS)
 manpagesynopsis() 
 
-bf(nmblookup) [link(-M)(minusM)] [link(-R)(minusR)] [link(-S)(minusS)] [link(-r)(minusr)] [link(-A)(minusA)] [link(-h)(minush)] [link(-B broadcast address)(minusB)] [link(-U unicast address)(minusU)] [link(-d debuglevel)(minusd)] [link(-s smb config file)(minuss)] [link(-i NetBIOS scope)(minusi)] link(name)(name)
+bf(nmblookup) [link(-M)(minusM)] [link(-R)(minusR)] [link(-S)(minusS)] [link(-r)(minusr)] [link(-A)(minusA)] [link(-h)(minush)] [link(-B broadcast address)(minusB)] [link(-U unicast address)(minusU)] [link(-d debuglevel)(minusd)] [link(-s smb config file)(minuss)] [link(-i NetBIOS scope)(minusi)] [link(-T)(minusT)] link(name)(name)
 
 label(DESCRIPTION)
 manpagedescription()
@@ -26,8 +26,9 @@ manpageoptions()
 startdit()
 
 label(minusM)
-dit(bf(-M)) Searches for a master browser. This is done by doing a
-broadcast lookup on the special name tt(__MSBROWSE__).
+dit(bf(-M)) Searches for a master browser by looking up the 
+NetBIOS name link(bf(name))(name) with a type of 0x1d. If link(bf(name))(name)
+is tt("-") then it does a lookup on the special name tt(__MSBROWSE__).
 
 label(minusR)
 dit(bf(-R)) Set the recursion desired bit in the packet to do a
@@ -61,8 +62,8 @@ dit(bf(-h)) Print a help (usage) message.
 label(minusB)
 dit(bf(-B broadcast address)) Send the query to the given broadcast
 address. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the primary network
-interface as either auto-detected or defined in the 
+send the query to the broadcast address of the network
+interfaces as either auto-detected or defined in the 
 url(bf(interfaces))(smb.conf.5.html#interfaces) parameter of the 
 url(bf(smb.conf (5)))(smb.conf.5.html) file.
 
@@ -103,6 +104,12 @@ are em(very) rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
 
+label(minusT)
+dit(bf(-T)) This causes any IP addresses found in the lookup to be
+looked up via a reverse DNS lookup into a DNS name, and printed out
+before each tt("IP address   NetBIOS name") pair that is the normal
+output.
+
 label(name)
 dit(bf(name)) This is the NetBIOS name being queried. Depending upon
 the previous options this may be a NetBIOS name or IP address. If a
index ff4ff2796b5c0b3d5fd3f8741566b7b9bbfc47fe..dc238bd0fc96a41ef0c13cb0205e624746ada8b0 100644 (file)
@@ -47,15 +47,6 @@ servers (such as Windows NT), and can also be used to allow a UNIX box
 to print to a printer attached to any SMB server (such as a PC running
 Windows NT).
 
-dit(url(bf(rpcclient))(rpcclient.1.html)) nl() nl() The url(bf(rpcclient)
-(1))(rpcclient.1.html) program is a client that can 'talk' to an
-SMB/CIFS MSRPC server.  Operations include things like managing a SAM
-Database (users, groups and aliases) in the same way as the Windows NT
-programs bf(User Manager for Domains) and bf(Server Manager for Domains);
-managing a remote registry in the same way as the Windows NT programs
-bf(REGEDT32.EXE) and bf(REGEDIT.EXE); viewing a remote event log (same
-as bf(EVENTVWR.EXE)).
-
 dit(url(bf(testparm))(testparm.1.html)) nl() nl() The url(bf(testparm
 (1)))(testparm.1.html) utility allows you to test your url(bf(smb.conf
 (5)))(smb.conf.5.html) configuration file.
index 05352bb883b1e8e33aef43805701f1f7c2ad245e..abb26f5ec1ec4175c96cf6394221f453b2feab4e 100644 (file)
@@ -478,6 +478,10 @@ parameter for details.  Note that some are synonyms.
 
 startit()
 
+it() link(bf(add user script))(adduserscript)
+
+it() link(bf(allow trusted domains))(allowtrusteddomains)
+
 it() link(bf(announce as))(announceas)
 
 it() link(bf(announce version))(announceversion)
@@ -500,14 +504,22 @@ it() link(bf(config file))(configfile)
 
 it() link(bf(deadtime))(deadtime)
 
+it() link(bf(debug hires timestamp))(debughirestimestamp)
+
+it() link(bf(debug pid))(debugpid)
+
 it() link(bf(debug timestamp))(debugtimestamp)
 
+it() link(bf(debug uid))(debuguid)
+
 it() link(bf(debuglevel))(debuglevel)
 
 it() link(bf(default))(default)
 
 it() link(bf(default service))(defaultservice)
 
+it() link(bf(delete user script))(deleteuserscript)
+
 it() link(bf(dfree command))(dfreecommand)
 
 it() link(bf(dns proxy))(dnsproxy)
@@ -518,8 +530,6 @@ it() link(bf(domain admin users))(domainadminusers)
 
 it() link(bf(domain controller))(domaincontroller)
 
-it() link(bf(domain group map))(domaingroupmap)
-
 it() link(bf(domain groups))(domaingroups)
 
 it() link(bf(domain guest group))(domainguestgroup)
@@ -530,8 +540,6 @@ it() link(bf(domain logons))(domainlogons)
 
 it() link(bf(domain master))(domainmaster)
 
-it() link(bf(domain user map))(domainusermap)
-
 it() link(bf(encrypt passwords))(encryptpasswords)
 
 it() link(bf(getwd cache))(getwdcache)
@@ -546,12 +554,14 @@ it() link(bf(keepalive))(keepalive)
 
 it() link(bf(kernel oplocks))(kerneloplocks)
 
-it() link(bf(ldap bind as))(ldapbindas)
-
-it() link(bf(ldap passwd file))(ldappasswdfile)
+it() link(bf(ldap filter))(ldapfilter)
 
 it() link(bf(ldap port))(ldapport)
 
+it() link(bf(ldap root))(ldaproot)
+
+it() link(bf(ldap root passwd))(ldaprootpasswd)
+
 it() link(bf(ldap server))(ldapserver)
 
 it() link(bf(ldap suffix))(ldapsuffix)
@@ -562,8 +572,6 @@ it() link(bf(lm interval))(lminterval)
 
 it() link(bf(load printers))(loadprinters)
 
-it() link(bf(local group map))(localgroupmap)
-
 it() link(bf(local master))(localmaster)
 
 it() link(bf(lock dir))(lockdir)
@@ -588,6 +596,8 @@ it() link(bf(machine password timeout))(machinepasswordtimeout)
 
 it() link(bf(mangled stack))(mangledstack)
 
+it() link(bf(map to guest))(maptoguest)
+
 it() link(bf(max disk size))(maxdisksize)
 
 it() link(bf(max log size))(maxlogsize)
@@ -606,6 +616,8 @@ it() link(bf(max xmit))(maxxmit)
 
 it() link(bf(message command))(messagecommand)
 
+it() link(bf(min passwd length))(minpasswdlength)
+
 it() link(bf(min wins ttl))(minwinsttl)
 
 it() link(bf(name resolve order))(nameresolveorder)
@@ -616,6 +628,8 @@ it() link(bf(netbios name))(netbiosname)
 
 it() link(bf(nis homedir))(nishomedir)
 
+it() link(bf(nt acl support))(ntaclsupport)
+
 it() link(bf(nt pipe support))(ntpipesupport)
 
 it() link(bf(nt smb support))(ntsmbsupport)
@@ -624,6 +638,8 @@ it() link(bf(null passwords))(nullpasswords)
 
 it() link(bf(ole locking compatibility))(olelockingcompatibility)
 
+it() link(bf(oplock break wait time))(oplockbreakwaittime)
+
 it() link(bf(os level))(oslevel)
 
 it() link(bf(packet size))(packetsize)
@@ -666,6 +682,8 @@ it() link(bf(remote announce))(remoteannounce)
 
 it() link(bf(remote browse sync))(remotebrowsesync)
 
+it() link(bf(restrict anonymous))(restrictanonymous)
+
 it() link(bf(root))(root)
 
 it() link(bf(root dir))(rootdir)
@@ -748,6 +766,8 @@ it() link(bf(wins proxy))(winsproxy)
 
 it() link(bf(wins server))(winsserver)
 
+it() link(bf(wins hook))(winshook)
+
 it() link(bf(wins support))(winssupport)
 
 it() link(bf(workgroup))(workgroup)
@@ -804,6 +824,8 @@ it() link(bf(directory mask))(directorymask)
 
 it() link(bf(directory mode))(directorymode)
 
+it() link(bf(directory security mask))(directorysecuritymask)
+
 it() link(bf(dont descend))(dontdescend)
 
 it() link(bf(dos filetime resolution))(dosfiletimeresolution)
@@ -822,8 +844,12 @@ it() link(bf(force create mode))(forcecreatemode)
 
 it() link(bf(force directory mode))(forcedirectorymode)
 
+it() link(bf(force directory security mode))(forcedirectorysecuritymode)
+
 it() link(bf(force group))(forcegroup)
 
+it() link(bf(force security mode))(forcesecuritymode)
+
 it() link(bf(force user))(forceuser)
 
 it() link(bf(fstype))(fstype)
@@ -848,6 +874,8 @@ it() link(bf(include))(include)
 
 it() link(bf(invalid users))(invalidusers)
 
+it() link(bf(level2 oplocks))(level2oplocks)
+
 it() link(bf(locking))(locking)
 
 it() link(bf(lppause command))(lppausecommand)
@@ -864,6 +892,8 @@ it() link(bf(magic script))(magicscript)
 
 it() link(bf(mangle case))(manglecase)
 
+it() link(bf(mangle locks))(manglelocks)
+
 it() link(bf(mangled map))(mangledmap)
 
 it() link(bf(mangled names))(manglednames)
@@ -876,8 +906,6 @@ it() link(bf(map hidden))(maphidden)
 
 it() link(bf(map system))(mapsystem)
 
-it() link(bf(map to guest))(maptoguest)
-
 it() link(bf(max connections))(maxconnections)
 
 it() link(bf(min print space))(minprintspace)
@@ -888,6 +916,8 @@ it() link(bf(only user))(onlyuser)
 
 it() link(bf(oplocks))(oplocks)
 
+it() link(bf(oplock contention limit))(oplockcontentionlimit)
+
 it() link(bf(path))(path)
 
 it() link(bf(postexec))(postexec)
@@ -896,6 +926,8 @@ it() link(bf(postscript))(postscript)
 
 it() link(bf(preexec))(preexec)
 
+it() link(bf(preexec close))(preexecclose)
+
 it() link(bf(preserve case))(preservecase)
 
 it() link(bf(print command))(printcommand)
@@ -930,6 +962,10 @@ it() link(bf(root postexec))(rootpostexec)
 
 it() link(bf(root preexec))(rootpreexec)
 
+it() link(bf(security mask))(securitymask)
+
+it() link(bf(root preexec close))(rootpreexecclose)
+
 it() link(bf(set directory))(setdirectory)
 
 it() link(bf(share modes))(sharemodes)
@@ -975,6 +1011,55 @@ manpagesection(EXPLANATION OF EACH PARAMETER)
 
 startdit()
 
+label(adduserscript)
+dit(bf(add user script (G)))
+
+This is the full pathname to a script that will be run em(AS ROOT) by
+url(bf(smbd (8)))(smbd.8.html) under special circumstances decribed
+below.
+
+Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task. This option allows url(bf(smbd))(smbd.8.html) to create
+the required UNIX users em(ON DEMAND) when a user accesses the Samba
+server.
+
+In order to use this option, url(bf(smbd))(smbd.8.html) must be set to
+link(bf(security=server))(securityequalserver) or
+link(bf(security=domain))(securityequaldomain) and bf("add user script")
+must be set to a full pathname for a script that will create a UNIX user
+given one argument of bf(%u), which expands into the UNIX user name to
+create.
+
+When the Windows user attempts to access the Samba server, at
+em("login")(session setup in the SMB protocol) time,
+url(bf(smbd))(smbd.8.html) contacts the link(bf(password
+server))(passwordserver) and attempts to authenticate the given user
+with the given password. If the authentication succeeds then
+url(bf(smbd))(smbd.8.html) attempts to find a UNIX user in the UNIX
+password database to map the Windows user into. If this lookup fails,
+and bf("add user script") is set then url(bf(smbd))(smbd.8.html) will
+call the specified script em(AS ROOT), expanding any bf(%u) argument
+to be the user name to create.
+
+If this script successfully creates the user then
+url(bf(smbd))(smbd.8.html) will continue on as though the UNIX user
+already existed. In this way, UNIX users are dynamically created to
+match existing Windows NT accounts.
+
+See also link(bf(security=server))(securityequalserver),
+link(bf(security=domain))(securityequaldomain), link(bf(password
+server))(passwordserver), link(bf(delete user
+script))(deleteuserscript).
+
+  bf(Default:)
+tt(    add user script = <empty string>)
+
+  bf(Example:)
+tt(    add user script = /usr/local/samba/bin/add_user %u)
+
 label(adminusers)
 dit(bf(admin users (S)))
 
@@ -995,63 +1080,30 @@ tt(      admin users = jason)
 label(allow hosts)
 dit(bf(allow hosts (S)))
 
-A synonym for this parameter is link(bf('hosts allow'))(hostsallow)
+Synonym for link(bf(hosts allow))(hostsallow).
 
-This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service.
+label(allowtrusteddomains)
+dit(bf(allow trusted domains (G)))
 
-If specified in the link(bf([global]))(global) section then it will
-apply to all services, regardless of whether the individual service
-has a different setting.
+This option only takes effect when the link(bf(security))(security)
+option is set to bf(server) or bf(domain).  If it is set to no,
+then attempts to connect to a resource from a domain or workgroup other than
+the one which smbd is running in will fail, even if that domain
+is trusted by the remote server doing the authentication.
 
-You can specify the hosts by name or IP number. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like tt("allow hosts = 150.203.5."). The full syntax of the list is
-described in the man page bf(hosts_access (5)). Note that this man
-page may not be present on your system, so a brief description will
-be given here also.
-
-em(NOTE:) IF you wish to allow the url(bf(smbpasswd
-(8)))(smbpasswd.html.8) program to be run by local users to change
-their Samba passwords using the local url(bf(smbd (8)))(smbd.8.html)
-daemon, then you em(MUST) ensure that the localhost is listed in your
-bf(allow hosts) list, as url(bf(smbpasswd (8)))(smbpasswd.html.8) runs
-in client-server mode and is seen by the local
-url(bf(smbd))(smbd.8.html) process as just another client.
-
-You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups. The em(EXCEPT) keyword can also
-be used to limit a wildcard list. The following examples may provide
-some help:
-
-bf(Example 1): allow localhost and all IPs in 150.203.*.* except one
-
-tt(    hosts allow = localhost, 150.203. EXCEPT 150.203.6.66)
-
-bf(Example 2): allow localhost and hosts that match the given network/netmask
-
-tt(    hosts allow = localhost, 150.203.15.0/255.255.255.0)
-
-bf(Example 3): allow a localhost plus a couple of hosts
-
-tt(    hosts allow = localhost, lapland, arvidsjaur)
-
-bf(Example 4): allow only hosts in NIS netgroup "foonet" or localhost, but 
-deny access from one particular host
-
-tt(    hosts allow = @foonet, localhost)
-tt(    hosts deny = pirate)
-
-Note that access still requires suitable user-level passwords.
-
-See url(bf(testparm (1)))(testparm.1.html) for a way of testing your
-host access to see if it does what you expect.
+This is useful if you only want your Samba server to serve resources
+to users in the domain it is a member of. As an example, suppose that there are
+two domains DOMA and DOMB.  DOMB is trusted by DOMA, which contains
+the Samba server.  Under normal circumstances, a user with an account
+in DOMB can then access the resources of a UNIX account with the same
+account name on the Samba server even if they do not have an account
+in DOMA.  This can make implementing a security boundary difficult.
 
   bf(Default:)
-tt(    none (i.e., all hosts permitted access))
+tt(     allow trusted domains = Yes)
 
   bf(Example:)
-tt(    allow hosts = 150.203.5. localhost myhost.mynet.edu.au)
+tt(     allow trusted domains = No)
 
 label(alternatepermissions)
 dit(bf(alternate permissions (S)))
@@ -1067,14 +1119,15 @@ dit(bf(announce as (G)))
 
 This specifies what type of server url(bf(nmbd))(nmbd.8.html) will
 announce itself as, to a network neighborhood browse list. By default
-this is set to Windows NT. The valid options are : "NT", "Win95" or
-"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
-respectively. Do not change this parameter unless you have a specific
-need to stop Samba appearing as an NT server as this may prevent Samba
-servers from participating as browser servers correctly.
+this is set to Windows NT. The valid options are : "NT", which is a
+synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
+"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
+and Windows for Workgroups respectively. Do not change this parameter
+unless you have a specific need to stop Samba appearing as an NT server
+as this may prevent Samba servers from participating as browser servers correctly.
 
   bf(Default:)
-tt(    announce as = NT)
+tt(    announce as = NT Server)
 
   bf(Example)
 tt(    announce as = Win95)
@@ -1158,11 +1211,16 @@ should not use this parameter for machines that are serving PPP or
 other intermittent or non-broadcast network interfaces as it will not
 cope with non-permanent interfaces.
 
-In addition, to change a users SMB password, the
-url(bf(smbpasswd))(smbpasswd.8.html) by default connects to the
-em("localhost" - 127.0.0.1) address as an SMB client to issue the
-password change request. If bf("bind interfaces only") is set then
-unless the network address em(127.0.0.1) is added to the
+If bf("bind interfaces only") is set then unless the network address
+em(127.0.0.1) is added to the link(bf('interfaces'))(interfaces) parameter
+list url(bf(smbpasswd))(smbpasswd.8.html) and
+url(bf(swat))(swat.8.html) may not work as expected due to the
+reasons covered below.
+
+To change a users SMB password, the url(bf(smbpasswd))(smbpasswd.8.html)
+by default connects to the em("localhost" - 127.0.0.1) address as an SMB
+client to issue the password change request. If bf("bind interfaces only")
+is set then unless the network address em(127.0.0.1) is added to the
 link(bf('interfaces'))(interfaces) parameter list then
 url(bf(smbpasswd))(smbpasswd.8.html) will fail to connect in it's
 default mode. url(bf(smbpasswd))(smbpasswd.8.html) can be forced to
@@ -1171,6 +1229,14 @@ url(bf("-r remote machine"))(smbpasswd.8.html#minusr) parameter, with
 bf("remote machine") set to the IP name of the primary interface
 of the local host.
 
+The url(bf(swat))(swat.8.html) status page tries to connect with
+url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html) at the address 
+em(127.0.0.1) to determine if they are running.  Not adding em(127.0.0.1)  will cause
+url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html) to always show
+"not running" even if they really are.  This can prevent
+url(bf(swat))(swat.8.html) from starting/stopping/restarting
+url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html).
+
   bf(Default:)
 tt(    bind interfaces only = False)
 
@@ -1282,7 +1348,13 @@ correctly.
 
 it() bf(ISO8859-5) Russian Cyrillic UNIX character set. The parameter
 link(bf(client code page))(clientcodepage) em(MUST) be set to code
-page 866 if the bf(character set) parameter is set to ISO8859-2
+page 866 if the bf(character set) parameter is set to ISO8859-5
+in order for the conversion to the UNIX character set to be done
+correctly. 
+
+it() bf(ISO8859-7) Greek UNIX character set. The parameter
+link(bf(client code page))(clientcodepage) em(MUST) be set to code
+page 737 if the bf(character set) parameter is set to ISO8859-7
 in order for the conversion to the UNIX character set to be done
 correctly. 
 
@@ -1529,6 +1601,22 @@ tt(      deadtime = 0)
   bf(Example:)
 tt(    deadtime = 15)
 
+label(debughirestimestamp)
+dit(bf(debug hires timestamp (G)))
+
+Sometimes the timestamps in the log messages are needed with a
+resolution of higher that seconds, this boolean parameter adds
+microsecond resolution to the timestamp message header when turned on.
+
+Note that the parameter link(bf(debug timestamp))(debugtimestamp)
+must be on for this to have an effect.
+
+  bf(Default:)
+tt( debug hires timestamp = No)
+
+  bf(Example:)
+tt( debug hires timestamp = Yes)
+
 label(debugtimestamp)
 dit(bf(debug timestamp (G)))
 
@@ -1543,6 +1631,39 @@ tt(      debug timestamp = Yes)
   bf(Example:)
 tt(    debug timestamp = No)
 
+label(debugpid)
+dit(bf(debug pid (G)))
+
+When using only one log file for more then one forked smbd-process
+there may be hard to follow which process outputs which message.
+This boolean parameter is adds the process-id to the timestamp message
+headers in the logfile when turned on.
+
+Note that the parameter link(bf(debug timestamp))(debugtimestamp)
+must be on for this to have an effect.
+
+  bf(Default:)
+tt(    debug pid = No)
+
+  bf(Example:)
+tt(    debug pid = Yes)
+
+label(debuguid)
+dit(bf(debug uid (G)))
+
+Samba is sometimes run as root and sometime run as the connected
+user, this boolean parameter inserts the current euid, egid, uid
+and gid to the timestamp message headers in the log file if turned on.
+
+Note that the parameter link(bf(debug timestamp))(debugtimestamp)
+must be on for this to have an effect.
+
+  bf(Default:)
+tt(    debug uid = No)
+
+  bf(Example:)
+tt(    debug uid = Yes)
+
 label(debuglevel)
 dit(bf(debug level (G)))
 
@@ -1567,7 +1688,7 @@ dit(bf(default case (S)))
 See the section on link(bf("NAME MANGLING"))(NAMEMANGLING). Also note
 the link(bf("short preserve case"))(shortpreservecase) parameter.
 
-label(default service)
+label(defaultservice)
 dit(bf(default service (G)))
 
 This parameter specifies the name of a service which will be connected
@@ -1599,6 +1720,60 @@ verb(
                path = /%S
 )
 
+label(deleteuserscript)
+dit(bf(delete user script (G)))
+
+This is the full pathname to a script that will be run em(AS ROOT) by
+url(bf(smbd (8)))(smbd.8.html) under special circumstances decribed
+below.
+
+Normally, a Samba server requires that UNIX users are created for all
+users accessing files on this server. For sites that use Windows NT
+account databases as their primary user database creating these users
+and keeping the user list in sync with the Windows NT PDC is an
+onerous task. This option allows url(bf(smbd))(smbd.8.html) to delete
+the required UNIX users em(ON DEMAND) when a user accesses the Samba
+server and the Windows NT user no longer exists.
+
+In order to use this option, url(bf(smbd))(smbd.8.html) must be set to
+link(bf(security=domain))(securityequaldomain) and bf("delete user
+script") must be set to a full pathname for a script that will delete
+a UNIX user given one argument of bf(%u), which expands into the UNIX
+user name to delete. em(NOTE) that this is different to the
+link(bf(add user script))(adduserscript) which will work with the
+link(bf(security=server))(securityequalserver) option as well as
+link(bf(security=domain))(securityequaldomain). The reason for this
+is only when Samba is a domain member does it get the information
+on an attempted user logon that a user no longer exists. In the
+link(bf(security=server))(securityequalserver) mode a missing user
+is treated the same as an invalid password logon attempt. Deleting
+the user in this circumstance would not be a good idea.
+
+When the Windows user attempts to access the Samba server, at
+em("login")(session setup in the SMB protocol) time,
+url(bf(smbd))(smbd.8.html) contacts the link(bf(password
+server))(passwordserver) and attempts to authenticate the given user
+with the given password. If the authentication fails with the specific
+Domain error code meaning that the user no longer exists then
+url(bf(smbd))(smbd.8.html) attempts to find a UNIX user in the UNIX
+password database that matches the Windows user account. If this lookup succeeds,
+and bf("delete user script") is set then url(bf(smbd))(smbd.8.html) will
+call the specified script em(AS ROOT), expanding any bf(%u) argument
+to be the user name to delete.
+
+This script should delete the given UNIX username. In this way, UNIX
+users are dynamically deleted to match existing Windows NT accounts.
+
+See also link(bf(security=domain))(securityequaldomain),
+link(bf(password server))(passwordserver), link(bf(add user
+script))(adduserscript).
+
+  bf(Default:)
+tt(    delete user script = <empty string>)
+
+  bf(Example:)
+tt(    delete user script = /usr/local/samba/bin/del_user %u)
+
 label(deletereadonly)
 dit(bf(delete readonly (S)))
 
@@ -1646,16 +1821,7 @@ tt(      delete veto files = True)
 label(denyhosts)
 dit(bf(deny hosts (S)))
 
-The opposite of link(bf('allow hosts'))(allowhosts) - hosts listed
-here are em(NOT) permitted access to services unless the specific
-services have their own lists to override this one. Where the lists
-conflict, the link(bf('allow'))(allowhosts) list takes precedence.
-
-  bf(Default:)
-tt(    none (i.e., no hosts specifically excluded))
-
-  bf(Example:)
-tt(    deny hosts = 150.203.4. badhost.mynet.edu.au)
+Synonym for link(bf(hosts deny))(hostsdeny).
 
 label(dfreecommand)
 dit(bf(dfree command (G)))
@@ -1737,7 +1903,8 @@ See the link(bf("force directory mode"))(forcedirectorymode) parameter
 to cause particular mode bits to always be set on created directories.
 
 See also the link(bf("create mode"))(createmode) parameter for masking
-mode bits on created files.
+mode bits on created files, and the link(bf("directory security mask"))(directorysecuritymask)
+parameter.
 
   bf(Default:)
 tt(    directory mask = 0755)
@@ -1750,6 +1917,39 @@ dit(bf(directory mode (S)))
 
 Synonym for link(bf(directory mask))(directorymask).
 
+label(directorysecuritymask)
+dit(bf(directory security mask (S)))
+
+This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+directory using the native NT security dialog box.
+
+This parameter is applied as a mask (AND'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change.
+
+If not set explicitly this parameter is set to the same value as the
+link(bf(directory mask))(directorymask) parameter. To allow a user to
+modify all the user/group/world permissions on a directory, set this
+parameter to 0777.
+
+em(Note) that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0777.
+
+See also the link(bf(force directory security
+mode))(forcedirectorysecuritymode), link(bf(security
+mask))(securitymask), link(bf(force security mode))(forcesecuritymode)
+parameters.
+
+  bf(Default:)
+tt(    directory security mask = <same as directory mask>)
+
+  bf(Example:)
+tt(    directory security mask = 0777)
+
 label(dnsproxy)
 dit(bf(dns proxy (G)))
 
@@ -1775,7 +1975,7 @@ label(domainadmingroup)
 bf(domain admin group (G))
 
 This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code.  It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list bf(Samba-ntdom) available by sending email to
@@ -1785,7 +1985,7 @@ label(domainadminusers)
 dit(bf(domain admin users (G)))
 
 This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list bf(Samba-ntdom) available by sending email to
@@ -1798,93 +1998,11 @@ This is a bf(DEPRECATED) parameter. It is currently not used within
 the Samba source and should be removed from all current smb.conf
 files. It is left behind for compatibility reasons.
 
-label(domaingroupmap)
-dit(bf(domain group map (G)))
-
-This option allows you to specify a file containing unique mappings
-of individual NT Domain Group names (in any domain) to UNIX group
-names.  This allows NT domain groups to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-
-This option is used in conjunction with link(bf('local group map'))(localgroupmap)
-and link(bf('domain user map'))(domainusermap).  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-
-
-The map file is parsed line by line.  If any line begins with a tt('#')
-or a tt(';') then it is ignored.  Each line should contain a single UNIX
-group name on the left then a single NT Domain Group name on the right,
-separated by a tabstop or tt('=').  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-
-tt(  UNIXgroupname     \\DOMAIN_NAME\\DomainGroupName )
-
-or:
-
-tt(  UNIXgroupname     DomainGroupName )
-
-In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
-or it is a member of a domain using link(bf("security = domain"))(security),
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
-
-Any UNIX groups that are em(NOT) specified in this map file are assumed to
-be either Local or Domain Groups, depending on the role of the Samba Server.
-
-In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
-will present em(ALL) such unspecified UNIX groups as its own NT Domain
-Groups, with the same name.
-
-In the case where Samba is member of a domain using
-link(bf("security = domain"))(security), Samba will check the UNIX name with
-its Domain Controller (see link(bf("password server"))(passwordserver))
-as if it was an NT Domain Group.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running bf(USRMGR.EXE) and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
-a local Workstation.
-
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you bf(want) to get fancy, however, you can.
-
-Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group em(REQUIRES) the following:
-
-startit()
-
-it() that the UNIX group exists on the UNIX server.
-
-it() that the NT Domain Group exists in the specified NT Domain
-
-it() that the UNIX Server knows about the specified Domain; 
-
-it() that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using link(bf('domain user map'))(domainusermap).
-
-endit()
-
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
-
-
 label(domaingroups)
 dit(bf(domain groups (G)))
 
 This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list bf(Samba-ntdom) available by sending email to
@@ -1894,7 +2012,7 @@ label(domainguestgroup)
 dit(bf(domain guest group (G)))
 
 This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list bf(Samba-ntdom) available by sending email to
@@ -1904,7 +2022,7 @@ label(domainguestusers)
 dit(bf(domain guest users (G)))
 
 This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It has been removed as of November 98.
+Samba NT Domain Controller Code. It may be removed in a later release.
 To work with the latest code builds that may have more support for
 Samba NT Domain Controller functionality please subscribe to the
 mailing list bf(Samba-ntdom) available by sending email to
@@ -1952,99 +2070,9 @@ special name for a link(bf(workgroup))(workgroup) before a Windows NT
 PDC is able to do so then cross subnet browsing will behave strangely
 and may fail.
 
-By default ("auto") Samba will attempt to become the domain master
-browser only if it is the Primary Domain Controller.
-
   bf(Default:)
-tt(    domain master = auto)
-
-  bf(Example:)
 tt(    domain master = no)
 
-
-label(domainusermap)
-dit(bf(domain user map (G)))
-
-This option allows you to specify a file containing unique mappings
-of individual NT Domain User names (in any domain) to UNIX user
-names.  This allows NT domain users to be presented correctly to
-NT systems, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-
-This option is used in conjunction with link(bf('local group map'))(localgroupmap)
-and link(bf('domain group map'))(domaingroupmap).  The use of these three
-options is trivial and often unnecessary in the case where Samba is
-not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-
-This option, which provides (and maintains) a one-to-one link between
-UNIX and NT users, is em(DIFFERENT) from link(bf('username map'))
-(usernamemap), which does em(NOT) maintain a distinction between the
-name(s) it can map to and the name it maps.
-
-
-The map file is parsed line by line.  If any line begins with a tt('#')
-or a tt(';') then the line is ignored.  Each line should contain a single UNIX
-user name on the left then a single NT Domain User name on the right,
-separated by a tabstop or tt('=').  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-
-tt(  UNIXusername      \\DOMAIN_NAME\\DomainUserName )
-
-or:
-
-tt(  UNIXusername      DomainUserName )
-
-In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
-or it is a member of a domain using link(bf("security = domain"))(security),
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
-
-Any UNIX users that are em(NOT) specified in this map file are assumed
-to be either Domain or Workstation Users, depending on the role of the
-Samba Server.
-
-In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
-will present em(ALL) such unspecified UNIX users as its own NT Domain
-Users, with the same name.
-
-In the case where Samba is a member of a domain using
-link(bf("security = domain"))(security), Samba will check the UNIX name with
-its Domain Controller (see link(bf("password server"))(passwordserver))
-as if it was an NT Domain User.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX users which also are not NT Domain
-Users are treated as Local Users in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Users,
-which are managed by running bf(USRMGR.EXE) and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
-a local Workstation.
-
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you bf(want) to get fancy, however, you can.
-
-Note that adding an entry to map an arbitrary NT User in an arbitrary
-Domain to an arbitrary UNIX user em(REQUIRES) the following:
-
-startit()
-
-it() that the UNIX user exists on the UNIX server.
-
-it() that the NT Domain User exists in the specified NT Domain.
-
-it() that the UNIX Server knows about the specified Domain.
-
-endit()
-
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
-
-
 label(dont descend)
 dit(bf(dont descend (S)))
 
@@ -2209,14 +2237,15 @@ label(forcecreatemode)
 dit(bf(force create mode (S)))
 
 This parameter specifies a set of UNIX mode bit permissions that will
-em(*always*) be set on a file created by Samba. This is done by
-bitwise 'OR'ing these bits onto the mode bits of a file that is being
-created. The default for this parameter is (in octal) 000. The modes
-in this parameter are bitwise 'OR'ed onto the file mode after the mask
-set in the link(bf("create mask"))(createmask) parameter is applied.
+em(*always*) be set on a file by Samba. This is done by bitwise
+'OR'ing these bits onto the mode bits of a file that is being created
+or having its permissions changed. The default for this parameter is
+(in octal) 000. The modes in this parameter are bitwise 'OR'ed onto
+the file mode after the mask set in the link(bf("create
+mask"))(createmask) parameter is applied.
 
 See also the parameter link(bf("create mask"))(createmask) for details
-on masking mode bits on created files.
+on masking mode bits on files.
 
   bf(Default:)
 tt(    force create mode = 000)
@@ -2252,6 +2281,39 @@ would force all created directories to have read and execute
 permissions set for 'group' and 'other' as well as the
 read/write/execute bits set for the 'user'.
 
+label(forcedirectorysecuritymode)
+dit(bf(force directory security mode (S)))
+
+This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a directory
+using the native NT security dialog box.
+
+This parameter is applied as a mask (OR'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a directory,
+the user has always set to be 'on'.
+
+If not set explicitly this parameter is set to the same value as the
+link(bf(force directory mode))(forcedirectorymode) parameter. To allow
+a user to modify all the user/group/world permissions on a directory,
+with restrictions set this parameter to 000.
+
+em(Note) that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0000.
+
+See also the link(bf(directory security mask))(directorysecuritymask),
+link(bf(security mask))(securitymask), link(bf(force security
+mode))(forcesecuritymode) parameters.
+
+  bf(Default:)
+tt(    force directory security mode = <same as force directory mode>)
+
+  bf(Example:)
+tt(    force directory security mode = 0)
+
 label(forcegroup)
 dit(bf(force group (S)))
 
@@ -2263,12 +2325,64 @@ permissions for this group to the files and directories within this
 service the Samba administrator can restrict or allow sharing of these
 files.
 
+In Samba 2.0.5 and above this parameter has extended functionality in the following
+way. If the group name listed here has a '+' character prepended to it
+then the current user accessing the share only has the primary group 
+default assigned to this group if they are already assigned as a member
+of that group. This allows an administrator to decide that only users
+who are already in a particular group will create files with group 
+ownership set to that group. This gives a finer granularity of ownership
+assignment. For example, the setting tt(force group = +sys) means
+that only users who are already in group sys will have their default
+primary group assigned to sys when accessing this Samba share. All
+other users will retain their ordinary primary group.
+
+If the link(bf("force user"))(forceuser) parameter is also set the
+group specified in bf(force group) will override the primary group
+set in link(bf("force user"))(forceuser).
+
+See also link(bf("force user"))(forceuser)
+
   bf(Default:)
 tt(    no forced group)
 
   bf(Example:)
 tt(    force group = agroup)
 
+label(forcesecuritymode)
+dit(bf(force security mode (S)))
+
+This parameter controls what UNIX permission bits can be modified when
+a Windows NT client is manipulating the UNIX permission on a file
+using the native NT security dialog box.
+
+This parameter is applied as a mask (OR'ed with) to the changed
+permission bits, thus forcing any bits in this mask that the user may
+have modified to be on. Essentially, one bits in this mask may be
+treated as a set of bits that, when modifying security on a file, the
+user has always set to be 'on'.
+
+If not set explicitly this parameter is set to the same value as the
+link(bf(force create mode))(forcecreatemode) parameter. To allow
+a user to modify all the user/group/world permissions on a file,
+with no restrictions set this parameter to 000.
+
+em(Note) that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0000.
+
+See also the link(bf(force directory security
+mode))(forcedirectorysecuritymode), link(bf(directory security
+mask))(directorysecuritymask), link(bf(security mask))(securitymask)
+parameters.
+
+  bf(Default:)
+tt(    force security mode = <same as force create mode>)
+
+  bf(Example:)
+tt(    force security mode = 0)
+
 label(forceuser)
 dit(bf(force user (S)))
 
@@ -2284,6 +2398,13 @@ tt("forced user"), no matter what username the client connected as.
 
 This can be very useful.
 
+In Samba 2.0.5 and above this parameter also causes the primary
+group of the forced user to be used as the primary group for all
+file activity. Prior to 2.0.5 the primary group was left as the
+primary group of the connecting user (this was a bug).
+
+See also link(bf("force group"))(forcegroup)
+
   bf(Default:)
 tt(    no forced user)
 
@@ -2427,7 +2548,7 @@ verb(
 tt(    hide files = /.*/DesktopFolderDB/TrashFor%m/resource.frk/)
 
 The above example is based on files that the Macintosh SMB client
-(DAVE) available from url(bf(Thursby))(www.thursby.com) creates for
+(DAVE) available from url(bf(Thursby))(http://www.thursby.com) creates for
 internal use, and also still hides all files beginning with a dot.
 
 label(homedirmap)
@@ -2460,12 +2581,74 @@ tt(     homedir map = amd.homedir)
 label(hostsallow)
 dit(bf(hosts allow (S)))
 
-Synonym for link(bf(allow hosts))(allowhosts).
+A synonym for this parameter is link(bf('allow hosts'))(allowhosts)
+
+This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service.
+
+If specified in the link(bf([global]))(global) section then it will
+apply to all services, regardless of whether the individual service
+has a different setting.
+
+You can specify the hosts by name or IP number. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like tt("allow hosts = 150.203.5."). The full syntax of the list is
+described in the man page bf(hosts_access (5)). Note that this man
+page may not be present on your system, so a brief description will
+be given here also.
+
+Note that the localhost address 127.0.0.1 will always be allowed
+access unless specifically denied by a "hosts deny" option.
+
+You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups. The em(EXCEPT) keyword can also
+be used to limit a wildcard list. The following examples may provide
+some help:
+
+bf(Example 1): allow all IPs in 150.203.*.* except one
+
+tt(    hosts allow = 150.203. EXCEPT 150.203.6.66)
+
+bf(Example 2): allow hosts that match the given network/netmask
+
+tt(    hosts allow = 150.203.15.0/255.255.255.0)
+
+bf(Example 3): allow a couple of hosts
+
+tt(    hosts allow = lapland, arvidsjaur)
+
+bf(Example 4): allow only hosts in NIS netgroup "foonet", but 
+deny access from one particular host
+
+tt(    hosts allow = @foonet)
+
+tt(    hosts deny = pirate)
+
+Note that access still requires suitable user-level passwords.
+
+See url(bf(testparm (1)))(testparm.1.html) for a way of testing your
+host access to see if it does what you expect.
+
+  bf(Default:)
+tt(    none (i.e., all hosts permitted access))
+
+  bf(Example:)
+tt(    allow hosts = 150.203.5. myhost.mynet.edu.au)
+
 
 label(hostsdeny)
 dit(bf(hosts deny (S)))
 
-Synonym for link(bf(denyhosts))(denyhosts).
+The opposite of link(bf('hosts allow'))(hostsallow) - hosts listed
+here are em(NOT) permitted access to services unless the specific
+services have their own lists to override this one. Where the lists
+conflict, the link(bf('allow'))(hostsallow) list takes precedence.
+
+  bf(Default:)
+tt(    none (i.e., no hosts specifically excluded))
+
+  bf(Example:)
+tt(    hosts deny = 150.203.4. badhost.mynet.edu.au)
 
 label(hostsequiv)
 dit(bf(hosts equiv (G)))
@@ -2474,7 +2657,7 @@ If this global parameter is a non-null string, it specifies the name
 of a file to read for the names of hosts and users who will be allowed
 access without specifying a password.
 
-This is not be confused with link(bf(allow hosts))(allowhosts) which
+This is not be confused with link(bf(hosts allow))(hostsallow) which
 is about hosts access to services and is more useful for guest
 services. bf(hosts equiv) may be useful for NT clients which will not
 supply passwords to samba.
@@ -2504,28 +2687,39 @@ link(bf(%P))(percentP) and link(bf(%S))(percentS).
 label(interfaces)
 dit(bf(interfaces (G)))
 
-This option allows you to setup multiple network interfaces, so that
-Samba can properly handle browsing on all interfaces.
-
-The option takes a list of ip/netmask pairs. The netmask may either be
-a bitmask, or a bitlength.
+This option allows you to override the default network interfaces list
+that Samba will use for browsing, name registration and other NBT
+traffic. By default Samba will query the kernel for the list of all
+active interfaces and use any interfaces except 127.0.0.1 that are
+broadcast capable.
 
-For example, the following line:
+The option takes a list of interface strings. Each string can be in
+any of the following forms:
 
-tt(interfaces = 192.168.2.10/24 192.168.3.10/24)
+startit()
+it() a network interface name (such as eth0). This may include
+     shell-like wildcards so eth* will match any interface starting
+     with the substring "eth"
+if() a IP address. In this case the netmask is determined
+     from the list of interfaces obtained from the kernel
+if() a IP/mask pair. 
+if() a broadcast/mask pair. 
+endit()
 
-would configure two network interfaces with IP addresses 192.168.2.10
-and 192.168.3.10. The netmasks of both interfaces would be set to
-255.255.255.0.
+The "mask" parameters can either be a bit length (such as 24 for a C
+class network) or a full netmask in dotted decmal form.
 
-You could produce an equivalent result by using:
+The "IP" parameters above can either be a full dotted decimal IP
+address or a hostname which will be looked up via the OSes normal
+hostname resolution mechanisms.
 
-tt(interfaces = 192.168.2.10/255.255.255.0 192.168.3.10/255.255.255.0)
+For example, the following line:
 
-if you prefer that format.
+tt(interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0)
 
-If this option is not set then Samba will attempt to find a primary
-interface, but won't attempt to configure more than one interface.
+would configure three network interfaces corresponding to the eth0
+device and IP addresses 192.168.2.10 and 192.168.3.10. The netmasks of
+the latter two interfaces would be set to 255.255.255.0.
 
 See also link(bf("bind interfaces only"))(bindinterfacesonly).
 
@@ -2576,10 +2770,10 @@ options"))(socketoptions)). Basically you should only use this option
 if you strike difficulties.
 
   bf(Default:)
-tt(    keep alive = 0)
+tt(    keepalive = 0)
 
   bf(Example:)
-tt(    keep alive = 60)
+tt(    keepalive = 60)
 
 label(kerneloplocks)
 dit(bf(kernel oplocks (G)))
@@ -2598,55 +2792,76 @@ This parameter defaults to em("On") on systems that have the support,
 and em("off") on systems that don't. You should never need to touch
 this parameter.
 
-label(ldapbindas)
-dit(bf(ldap bind as (G)))
+See also the link(bf("oplocks"))(oplocks) and link(bf("level2 oplocks"))(level2oplocks)
+parameters.
+
+label(ldapfilter)
+dit(bf(ldap filter (G)))
 
 This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the bf(--with-ldap)
-option.
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the bf(--with-ldap) option.
 
-This parameter specifies the entity to bind to an LDAP directory as.
-Usually it should be safe to use the LDAP root account; for larger
-installations it may be preferable to restrict Samba's access. See also
-link(bf(ldap passwd file))(ldappasswdfile).
+This parameter specifies an LDAP search filter used to search for a
+user name in the LDAP database. It must contain the string
+link(bf(%u))(percentU) which will be replaced with the user being
+searched for.
 
   bf(Default:)
-tt(    none (bind anonymously))
+tt(    empty string.)
 
-  bf(Example:)
-tt(    ldap bind as = "uid=root, dc=mydomain, dc=org")
-
-label(ldappasswdfile)
-dit(bf(ldap passwd file (G)))
+label(ldapport)
+dit(bf(ldap port (G)))
 
 This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the bf(--with-ldap)
-option.
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the bf(--with-ldap) option.
 
-This parameter specifies a file containing the password with which
-Samba should bind to an LDAP server. For obvious security reasons
-this file must be set to mode 700 or less.
+This parameter specifies the TCP port number to use to contact
+the LDAP server on.
 
   bf(Default:)
-tt(    none (bind anonymously))
+tt(    ldap port = 389.)
 
-  bf(Example:)
-tt(    ldap passwd file = /usr/local/samba/private/ldappasswd)
+label(ldaproot)
+dit(bf(ldap root (G)))
 
-label(ldapport)
-dit(bf(ldap port (G)))
+This parameter is part of the em(EXPERIMENTAL) Samba support for a
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the bf(--with-ldap) option.
+
+This parameter specifies the entity to bind to the LDAP server
+as (essentially the LDAP username) in order to be able to perform
+queries and modifications on the LDAP database.
+
+See also link(bf(ldap root passwd))(ldaprootpasswd).
+
+  bf(Default:)
+tt(    empty string (no user defined))
+
+label(ldaprootpasswd)
+dit(bf(ldap root passwd (G)))
 
 This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server. These options are only
-available if your version of Samba was configured with the bf(--with-ldap)
-option.
+password database stored on an LDAP server back-end. These options
+are only available if your version of Samba was configured with
+the bf(--with-ldap) option.
+
+This parameter specifies the password for the entity to bind to the
+LDAP server as (the password for this LDAP username) in order to be
+able to perform queries and modifications on the LDAP database.
+
+em(BUGS:) This parameter should em(NOT) be a readable parameter
+in the bf(smb.conf) file and will be removed once a correct
+storage place is found.
 
-This parameter specifies the TCP port number of the LDAP server.
+See also link(bf(ldap root))(ldaproot).
 
   bf(Default:)
-tt(    ldap port = 389.)
+tt(    empty string.)
 
 label(ldapserver)
 dit(bf(ldap server (G)))
@@ -2657,8 +2872,7 @@ are only available if your version of Samba was configured with
 the bf(--with-ldap) option.
 
 This parameter specifies the DNS name of the LDAP server to use
-when storing and retrieving information about Samba users and
-groups.
+for SMB/CIFS authentication purposes.
 
   bf(Default:)
 tt(    ldap server = localhost)
@@ -2671,15 +2885,53 @@ password database stored on an LDAP server back-end. These options
 are only available if your version of Samba was configured with
 the bf(--with-ldap) option.
 
-This parameter specifies the node of the LDAP tree beneath which
-Samba should store its information. This parameter MUST be provided
-when using LDAP with Samba.
+This parameter specifies the tt("dn") or LDAP em("distinguished name")
+that tells url(bf(smbd))(smbd.8.html) to start from when searching
+for an entry in the LDAP password database.
 
   bf(Default:)
-tt(    none)
+tt(    empty string.)
+
+label(level2oplocks)
+dit(bf(level2 oplocks (S)))
+
+This parameter (new in Samba 2.0.5) controls whether Samba supports
+level2 (read-only) oplocks on a share. In Samba 2.0.4 this parameter
+defaults to "False" as the code is new, but will default to "True"
+in a later release.
+
+Level2, or read-only oplocks allow Windows NT clients that have an
+oplock on a file to downgrade from a read-write oplock to a read-only
+oplock once a second client opens the file (instead of releasing all
+oplocks on a second open, as in traditional, exclusive oplocks). This
+allows all openers of the file that support level2 oplocks to cache
+the file for read-ahead only (ie. they may not cache writes or lock
+requests) and increases performance for many acesses of files that
+are not commonly written (such as application .EXE files).
+
+Once one of the clients which have a read-only oplock writes to
+the file all clients are notified (no reply is needed or waited
+for) and told to break their oplocks to "none" and delete any
+read-ahead caches.
+
+It is recommended that this parameter be turned on to speed access
+to shared executables (and also to test the code :-).
+
+For more discussions on level2 oplocks see the CIFS spec.
+
+Currently, if link(bf("kernel oplocks"))(kerneloplocks) are supported
+then level2 oplocks are not granted (even if this parameter is set
+to tt("true")). Note also, the link(bf("oplocks"))(oplocks) parameter must
+be set to "true" on this share in order for this parameter to have any
+effect.
+
+See also the link(bf("oplocks"))(oplocks) and link(bf("kernel oplocks"))(kerneloplocks) parameters.
+
+  bf(Default:)
+tt( level2 oplocks = False)
 
   bf(Example:)
-tt(    ldap suffix = "dc=mydomain, dc=org")
+tt( level2 oplocks = True)
 
 label(lmannounce)
 dit(bf(lm announce (G)))
@@ -2735,88 +2987,6 @@ tt(      load printers = yes)
   bf(Example:)
 tt(    load printers = no)
 
-label(localgroupmap)
-dit(bf(local group map (G)))
-
-This option allows you to specify a file containing unique mappings
-of individual NT Local Group names (in any domain) to UNIX group
-names.  This allows NT Local groups (aliases) to be presented correctly to
-NT users, despite the lack of native support for the NT Security model
-(based on VAX/VMS) in UNIX.  The reader is advised to become familiar
-with the NT Domain system and its administration.
-
-This option is used in conjunction with link(bf('domain group map'))(domaingroupmap)
-and link(bf('domain name map'))(domainusermap).  The use of these three
-options is trivial and often unnecessary in the case where Samba
-is not expected to interact with any other SAM databases (whether local
-workstations or Domain Controllers).
-
-
-The map file is parsed line by line.  If any line begins with a tt('#')
-or a tt(';') then it is ignored.  Each line should contain a single UNIX
-group name on the left then a single NT Local Group name on the right,
-separated by a tabstop or tt('=').  If either name contains spaces then
-it should be enclosed in quotes.
-The line can be either of the form:
-
-tt(  UNIXgroupname     \\DOMAIN_NAME\\LocalGroupName )
-
-or:
-
-tt(  UNIXgroupname     LocalGroupName )
-
-In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
-or it is a member of a domain using link(bf("security = domain"))(security),
-the latter format can be used: the default Domain name is the Samba Server's
-Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
-
-Any UNIX groups that are em(NOT) specified in this map file are treated
-as either Local or Domain Groups depending on the role of the Samba Server.
-
-In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
-will present em(ALL) unspecified UNIX groups as its own NT Domain
-Groups, with the same name, and em(NOT) as Local Groups.
-
-In the case where Samba is member of a domain using
-link(bf("security = domain"))(security), Samba will check the UNIX name with
-its Domain Controller (see link(bf("password server"))(passwordserver))
-as if it was an NT Domain Group.  If the Domain Controller says that it is not,
-such unspecified (unmapped) UNIX groups which also are not NT Domain
-Groups are treated as Local Groups in the Samba Server's local SAM database.
-NT Administrators will recognise these as Workstation Local Groups,
-which are managed by running bf(USRMGR.EXE) and selecting a remote
-Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
-a local Workstation.
-
-This may sound complicated, but it means that a Samba Server as
-either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
-will act like an NT Workstation (with a local SAM database) or an NT PDC
-(with a Domain SAM database) respectively, without the need for any of
-the map files at all.  If you bf(want) to get fancy, however, you can.
-
-Note that adding an entry to map an arbitrary NT group in an arbitrary
-Domain to an arbitrary UNIX group em(REQUIRES) the following:
-
-startit()
-
-it() that the UNIX group exists on the UNIX server.
-
-it() that the NT Domain Group exists in the specified NT Domain
-
-it() that the UNIX Server knows about the specified Domain; 
-
-it() that all the UNIX users (who are expecting to access the Samba
-Server as the correct NT user and with the correct NT group permissions)
-in the UNIX group be mapped to the correct NT Domain users in the specified
-NT Domain using link(bf('domain user map'))(domainusermap).
-
-endit()
-
-Failure to meet any of these requirements may result in either (or
-both) errors reported in the log files or (and) incorrect or missing
-access rights granted to users.
-
-
 label(localmaster)
 dit(bf(local master (G)))
 
@@ -3240,6 +3410,13 @@ dit(bf(mangle case (S)))
 
 See the section on link(bf("NAME MANGLING"))(NAMEMANGLING).
 
+label(manglelocks)
+dit(bf(mangle locks (S)))
+
+This option is was introduced with Samba 2.0.4 and above and has been
+removed in Samba 2.0.6 as Samba now dynamically configures such things
+on 32 bit systems.
+
 label(mangledmap)
 dit(bf(mangled map (S)))
 
@@ -3542,7 +3719,7 @@ never need to set this parameter.
 tt(    max mux = 50)
 
 label(maxopenfiles)
-dit(bf(maxopenfiles (G)))
+dit(bf(max open files (G)))
 
 This parameter limits the maximum number of open files that one
 url(bf(smbd))(smbd.8.html) file serving process may have open for
@@ -3676,6 +3853,20 @@ tt(      min print space = 0)
   bf(Example:)
 tt(    min print space = 2000)
 
+label(minpasswdlength)
+dit(bf(min passwd length (G)))
+
+This option sets the minimum length in characters of a plaintext password
+than smbd will accept when performing UNIX password changing.
+
+See also link(bf("unix password sync"))(unixpasswordsync),
+link(bf("passwd program"))(passwdprogram) and link(bf("passwd chat
+debug"))(passwdchatdebug).
+
+  bf(Default:)
+tt(    min passwd length = 5)
+
+
 label(minwinsttl)
 dit(bf(min wins ttl (G)))
 
@@ -3703,11 +3894,16 @@ names to be resolved as follows :
 startit()
 
 it() bf(lmhosts) : Lookup an IP address in the Samba lmhosts file.
+If the line in lmhosts has no name type attached to the NetBIOS
+name (see the url(bf(lmhosts (5)))(lmhosts.5.html) for details) then
+any name type matches for lookup.
 
 it() bf(host) : Do a standard host name to IP address resolution,
 using the system /etc/hosts, NIS, or DNS lookups. This method of name
 resolution is operating system depended for instance on IRIX or
 Solaris this may be controlled by the em(/etc/nsswitch.conf) file).
+Note that this method is only used if the NetBIOS name type being
+queried is the 0x20 (server) name type, otherwise it is ignored.
 
 it() bf(wins) : Query a name with the IP address listed in the
 link(bf(wins server))(winsserver) parameter. If no WINS server has
@@ -3798,6 +3994,18 @@ tt(      nis homedir = false)
   bf(Example:)
 tt(    nis homedir = true)
 
+label(ntaclsupport)
+dit(bf(nt acl support (G)))
+
+This boolean parameter controls whether url(bf(smbd))(smbd.8.html)
+will attempt to map UNIX permissions into Windows NT access control lists.
+
+  bf(Default:)
+tt(    nt acl support = yes)
+
+  bf(Example:)
+tt(    nt acl support = no)
+
 label(ntpipesupport)
 dit(bf(nt pipe support (G)))
 
@@ -3902,12 +4110,48 @@ all access to oplocked files, whether it be via Samba or NFS or a local
 UNIX process. See the link(bf(kernel oplocks))(kerneloplocks) parameter
 for details.
 
+See also the link(bf("kernel oplocks"))(kerneloplocks) and
+link(bf("level2 oplocks"))(level2oplocks) parameters.
+
   bf(Default:)
 tt(    oplocks = True)
 
   bf(Example:)
 tt(    oplocks = False)
 
+label(oplockbreakwaittime)
+dit(bf(oplock break wait time (G)))
+
+This is a tuning parameter added due to bugs in both Windows 9x and WinNT.
+If Samba responds to a client too quickly when that client issues an SMB that
+can cause an oplock break request, then the client redirector can fail and
+not respond to the break request. This tuning parameter (which is set in
+milliseconds) is the amount of time Samba will wait before sending an
+oplock break request to such (broken) clients.
+
+em(DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE).
+
+  bf(Default:)
+tt(    oplock break wait time = 10)
+
+label(oplockcontentionlimit)
+dit(bf(oplock contention limit (S)))
+
+This is a em(very) advanced url(bf(smbd))(smbd.8.html) tuning option to improve
+the efficiency of the granting of oplocks under multiple client contention for the same file.
+
+In brief it specifies a number, which causes smbd not to grant an oplock even
+when requested if the approximate number of clients contending for an oplock on
+the same file goes over this limit. This causes url(bf(smbd))(smbd.8.html) to
+behave in a similar way to Windows NT.
+
+em(DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
+OPLOCK CODE).
+
+  bf(Default:)
+tt( oplock contention limit = 2)
+
 label(oslevel)
 dit(bf(os level (G)))
 
@@ -3915,12 +4159,12 @@ This integer value controls what level Samba advertises itself as for
 browse elections. The value of this parameter determines whether
 url(bf(nmbd))(nmbd.8.html) has a chance of becoming a local master
 browser for the link(bf(WORKGROUP))(workgroup) in the local broadcast
-area. Setting this to zero will cause url(bf(nmbd))(nmbd.8.html) to
-always lose elections to Windows machines. See BROWSING.txt in the
-Samba docs/ directory for details.
+area. The default is zero, which means url(bf(nmbd))(nmbd.8.html) will
+lose elections to Windows machines. See BROWSING.txt in the Samba
+docs/ directory for details.
 
   bf(Default:)
-tt(    os level = 32)
+tt(    os level = 20)
 
   bf(Example:)
 tt(    os level = 65    ; This will win against any NT Server)
@@ -4123,7 +4367,7 @@ better restrict them with hosts allow!
 If the link(bf("security"))(security) parameter is set to
 bf("domain"), then the list of machines in this option must be a list
 of Primary or Backup Domain controllers for the
-link(bf(Domain))(workgroup), as the Samba server is cryptographicly
+link(bf(Domain))(workgroup) or the character tt(*), as the Samba server is cryptographicly
 in that domain, and will use cryptographicly authenticated RPC calls
 to authenticate the user logging on. The advantage of using
 link(bf("security=domain"))(securityequaldomain) is that if you list
@@ -4131,6 +4375,12 @@ several hosts in the bf("password server") option then
 url(bf(smbd))(smbd.8.html) will try each in turn till it finds one
 that responds. This is useful in case your primary server goes down.
 
+If the bf("password server") option is set to the character tt(*),
+then Samba will attempt to auto-locate the Primary or Backup Domain controllers
+to authenticate against by doing a query for the name tt(WORKGROUP<1C>)
+and then contacting each server returned in the list of IP addresses
+from the link(bf(name resolution))(nameresolveorder) source.
+
 If the link(bf("security"))(security) parameter is set to
 link(bf("server"))(securityequalserver), then there are different
 restrictions that link(bf("security=domain"))(securityequaldomain)
@@ -4163,6 +4413,9 @@ tt(       password server = <empty string>)
   bf(Example:)
 tt(    password server = NT-PDC, NT-BDC1, NT-BDC2)
 
+  bf(Example:)
+tt(    password server = *)
+
 label(path)
 dit(bf(path (S)))
 
@@ -4243,7 +4496,7 @@ verb(
 
 Of course, this could get annoying after a while :-)
 
-See also link(bf(postexec))(postexec).
+See also link(bf(preexec close))(preexecclose) and link(bf(postexec))(postexec).
 
   bf(Default:)
 tt(    none (no command executed))
@@ -4251,6 +4504,18 @@ tt(      none (no command executed))
   bf(Example:)
 tt(        preexec = echo \"%u connected to %S from %m (%I)\" >> /tmp/log)
 
+label(preexecclose)
+dit(bf(preexec close (S)))
+
+This boolean option controls whether a non-zero return code from
+link(bf("preexec"))(preexec) should close the service being connected to.
+
+  bf(Default:)
+tt(    preexec close = no)
+
+  bf(Example:)
+tt(    preexec close = yes)
+
 label(preferredmaster)
 dit(bf(preferred master (G)))
 
@@ -4262,8 +4527,7 @@ force an election, and it will have a slight advantage in winning the
 election.  It is recommended that this parameter is used in
 conjunction with link(bf("domain master = yes"))(domainmaster), so
 that url(bf(nmbd))(nmbd.8.html) can guarantee becoming a domain
-master. Indeed the default ("auto") enables "preferred master" if
-Samba is configured as the domain master browser.
+master.
 
 Use this option with caution, because if there are several hosts
 (whether Samba servers, Windows 95 or NT) that are preferred master
@@ -4275,7 +4539,7 @@ capabilities.
 See also link(bf(os level))(oslevel).
 
   bf(Default:)
-tt(    preferred master = auto)
+tt(    preferred master = no)
 
   bf(Example:)
 tt(    preferred master = yes)
@@ -4314,16 +4578,11 @@ command you specify should remove the spool file when it has been
 processed, otherwise you will need to manually remove old spool files.
 
 The print command is simply a text string. It will be used verbatim,
-with two exceptions: All occurrences of tt("%s") will be replaced by
-the appropriate spool file name, and all occurrences of tt("%p") will
-be replaced by the appropriate printer name. The spool file name is
-generated automatically by the server, the printer name is discussed
-below.
-
-The full path name will be used for the filename if tt("%s") is not
-preceded by a tt('/'). If you don't like this (it can stuff up some
-lpq output) then use tt("%f") instead. Any occurrences of tt("%f") get
-replaced by the spool filename without the full path at the front.
+with two exceptions: All occurrences of tt("%s") and tt("%f") will be
+replaced by the appropriate spool file name, and all occurrences of
+tt("%p") will be replaced by the appropriate printer name. The spool
+file name is generated automatically by the server, the printer name
+is discussed below.
 
 The print command em(MUST) contain at least one occurrence of tt("%s")
 or tt("%f") - the tt("%p") is optional. At the time a job is
@@ -4721,14 +4980,14 @@ This overlapping works best when the speeds of disk and network access
 are similar, having very little effect when the speed of one is much
 greater than the other.
 
-The default value is 2048, but very little experimentation has been
+The default value is 16384, but very little experimentation has been
 done yet to determine the optimal value, and it is likely that the
 best value will vary greatly between systems anyway. A value over
 65536 is pointless and will cause you to allocate memory
 unnecessarily.
 
   bf(Default:)
-tt(    read size = 2048)
+tt(    read size = 16384)
 
   bf(Example:)
 tt(    read size = 8192)
@@ -4802,6 +5061,39 @@ tt(      remote browse sync = <empty string>)
   bf(Example:)
 tt(    remote browse sync = 192.168.2.255 192.168.4.255)
 
+
+label(restrict anonymous)
+dit(bf(restrict anonymous (G)))
+
+This is a boolean parameter.  If it is true, then anonymous access
+to the server will be restricted, namely in the case where the server
+is expecting the client to send a username, but it doesn't.  Setting
+it to true will force these anonymous connections to be denied, and
+the client will be required to always supply a username and password
+when connecting. Use of this parameter is only recommened for homogenous 
+NT client environments.
+
+This parameter makes the use of macro expansions that rely
+on the username (%U, %G, etc) consistant.  NT 4.0 likes to use
+anonymous connections when refreshing the share list, and this
+is a way to work around that.
+
+When restrict anonymous is true, all anonymous connections are denied
+no matter what they are for.  This can effect the ability of a machine
+to access the samba Primary Domain Controller to revalidate it's machine
+account after someone else has logged on the client interactively.  The
+NT client will display a message saying that the machine's account in 
+the domain doesn't exist or the password is bad.  The best way to deal 
+with this is to reboot NT client machines between interactive logons, 
+using "Shutdown and Restart", rather than "Close all programs and logon 
+as a different user".
+
+  bf(Default:)
+tt(     restrict anonymous = false)
+
+  bf(Example:)
+tt(     restrict anonymous = true)
+
 label(revalidate)
 dit(bf(revalidate (S)))
 
@@ -4878,7 +5170,16 @@ This is the same as the link(bf("preexec"))(preexec) parameter except
 that the command is run as root. This is useful for mounting
 filesystems (such as cdroms) before a connection is finalized.
 
-See also link(bf("preexec"))(preexec).
+See also link(bf("preexec"))(preexec)
+and link(bf("root preexec close"))(rootpreexecclose).
+
+label(rootpreexecclose)
+dit(bf(root preexec close (S)))
+
+This is the same as the link(bf("preexec close"))(preexecclose) parameter
+except that the command is run as root.
+
+See also link(bf("preexec"))(preexec), link(bf("preexec close"))(preexecclose).
 
 label(security)
 dit(bf(security (G)))
@@ -5079,7 +5380,7 @@ users into the link(bf("guest account"))(guestaccount). See the
 link(bf("map to guest"))(maptoguest) parameter for details on
 doing this.
 
-e,(BUG:) There is currently a bug in the implementation of
+em(BUG:) There is currently a bug in the implementation of
 bf("security=domain) with respect to multi-byte character
 set usernames. The communication with a Domain Controller
 must be done in UNICODE and Samba currently does not widen
@@ -5101,6 +5402,40 @@ tt(      security = USER)
   bf(Example:)
 tt(    security = DOMAIN)
 
+label(securitymask)
+dit(bf(security mask (S)))
+
+This parameter controls what UNIX permission bits can be modified
+when a Windows NT client is manipulating the UNIX permission on a
+file using the native NT security dialog box.
+
+This parameter is applied as a mask (AND'ed with) to the changed
+permission bits, thus preventing any bits not in this mask from
+being modified. Essentially, zero bits in this mask may be treated
+as a set of bits the user is not allowed to change.
+
+If not set explicitly this parameter is set to the same value as the
+link(bf(create mask))(createmask) parameter. To allow a user to
+modify all the user/group/world permissions on a file, set this
+parameter to 0777.
+
+em(Note) that users who can access the Samba server through other
+means can easily bypass this restriction, so it is primarily
+useful for standalone "appliance" systems.  Administrators of
+most normal systems will probably want to set it to 0777.
+
+See also the link(bf(force directory security
+mode))(forcedirectorysecuritymode), link(bf(directory security
+mask))(directorysecuritymask), link(bf(force security
+mode))(forcesecuritymode) parameters.
+
+  bf(Default:)
+tt(    security mask = <same as create mask>)
+
+  bf(Example:)
+tt(    security mask = 0777)
+
+
 label(serverstring)
 dit(bf(server string (G)))
 
@@ -5170,6 +5505,9 @@ users reporting strange problems trying to save files (locking errors)
 and error messages in the smbd log looking like tt("ERROR
 smb_shm_alloc : alloc of XX bytes failed").
 
+If your OS refuses the size that Samba asks for then Samba will try a
+smaller size, reducing by a factor of 0.8 until the OS accepts it.
+
   bf(Default:)
 tt(    shared mem size = 1048576)
 
@@ -5691,9 +6029,12 @@ dit(bf(syslog (G)))
 This parameter maps how Samba debug messages are logged onto the
 system syslog logging levels. Samba debug level zero maps onto syslog
 LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-to LOG_NOTICE, debug level three maps onto LOG_INFO.  The parameter
-sets the threshold for doing the mapping, all Samba debug messages
-above this threshold are mapped to syslog LOG_DEBUG messages.
+onto LOG_NOTICE, debug level three maps onto LOG_INFO. All higher 
+levels are mapped to LOG_DEBUG.
+
+This paramter sets the threshold for sending messages to syslog. 
+Only messages with debug level less than this value will be sent 
+to syslog.
 
   bf(Default:)
 tt(    syslog = 1)
@@ -5933,17 +6274,6 @@ Windows machines to those that the UNIX box uses. The other is to map
 multiple users to a single username so that they can more easily share
 files.
 
-The use of this option, therefore, relates to UNIX usernames
-and not Windows (specifically NT Domain) usernames.  In other words,
-once a name has been mapped using this option, the Samba server uses
-the mapped name for internal em(AND) external purposes.
-
-This option is em(DIFFERENT) from the link(bf("domain user map"))(domainusermap) 
-parameter, which maintains a one-to-one mapping between UNIX usernames
-and NT Domain Usernames: more specifically, the Samba server maintains
-a link between em(BOTH) usernames, presenting the NT username to the
-external NT world, and using the UNIX username internally.
-
 The map file is parsed line by line. Each line should contain a single
 UNIX username on the left then a tt('=') followed by a list of
 usernames on the right. The list of usernames on the right may contain
@@ -6020,7 +6350,7 @@ tt(       no username map)
 tt(    username map = /usr/local/samba/lib/users.map)
 
 label(validchars)
-dit(bf(valid chars (S)))
+dit(bf(valid chars (G)))
 
 The option allows you to specify additional characters that should be
 considered valid by the server in filenames. This is particularly
@@ -6194,6 +6524,10 @@ directory tree exported by the server are always allowed; this
 parameter controls access only to areas that are outside the directory
 tree being exported.
 
+Note that setting this parameter can have a negative effect on your
+server performance due to the extra system calls that Samba has to
+do in order to perform the link checks.
+
   bf(Default:)
 tt(    wide links = yes)
 
@@ -6216,7 +6550,7 @@ dit(bf(wins server (G)))
 This specifies the IP address (or DNS name: IP address for preference)
 of the WINS server that url(bf(nmbd))(nmbd.8.html) should register with.
 If you have a WINS server on your network then you should set this to
-the WINS server's IP.
+the WINS server's IP.        
 
 You should point this at your WINS server if you have a
 multi-subnetted network.
@@ -6233,6 +6567,42 @@ tt(      wins server = )
   bf(Example:)
 tt(    wins server = 192.9.200.1)
 
+label(winshook)
+dit(bf(wins hook (G)))
+
+When Samba is running as a WINS server this allows you to call an
+external program for all changes to the WINS database. The primary use
+for this option is to allow the dynamic update of external name
+resolution databases such as dynamic DNS.
+
+The wins hook parameter specifies the name of a script or executable
+that will be called as follows:
+
+   wins_hook operation name nametype ttl IP_list
+
+The first argument is the operation and is one of "add", "delete",
+or "refresh". In most cases the operation can be ignored as the rest
+of the parameters provide sufficient information. Note that "refresh"
+may sometimes be called when the name has not previously been added,
+in that case it should be treated as an add.
+
+The second argument is the netbios name. If the name is not a legal
+name then the wins hook is not called. Legal names contain only
+letters, digits, hyphens, underscores and periods.
+
+The third argument is the netbios name type as a 2 digit hexadecimal
+number. 
+
+The fourth argument is the TTL (time to live) for the name in seconds.
+
+The fifth and subsequent arguments are the IP addresses currently
+registered for that name. If this list is empty then the name should
+be deleted.
+
+An example script that calls the BIND dynamic DNS update program
+"nsupdate" is provided in the examples directory of the Samba source
+code. 
+
 label(winssupport)
 dit(bf(wins support (G)))
 
@@ -6264,7 +6634,6 @@ label(writable)
 dit(bf(writable (S)))
 
 Synonym for link(bf("writeable"))(writeable) for people who can't spell :-).
-Pronounced "ritter-bull".
 
 label(writelist)
 dit(bf(write list (S)))
@@ -6323,6 +6692,8 @@ verb(
        write ok = yes
 )
 
+endit()
+
 label(WARNINGS)
 manpagesection(WARNINGS)
 
index 327e47c7a2b1403dc1479c1b658a57c695f16998..a2d14209b995ff932fd965407cf537d2d017ac56 100644 (file)
@@ -8,7 +8,7 @@ manpagename(smbclient)(ftp-like client to access SMB/CIFS resources on servers)
 label(SYNOPSIS)
 manpagesynopsis()
 
-bf(smbclient) link(servicename)(servicename) [link(password)(password)] [link(-s smb.conf)(minuss)] [link(-B IP addr)(minusB)] [link(-O socket options)(minusO)][link(-R name resolve order)(minusR)] [link(-M NetBIOS name)(minusM)] [link(-i scope)(minusi)] [link(-N)(minusN)] [link(-n NetBIOS name)(minusn)] [link(-d debuglevel)(minusd)] [link(-P)(minusP)] [link(-p port)(minusp)] [link(-l log basename)(minusl)] [link(-h)(minush)] [link(-I dest IP)(minusI)] [link(-E)(minusE)] [link(-U username)(minusU)] [link(-L NetBIOS name)(minusL)] [link(-t terminal code)(minust)] [link(-m max protocol)(minusm)] [link(-W workgroup)(minusW)] [link(-T<c|x>IXFqgbNan)(minusT)] [link(-D directory)(minusD)] [link(-c command string)(minusc)]
+bf(smbclient) link(servicename)(servicename) [link(-s smb.conf)(minuss)] [link(-O socket options)(minusO)][link(-R name resolve order)(minusR)] [link(-M NetBIOS name)(minusM)] [link(-i scope)(minusi)] [link(-N)(minusN)] [link(-n NetBIOS name)(minusn)] [link(-d debuglevel)(minusd)] [link(-P)(minusP)] [link(-p port)(minusp)] [link(-l log basename)(minusl)] [link(-h)(minush)] [link(-I dest IP)(minusI)] [link(-E)(minusE)] [link(-U username)(minusU)] [link(-L NetBIOS name)(minusL)] [link(-t terminal code)(minust)] [link(-m max protocol)(minusm)] [link(-b buffersize)(minusb)] [link(-W workgroup)(minusW)] [link(-T<c|x>IXFqgbNan)(minusT)] [link(-D directory)(minusD)] [link(-c command string)(minusc)]
 
 label(DESCRIPTION)
 manpagedescription()
@@ -71,9 +71,6 @@ Samba configuration file, smb.conf. This file controls all aspects of
 the Samba setup on the machine and smbclient also needs to read this
 file.
 
-label(minusB)
-dit(bf(-B IP addr)) The IP address to use when sending a broadcast packet.
-
 label(minusO)
 dit(bf(-O socket options)) TCP socket options to set on the client
 socket. See the url(socket options)(smb.conf.5.html#socketoptions)
@@ -107,8 +104,7 @@ it() bf(bcast) : Do a broadcast on each of the known local interfaces
 listed in the url(bf(interfaces))(smb.conf.5.html#interfaces) parameter
 in the smb.conf file. This is the least reliable of the name resolution
 methods as it depends on the target host being on a locally connected
-subnet. To specify a particular broadcast address the link(bf(-B))(minusB) option 
-may be used.
+subnet. 
 
 endit()
 
@@ -286,7 +282,7 @@ nothing before or nothing after the percent symbol will cause an empty
 username or an empty password to be used, respectively.
 
 The password may also be specified by setting up an environment
-variable called tt(PASSWORD) that contains the users password. Note
+variable called tt(PASSWD) that contains the users password. Note
 that this may be very insecure on some systems but on others allows
 users to script smbclient commands without having a password appear in
 the command line of a process listing.
@@ -296,7 +292,7 @@ on an uppercase password. Lowercase or mixed case passwords may be
 rejected by these servers.
 
 Be cautious about including passwords in scripts or in the
-tt(PASSWORD) environment variable. Also, on many systems the command
+tt(PASSWD) environment variable. Also, on many systems the command
 line of a running process may be seen via the tt(ps) command to be
 safe always allow smbclient to prompt for a password and type it in
 directly.
@@ -328,6 +324,12 @@ protocols level the server supports. This parameter is
 preserved for backwards compatibility, but any string
 following the bf(-m) will be ignored.
 
+label(minusb)
+dit(bf(-b buffersize)) This option changes the transmit/send buffer
+size when getting or putting a file from/to the server. The default
+is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
+observed to speed up file transfers to and from a Win9x server.
+
 label(minusW)
 dit(bf(-W WORKGROUP)) Override the default workgroup specified in the
 url(bf(workgroup))(smb.conf.5.html#workgroup) parameter of the
@@ -683,7 +685,7 @@ The variable bf(USER) may contain the username of the person using the
 client.  This information is used only if the protocol level is high
 enough to support session-level passwords.
 
-The variable bf(PASSWORD) may contain the password of the person using
+The variable bf(PASSWD) may contain the password of the person using
 the client.  This information is used only if the protocol level is
 high enough to support session-level passwords.
 
index b0ed9a6cff119c73f142b1d2fa96c351631e86e8..d3fd08c445d12f9d3bd36c244ba1ec04fbcd3664 100644 (file)
@@ -8,7 +8,7 @@ manpagename(smbd)(server to provide SMB/CIFS services to clients)
 label(SYNOPSIS)
 manpagesynopsis()
 
-bf(smbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-d debuglevel)(minusd)] [link(-l log file)(minusl)] [link(-p port number)(minusp)] [link(-O socket options)(minusO)] [link(-s configuration file)(minuss)] [link(-i scope)(minusi)] [link(-P)(minusP)] [link(-h)(minush)]
+bf(smbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-P)(minusP)] [link(-h)(minush)] [link(-V)(minusV)] [link(-d debuglevel)(minusd)] [link(-l log file)(minusl)] [link(-p port number)(minusp)] [link(-O socket options)(minusO)] [link(-s configuration file)(minuss)] [link(-i scope)(minusi)]
 
 label(DESCRIPTION)
 manpagedescription()
@@ -71,6 +71,16 @@ dit(bf(-o)) If this parameter is specified, the log files will be
 overwritten when opened.  By default, the log files will be appended
 to.
 
+label(minusP)
+dit(bf(-P)) Passive option. Causes smbd not to send any network traffic
+out. Used for debugging by the developers only.
+
+label(minush)
+dit(bf(-h)) Prints the help information (usage) for bf(smbd).
+
+label(minusV)
+dit(bf(-V)) Prints the version number for bf(smbd).
+
 label(minusd)
 dit(bf(-d debuglevel)) debuglevel is an integer from 0 to 10.
 
@@ -142,13 +152,6 @@ are em(very) rarely used, only set this parameter if you are the
 system administrator in charge of all the NetBIOS systems you
 communicate with.
 
-label(minush)
-dit(bf(-h)) Prints the help information (usage) for smbd.
-
-label(minusP)
-dit(bf(-P)) Passive option. Causes smbd not to send any network traffic
-out. Used for debugging by the developers only.
-
 endit()
 
 label(FILES)
@@ -421,16 +424,11 @@ performance.
 label(SEEALSO)
 manpageseealso()
 
-bf(hosts_access (5)),
-bf(inetd (8)),
-url(bf(nmbd (8)))(nmbd.8.html),
-url(bf(smb.conf (5)))(smb.conf.5.html),
-url(bf(smbclient (1)))(smbclient.1.html),
-url(bf(testparm (1)))(testparm.1.html),
-url(bf(testprns (1)))(testprns.1.html),
-url(bf(rpcclient (1)))(rpcclient.1.html),
-and the Internet RFC's bf(rfc1001.txt), bf(rfc1002.txt).
-In addition the CIFS (formerly SMB)
+bf(hosts_access (5)), bf(inetd (8)), url(bf(nmbd (8)))(nmbd.8.html),
+url(bf(smb.conf (5)))(smb.conf.5.html), url(bf(smbclient
+(1)))(smbclient.1.html), url(bf(testparm (1)))(testparm.1.html),
+url(bf(testprns (1)))(testprns.1.html), and the Internet RFC's
+bf(rfc1001.txt), bf(rfc1002.txt). In addition the CIFS (formerly SMB)
 specification is available as a link from the Web page :
 url(http://samba.org/cifs/)(http://samba.org/cifs/).
 
index 0d88bc7ef55b45313b1e765f92bbf7c7018ceed1..f412a00a15155dd69b7e67ee1556b75d5d8e5bea 100644 (file)
@@ -24,7 +24,7 @@ manpageoptions()
 startdit()
 
 label(minusP)
-dit(bf(-P)) If samba has been compiled with the profiling option, 
+dit(bf(-P)) If samba has been compiled with the profiling option,
 print only the contents of the profiling shared memory area.
 
 label(minusb)
index 5059e3f47c6aeef4ac0c444c5849b425670fe208..145a919879759354f75d5b6871969c847616cccf 100644 (file)
@@ -3,7 +3,7 @@ mailto(samba-bugs@samba.org)
 manpage(swat htmlcommand((8)))(8)(23 Oct 1998)(Samba)(SAMBA)
 
 label(NAME)
-manpagename(swat)(swat - Samba Web Administration Tool)
+manpagename(swat)(Samba Web Administration Tool)
 
 label(SYNOPSIS)
 manpagesynopsis()
index 2c8e414bcd8d8dd40613d1588538f00feaf616f2..35ebce9a9820dd057e1aa0f531fdf8a0e6a4a242 100644 (file)
@@ -8,7 +8,7 @@ manpagename(testparm)(check an smb.conf configuration file for internal correctn
 label(SYNOPSIS)
 manpagesynopsis() 
 
-bf(testparm) [link(-s)(minuss)] [link(configfilename)(configfilename)] [link(hostname)(hostname) link(hostIP)(hostIP)]
+bf(testparm) [link(-s)(minuss)] [link(-h)(minush)] [link(-L servername)(minusL)] [link(configfilename)(configfilename)] [link(hostname)(hostname) link(hostIP)(hostIP)]
 
 label(DESCRIPTION)
 manpagedescription()
@@ -28,6 +28,11 @@ If the optional host name and host IP address are specified on the
 command line, this test program will run through the service entries
 reporting whether the specified host has access to each service.
 
+If bf(testparm) finds an error in the url(bf(smb.conf))(smb.conf.5.html)
+file it returns an exit code of 1 to the calling program, else it returns
+an exit code of 0. This allows shell scripts to test the output from
+bf(testparm).
+
 label(OPTIONS)
 manpageoptions()
 
@@ -38,6 +43,13 @@ dit(bf(-s)) Without this option, bf(testparm) will prompt for a
 carriage return after printing the service names and before dumping
 the service definitions.
 
+label(minush)
+dit(bf(-h)) Print usage message
+
+label(minusL)
+dit(bf(-L servername)) Sets the value of the %L macro to servername. This
+is useful for testing include files specified with the %L macro.
+
 label(configfilename)
 dit(bf(configfilename)) This is the name of the configuration file to
 check. If this parameter is not present then the default
index fc293f5391df5877ac2f4f5251f4a6024e7f6fe8..0fa8f4efc30b1daff6a0bbe2c816df603501d7e5 100644 (file)
@@ -9,10 +9,7 @@ valepp         -fstype=nfs,rsize=8192,wsize=8192               valepp:/
 galaun         -fstype=nfs,rsize=8192,wsize=8192               galaun:/
 
 # smb-servers
-supra_andreas  -fstype=smb,uuname=andreas                      supra:/aheinrich
-supra_cspiel   -fstype=smb,uuname=cspiel                       supra:/cspiel
-phonon_andreas -fstype=smb,uuname=andreas,fmod=3700            phonon:/andreas
-helium_cspiel  -fstype=smb,uuname=cspiel,fmod=3700             helium:/cspiel
-
-#supra_jaz       -fstype=smb,user,fmod=644,dmod=755            supra:/f
-
+supra_andreas  -fstype=smb,username=andreas,password=foo       ://supra/aheinrich
+supra_cspiel   -fstype=smb,username=cspiel                     ://supra/cspiel
+phonon_andreas -fstype=smb,username=andreas                    ://phonon/andreas
+helium_cspiel  -fstype=smb,username=cspiel                     ://helium/cspiel
index 98c2b72edd2249be2c1a7b03d1b4840354f520b4..ea1299068a3347da9977dce1a558af62d84a9e0f 100644 (file)
@@ -1,8 +1,5 @@
 #!/usr/bin/perl
 #
-# $Source: /data/src/mirror/cvs/samba/examples/printer-accounting/hp5-redir,v $
-# $Id: hp5-redir,v 1.1 1996/07/23 03:30:56 samba-bugs Exp $
-#
 # 0 == stdin  == docuement
 # 1 == stdout == printer
 # 2 == stderr == logging
index 3fe45f877fd7e096b011ab61c286914ac93b2d57..91a3def08f8fdb7d5dd0da073c77b30654af266a 100644 (file)
@@ -1,8 +1,5 @@
 #!/usr/bin/perl
 #
-# $Source: /data/src/mirror/cvs/samba/examples/printer-accounting/lp-acct,v $
-# $Id: lp-acct,v 1.1 1996/07/23 03:30:56 samba-bugs Exp $
-#
 # 0 == stdin  == docuement
 # 1 == stdout == printer
 # 2 == stderr == logging
index 9d19c26decd93466a024e958bc36d825f3f5d7fd..5a00a2a8aa870c4966092eca080dca3726463b70 100755 (executable)
@@ -87,7 +87,7 @@ echo "server $server, service $service" >> $logfile
 (
 # NOTE You may wish to add the line `echo translate' if you want automatic
 # CR/LF translation when printing.
-       if [ $TRANS ]; then
+       if [ $TRANS -eq 1 ]; then
           echo translate
         fi
        echo "print -"
index ce159568369d9e8ccc6eacf8674ec2d8eb78ac69..a5dbb39bedff5189afd6fea2789c64eaeab8d86a 100644 (file)
Binary files a/examples/validchars/validchr.com and b/examples/validchars/validchr.com differ
index a1d3827553c4195ff7c7b169e4507bbde9d3fdaf..2daee8b69efc5d361ab05bc028f655b664652c9e 100755 (executable)
@@ -1,10 +1,10 @@
 tar xvf skeleton.tar
+NOWDIR=`pwd`;
 ( cd /usr/local;
-       mv man man.orig;
-       mv samba samba.orig;
-       DIRNOW=`pwd1`;
-               ln -sf $NOWDIR/usr/local/man man;
-               ln -sf $NOWDIR/usr/local/samba samba; )
+       if [ -x man ]; then mv man man.orig; fi
+       if [ -x samba ]; then mv samba samba.orig; fi
+       ln -sf $NOWDIR/usr/local/man man;
+       ln -sf $NOWDIR/usr/local/samba samba; )
 gunzip samba-2.0.0.tar.gz
 tar xvf samba-2.0.0.tar
 cd samba-2.0.0/source
@@ -24,7 +24,7 @@ tar cvf samba-2.0.0.tar samba-2.0.0
 rm -rf samba-2.0.0
 rm -rf usr var
 cd ..
-find samba-2.0.0 -print | cpio -o > samba-2.0.0-OSF1-v4.0-alpha.cpio
-gzip samba-2.0.0-OSF1-v4.0-alpha.cpio
+find samba-2.0.0 -print | cpio -o > samba-2.0.0-OSF1-v4.0-beta5.cpio
+gzip samba-2.0.0-OSF1-v4.0-beta5.cpio
 cd samba-2.0.0
-tar xcf install.tar
+tar xvf install.tar
index c1d605cda0625667ce0a366a356d2f8ec8f11656..6a7424408909feb7c77dbcd02626daec30fcc46b 100755 (executable)
@@ -19,8 +19,8 @@ case "$1" in
 
        'start')
           echo "Starting Samba"
-          /usr/local/samba/sbin/smbd
-          /usr/local/samba/sbin/nmbd
+          /usr/local/samba/bin/smbd
+          /usr/local/samba/bin/nmbd
           echo "Done."
           ;;
        'stop')
index 5e5834a6d3c8b6e17b4ccf68e3cb23672606c2f3..e8f5089a865f67fbabd467715e7b8b0b181ac589 100755 (executable)
@@ -7,7 +7,7 @@ tar xvf skeleton.tar
 ( cd /usr/local;
        mv man man.orig;
        mv samba samba.orig;
-       DIRNOW=`pwd1`;
+       NOWDIR=`pwd`;
                ln -sf $NOWDIR/usr/local/man man;
                ln -sf $NOWDIR/usr/local/samba samba; )
 
@@ -32,9 +32,8 @@ tar cvf install.tar usr var
 
 # Clean up original sources preserving all configured files
 #        Note: This will allow installers to check build options
-cd samba-X.X.X/source/bin
-rm -f *
-cd ..
+cd samba-X.X.X/source
+rm -f ../source/bin/*
 make clean
 cd ../..
 tar cvf samba-X.X.X.tar samba-X.X.X
index 5fddb7cbfb496afe87bc13db256e34567f036a36..88d5222e09ad30f4ef8eb372f2146e61a764bff2 100644 (file)
@@ -1,44 +1,12 @@
-diff -uNr samba-PVERSION/source/Makefile.in samba-kgc/source/Makefile.in
---- samba-PVERSION/source/Makefile.in  Wed Dec  2 14:35:18 1998
-+++ samba-kgc/source/Makefile.in       Wed Dec  2 15:06:02 1998
-@@ -27,7 +27,7 @@
+--- samba-2.0.1/source/Makefile.in.orig        Tue Dec  1 22:32:20 1998
++++ samba-2.0.1/source/Makefile.in     Wed Dec  2 17:11:33 1998
+@@ -25,9 +25,9 @@
+ BINDIR = @bindir@
+ # we don't use sbindir because we want full compatibility with
  # the previous releases of Samba
- SBINDIR = @bindir@
+-SBINDIR = @bindir@
++SBINDIR = @sbindir@
  LIBDIR = @libdir@
--VARDIR = $(BASEDIR)/var
-+VARDIR = /var
+-VARDIR = @localstatedir@
++VARDIR = /var/log/samba
  MANDIR = @mandir@
- # The permissions to give the executables
-@@ -36,23 +36,23 @@
- # set these to where to find various files
- # These can be overridden by command line switches (see smbd(8))
- # or in smb.conf (see smb.conf(5))
--SMBLOGFILE = $(VARDIR)/log.smb
--NMBLOGFILE = $(VARDIR)/log.nmb
-+SMBLOGFILE = $(VARDIR)/log/samba/log.smb
-+NMBLOGFILE = $(VARDIR)/log/samba/log.nmb
- CONFIGFILE = $(LIBDIR)/smb.conf
- LMHOSTSFILE = $(LIBDIR)/lmhosts
- DRIVERFILE = $(LIBDIR)/printers.def
- PASSWD_PROGRAM = /bin/passwd
--SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
--SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
--SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
--SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
-+SMB_PASSWD_FILE = $(LIBDIR)/smbpasswd
-+SMB_PASSGRP_FILE = $(LIBDIR)/smbpassgrp
-+SMB_GROUP_FILE = $(LIBDIR)/smbgroup
-+SMB_ALIAS_FILE = $(LIBDIR)/smbalias
- SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
- # This is where SWAT images and help files go
--SWATDIR = $(BASEDIR)/swat
-+SWATDIR = $(BASEDIR)/share/swat
- # the directory where lock files go
--LOCKDIR = $(VARDIR)/locks
-+LOCKDIR = $(VARDIR)/lock/samba
- # The directory where code page definition files go
- CODEPAGEDIR = $(LIBDIR)/codepages
index bd9a8e15bcc3e84f2b1ce7cc7669d967a0c902af..e07d15c93efab8517b1f5ddd8cea6d8c6bbdb4ab 100644 (file)
@@ -85,7 +85,7 @@
 
 # Most people will find that this option gives better performance.
 # See speed.txt and the manual pages for details
-   socket options = TCP_NODELAY 
+   socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
 
 # Configure Samba to use multiple interfaces
 # If you have multiple network interfaces then you must list them
index 5fddb7cbfb496afe87bc13db256e34567f036a36..88d5222e09ad30f4ef8eb372f2146e61a764bff2 100644 (file)
@@ -1,44 +1,12 @@
-diff -uNr samba-PVERSION/source/Makefile.in samba-kgc/source/Makefile.in
---- samba-PVERSION/source/Makefile.in  Wed Dec  2 14:35:18 1998
-+++ samba-kgc/source/Makefile.in       Wed Dec  2 15:06:02 1998
-@@ -27,7 +27,7 @@
+--- samba-2.0.1/source/Makefile.in.orig        Tue Dec  1 22:32:20 1998
++++ samba-2.0.1/source/Makefile.in     Wed Dec  2 17:11:33 1998
+@@ -25,9 +25,9 @@
+ BINDIR = @bindir@
+ # we don't use sbindir because we want full compatibility with
  # the previous releases of Samba
- SBINDIR = @bindir@
+-SBINDIR = @bindir@
++SBINDIR = @sbindir@
  LIBDIR = @libdir@
--VARDIR = $(BASEDIR)/var
-+VARDIR = /var
+-VARDIR = @localstatedir@
++VARDIR = /var/log/samba
  MANDIR = @mandir@
- # The permissions to give the executables
-@@ -36,23 +36,23 @@
- # set these to where to find various files
- # These can be overridden by command line switches (see smbd(8))
- # or in smb.conf (see smb.conf(5))
--SMBLOGFILE = $(VARDIR)/log.smb
--NMBLOGFILE = $(VARDIR)/log.nmb
-+SMBLOGFILE = $(VARDIR)/log/samba/log.smb
-+NMBLOGFILE = $(VARDIR)/log/samba/log.nmb
- CONFIGFILE = $(LIBDIR)/smb.conf
- LMHOSTSFILE = $(LIBDIR)/lmhosts
- DRIVERFILE = $(LIBDIR)/printers.def
- PASSWD_PROGRAM = /bin/passwd
--SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
--SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
--SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
--SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
-+SMB_PASSWD_FILE = $(LIBDIR)/smbpasswd
-+SMB_PASSGRP_FILE = $(LIBDIR)/smbpassgrp
-+SMB_GROUP_FILE = $(LIBDIR)/smbgroup
-+SMB_ALIAS_FILE = $(LIBDIR)/smbalias
- SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
- # This is where SWAT images and help files go
--SWATDIR = $(BASEDIR)/swat
-+SWATDIR = $(BASEDIR)/share/swat
- # the directory where lock files go
--LOCKDIR = $(VARDIR)/locks
-+LOCKDIR = $(VARDIR)/lock/samba
- # The directory where code page definition files go
- CODEPAGEDIR = $(LIBDIR)/codepages
index fa69370dff0bcd9ee76e0de1d38a3bedceab5ea3..1767176a1fe94743a7dd51af106e4426549bab6c 100644 (file)
@@ -1,14 +1,47 @@
 #!/bin/sh
 # Copyright (C) John H Terpstra 1998
+# Updated for RPM 3 by Jochen Wiedmann, joe@ispsoft.de
 #
-RPMDIR=`rpm --showrc | awk '/^rpmdir/ { print $3}'`
-SPECDIR=`rpm --showrc | awk '/^specdir/ { print $3}'`
-SRCDIR=`rpm --showrc | awk '/^sourcedir/ { print $3}'`
+USERID=`id -u`
+GRPID=`id -g`
 
+rpm3var () {
+    echo "rpm3var start $1" >>/tmp/log
+    var=`rpm --showrc \
+         | awk "/-[0-9]+[:=][[:blank:]]+$1[[:blank:]]/ {print \\$3}"`
+    echo "var=$var" >>/tmp/log
+    while test -n "`echo $var | egrep '%{[_a-zA-Z]+}'`"; do
+       v=`echo $var | sed 's/.*%{\([_a-zA-Z]\+\)}.*/\1/'`
+       echo "Loop: v=$v" >>/tmp/log
+       w="`rpm3var $v`"
+       var=`echo $var | sed "s,%{\\([_a-zA-Z]\\+\\)},$w,g"`
+       echo "Loop: var=$var" >>/tmp/log
+    done
+    echo "rpm3var stop $1 $var" >>/tmp/log
+    echo $var
+}
+
+case `rpm --version | awk '{print $3}'` in
+    2.*)
+       RPMDIR=`rpm --showrc | awk '/^rpmdir/ { print $3}'`
+       SPECDIR=`rpm --showrc | awk '/^specdir/ { print $3}'`
+       SRCDIR=`rpm --showrc | awk '/^sourcedir/ { print $3}'`
+       ;;
+    3.*)
+       RPMDIR=`rpm3var _rpmdir`
+       SPECDIR=`rpm3var _specdir`
+       SRCDIR=`rpm3var _sourcedir`
+       ;;
+    *)
+       echo "Unknown RPM version: `rpm --version`"
+       exit 1
+       ;;
+esac
+
+( cd ../../.. ; chown -R ${USERID}.${GRPID} ${SRCDIR}/samba-PVERSION )
 ( cd ../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION )
+
 cp -a *.spec $SPECDIR
 cp -a *.patch smb.* samba.log $SRCDIR
-cd $SRCDIR
-chown -R root.root samba-PVERSION
 cd $SPECDIR
 rpm -ba -v samba2.spec
index c5f2a5b45bc9079355b28aeb14a92c0e1f8ff077..c8ab3852e2770d367c91c0905c2764ac43be214d 100644 (file)
@@ -1,11 +1,11 @@
 /var/log/samba/log.nmb {
     postrotate
        /usr/bin/killall -HUP nmbd
-    endrotate
+    endscript
 }
 
 /var/log/samba/log.smb {
     postrotate
        /usr/bin/killall -HUP smbd
-    endrotate
+    endscript
 }
index c7d665c672d055e03d13fb67fd20d0eaa9b9bed4..92ea52527b2dd337f04aa5bd85d249d078012f3a 100644 (file)
@@ -11,6 +11,7 @@ Packager: John H Terpstra [Samba-Team] <jht@samba.org>
 Requires: pam >= 0.64
 Prereq: chkconfig fileutils
 BuildRoot: /var/tmp/samba
+Prefix: /usr
 
 %description
 Samba provides an SMB server which can be used to provide
@@ -38,6 +39,25 @@ for Shadow passwords. Do NOT recompile with the SHADOW_PWD option
 enabled. Red Hat Linux has built in support for quotas in PAM.
 
 %changelog
+* Sat Nov 29 1999 Matthew Vanecek <mev0003@unt.edu>
+ - Added a Prefix and changed "/usr" to "%{prefix}"
+
+* Sat Nov 11 1999 Tridge <tridge@linuxcare.com>
+ - changed from mount.smb to mount.smbfs
+
+* Sat Oct 9 1999 Tridge <tridge@linuxcare.com>
+ - removed smbwrapper
+ - added smbmnt and smbmount
+
+* Sun Apr 25 1999 John H Terpstra <jht@samba.org>
+ - added smbsh.1 man page
+
+* Fri Mar 26 1999 Andrew Tridgell <tridge@samba.org>
+ - added --with-pam as pam is no longer used by default
+
+* Sat Jan 27 1999 Jeremy Allison <jra@samba.org>
+ - Removed smbrun binary and tidied up some loose ends
+
 * Sun Oct 25 1998 John H Terpstra <jht@samba.org>
  - Added parameters to /config to ensure smb.conf, lmhosts, 
        and smbusers never gets over-written.
@@ -75,7 +95,7 @@ enabled. Red Hat Linux has built in support for quotas in PAM.
  - Updated spec file
  - Included new codepage.936
 
-* Sat Mar 20 1998 John H Terpstra <jht@samba.anu.edu/au>
+* Sat Mar 20 1998 John H Terpstra <jht@samba.org>
  - Added swat facility
 
 * Sat Jan 24 1998 John H Terpstra <jht@samba.org>
@@ -97,8 +117,8 @@ enabled. Red Hat Linux has built in support for quotas in PAM.
 
 %build
 cd source
-./configure --prefix=/usr --libdir=/etc --with-smbwrapper
-make all smbwrapper
+./configure --prefix=%{prefix} --libdir=/etc --with-lockdir=/var/lock/samba --with-privatedir=/etc --with-swatdir=%{prefix}/share/swat --with-smbmount --with-automount --with-quotas --with-pam
+make all
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -107,34 +127,38 @@ mkdir -p $RPM_BUILD_ROOT/etc/codepages/src
 mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d}
 mkdir -p $RPM_BUILD_ROOT/etc/rc.d/{init.d,rc0.d,rc1.d,rc2.d,rc3.d,rc5.d,rc6.d}
 mkdir -p $RPM_BUILD_ROOT/home/samba
-mkdir -p $RPM_BUILD_ROOT/usr/{bin,sbin}
-mkdir -p $RPM_BUILD_ROOT/usr/share/swat/{images,help,include}
-mkdir -p $RPM_BUILD_ROOT/usr/man/{man1,man5,man7,man8}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT/sbin
+mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include}
+mkdir -p $RPM_BUILD_ROOT%{prefix}/man/{man1,man5,man7,man8}
 mkdir -p $RPM_BUILD_ROOT/var/lock/samba
 mkdir -p $RPM_BUILD_ROOT/var/log/samba
 mkdir -p $RPM_BUILD_ROOT/var/spool/samba
 
 # Install standard binary files
-for i in nmblookup smbclient smbpasswd smbrun smbstatus testparm testprns \
-      make_smbcodepage make_printerdef rpcclient smbsh smbwrapper.so
+for i in nmblookup smbclient smbspool smbpasswd smbstatus testparm testprns \
+      make_smbcodepage make_printerdef rpcclient
 do
-install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/bin
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
 done
 for i in addtosmbpass mksmbpasswd.sh smbtar 
 do
-install -m755 source/script/$i $RPM_BUILD_ROOT/usr/bin
+install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
 done
 
 # Install secure binary files
-for i in smbd nmbd swat
+for i in smbd nmbd swat smbmount smbmnt smbumount
 do
-install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/sbin
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT%{prefix}/sbin
 done
 
+# we need a symlink for mount to recognise the smb filesystem type
+ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
+
 # Install level 1 man pages
 for i in smbclient.1 smbrun.1 smbstatus.1 smbtar.1 testparm.1 testprns.1 make_smbcodepage.1 nmblookup.1
 do
-install -m644 docs/manpages/$i $RPM_BUILD_ROOT/usr/man/man1
+install -m644 docs/manpages/$i $RPM_BUILD_ROOT%{prefix}/man/man1
 done
 
 # Install codepage source files
@@ -146,34 +170,37 @@ done
 # Install SWAT helper files
 for i in swat/help/*.html docs/htmldocs/*.html
 do
-install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/help
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/help
 done
 for i in swat/images/*.gif
 do
-install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/images
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/images
 done
 for i in swat/include/*.html
 do
-install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/include
+install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/include
 done
 
 # Install the miscellany
-install -m644 swat/README $RPM_BUILD_ROOT/usr/share/swat
-install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT/usr/man/man5
-install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT/usr/man/man5
-install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT/usr/man/man5
-install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT/usr/man/man7
-install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT/usr/man/man8
-install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT/usr/man/man8
-install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT/usr/man/man8
-install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 swat/README $RPM_BUILD_ROOT%{prefix}/share/swat
+install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT%{prefix}/man/man5
+install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT%{prefix}/man/man5
+install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT%{prefix}/man/man5
+install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT%{prefix}/man/man7
+install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/smbmnt.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/smbmount.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 docs/manpages/smbspool.8 $RPM_BUILD_ROOT%{prefix}/man/man8
 install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/smb.conf
 install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/smbusers
-install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT/usr/bin
-install -m755 packaging/RedHat/findsmb $RPM_BUILD_ROOT/usr/bin
-install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/RedHat/findsmb $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT%{prefix}/bin
 install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
-install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/usr/sbin/samba
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
 install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
 install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
 echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/lmhosts
@@ -187,7 +214,7 @@ rm -rf $RPM_BUILD_ROOT
 # Build codepage load files
 for i in 437 737 850 852 861 866 932 936 949 950
 do
-/usr/bin/make_smbcodepage c $i /etc/codepages/src/codepage_def.$i /etc/codepages/codepage.$i
+%{prefix}/bin/make_smbcodepage c $i /etc/codepages/src/codepage_def.$i /etc/codepages/codepage.$i
 done
 
 # Add swat entry to /etc/services if not already there
@@ -197,7 +224,7 @@ fi
 
 # Add swat entry to /etc/inetd.conf if needed
 if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
-       echo 'swat      stream  tcp     nowait.400      root    /usr/sbin/swat swat' >> /etc/inetd.conf
+       echo 'swat      stream  tcp     nowait.400      root    %{prefix}/sbin/swat swat' >> /etc/inetd.conf
 killall -1 inetd || :
 fi
 
@@ -221,9 +248,7 @@ fi
 
 %postun
 # Only delete remnants of samba if this is the final deletion.
-if [ $1 != 0 ] ; then
-    exit 0
-
+if [ $1 = 0 ] ; then
     if [ -x /etc/pam.d/samba ]; then
       rm -f /etc/pam.d/samba
     fi
@@ -255,56 +280,60 @@ fi
 %doc docs
 %doc swat/README
 %doc examples
-%attr(-,root,root) /usr/sbin/smbd
-%attr(-,root,root) /usr/sbin/nmbd
-%attr(-,root,root) /usr/sbin/swat
-%attr(0750,root,root) /usr/sbin/samba
-%attr(-,root,root) /usr/bin/addtosmbpass
-%attr(-,root,root) /usr/bin/mksmbpasswd.sh
-%attr(-,root,root) /usr/bin/smbclient
-%attr(-,root,root) /usr/bin/rpcclient
-%attr(-,root,root) /usr/bin/testparm
-%attr(-,root,root) /usr/bin/testprns
-%attr(-,root,root) /usr/bin/smbrun
-%attr(-,root,root) /usr/bin/findsmb
-%attr(-,root,root) /usr/bin/smbstatus
-%attr(-,root,root) /usr/bin/nmblookup
-%attr(-,root,root) /usr/bin/make_smbcodepage
-%attr(-,root,root) /usr/bin/make_printerdef
-%attr(-,root,root) /usr/bin/smbpasswd
-%attr(-,root,root) /usr/bin/smbtar
-%attr(-,root,root) /usr/bin/smbprint
-%attr(-,root,root) /usr/bin/smbadduser
-%attr(0755,root,root) /usr/bin/smbsh
-%attr(0755,root,root) /usr/bin/smbwrapper.so
-%attr(-,root,root) /usr/share/swat/help/welcome.html
-%attr(-,root,root) /usr/share/swat/help/DOMAIN_MEMBER.html
-%attr(-,root,root) /usr/share/swat/help/lmhosts.5.html
-%attr(-,root,root) /usr/share/swat/help/make_smbcodepage.1.html
-%attr(-,root,root) /usr/share/swat/help/nmbd.8.html
-%attr(-,root,root) /usr/share/swat/help/nmblookup.1.html
-%attr(-,root,root) /usr/share/swat/help/samba.7.html
-%attr(-,root,root) /usr/share/swat/help/smb.conf.5.html
-%attr(-,root,root) /usr/share/swat/help/smbclient.1.html
-%attr(-,root,root) /usr/share/swat/help/smbd.8.html
-%attr(-,root,root) /usr/share/swat/help/smbpasswd.5.html
-%attr(-,root,root) /usr/share/swat/help/smbpasswd.8.html
-%attr(-,root,root) /usr/share/swat/help/smbrun.1.html
-%attr(-,root,root) /usr/share/swat/help/smbstatus.1.html
-%attr(-,root,root) /usr/share/swat/help/smbtar.1.html
-%attr(-,root,root) /usr/share/swat/help/swat.8.html
-%attr(-,root,root) /usr/share/swat/help/testparm.1.html
-%attr(-,root,root) /usr/share/swat/help/testprns.1.html
-%attr(-,root,root) /usr/share/swat/images/globals.gif
-%attr(-,root,root) /usr/share/swat/images/home.gif
-%attr(-,root,root) /usr/share/swat/images/passwd.gif
-%attr(-,root,root) /usr/share/swat/images/printers.gif
-%attr(-,root,root) /usr/share/swat/images/shares.gif
-%attr(-,root,root) /usr/share/swat/images/samba.gif
-%attr(-,root,root) /usr/share/swat/images/status.gif
-%attr(-,root,root) /usr/share/swat/images/viewconfig.gif
-%attr(-,root,root) /usr/share/swat/include/header.html
-%attr(-,root,root) /usr/share/swat/include/footer.html
+%attr(-,root,root) %{prefix}/sbin/smbd
+%attr(-,root,root) %{prefix}/sbin/nmbd
+%attr(-,root,root) %{prefix}/sbin/swat
+%attr(-,root,root) %{prefix}/sbin/smbmnt
+%attr(-,root,root) %{prefix}/sbin/smbmount
+%attr(-,root,root) %{prefix}/sbin/smbumount
+%attr(-,root,root) /sbin/mount.smbfs
+%attr(0750,root,root) %{prefix}/sbin/samba
+%attr(-,root,root) %{prefix}/bin/addtosmbpass
+%attr(-,root,root) %{prefix}/bin/mksmbpasswd.sh
+%attr(-,root,root) %{prefix}/bin/smbclient
+%attr(-,root,root) %{prefix}/bin/smbspool
+%attr(-,root,root) %{prefix}/bin/rpcclient
+%attr(-,root,root) %{prefix}/bin/testparm
+%attr(-,root,root) %{prefix}/bin/testprns
+%attr(-,root,root) %{prefix}/bin/findsmb
+%attr(-,root,root) %{prefix}/bin/smbstatus
+%attr(-,root,root) %{prefix}/bin/nmblookup
+%attr(-,root,root) %{prefix}/bin/make_smbcodepage
+%attr(-,root,root) %{prefix}/bin/make_printerdef
+%attr(-,root,root) %{prefix}/bin/smbpasswd
+%attr(-,root,root) %{prefix}/bin/smbtar
+%attr(-,root,root) %{prefix}/bin/smbprint
+%attr(-,root,root) %{prefix}/bin/smbadduser
+%attr(-,root,root) %{prefix}/share/swat/help/welcome.html
+%attr(-,root,root) %{prefix}/share/swat/help/DOMAIN_MEMBER.html
+%attr(-,root,root) %{prefix}/share/swat/help/NT_Security.html
+%attr(-,root,root) %{prefix}/share/swat/help/lmhosts.5.html
+%attr(-,root,root) %{prefix}/share/swat/help/make_smbcodepage.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/nmbd.8.html
+%attr(-,root,root) %{prefix}/share/swat/help/nmblookup.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/samba.7.html
+%attr(-,root,root) %{prefix}/share/swat/help/smb.conf.5.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbclient.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbspool.8.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbd.8.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbpasswd.5.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbpasswd.8.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbrun.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbstatus.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/smbtar.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/swat.8.html
+%attr(-,root,root) %{prefix}/share/swat/help/testparm.1.html
+%attr(-,root,root) %{prefix}/share/swat/help/testprns.1.html
+%attr(-,root,root) %{prefix}/share/swat/images/globals.gif
+%attr(-,root,root) %{prefix}/share/swat/images/home.gif
+%attr(-,root,root) %{prefix}/share/swat/images/passwd.gif
+%attr(-,root,root) %{prefix}/share/swat/images/printers.gif
+%attr(-,root,root) %{prefix}/share/swat/images/shares.gif
+%attr(-,root,root) %{prefix}/share/swat/images/samba.gif
+%attr(-,root,root) %{prefix}/share/swat/images/status.gif
+%attr(-,root,root) %{prefix}/share/swat/images/viewconfig.gif
+%attr(-,root,root) %{prefix}/share/swat/include/header.html
+%attr(-,root,root) %{prefix}/share/swat/include/footer.html
 %attr(-,root,root) %config(noreplace) /etc/lmhosts
 %attr(-,root,root) %config(noreplace) /etc/smb.conf
 %attr(-,root,root) %config(noreplace) /etc/smbusers
@@ -321,22 +350,25 @@ fi
 %attr(-,root,root) /etc/codepages/src/codepage_def.936
 %attr(-,root,root) /etc/codepages/src/codepage_def.949
 %attr(-,root,root) /etc/codepages/src/codepage_def.950
-%attr(-,root,root) /usr/man/man1/smbstatus.1
-%attr(-,root,root) /usr/man/man1/smbclient.1
-%attr(-,root,root) /usr/man/man1/make_smbcodepage.1
-%attr(-,root,root) /usr/man/man1/smbrun.1
-%attr(-,root,root) /usr/man/man1/smbtar.1
-%attr(-,root,root) /usr/man/man1/testparm.1
-%attr(-,root,root) /usr/man/man1/testprns.1
-%attr(-,root,root) /usr/man/man1/nmblookup.1
-%attr(-,root,root) /usr/man/man5/smb.conf.5
-%attr(-,root,root) /usr/man/man5/lmhosts.5
-%attr(-,root,root) /usr/man/man5/smbpasswd.5
-%attr(-,root,root) /usr/man/man7/samba.7
-%attr(-,root,root) /usr/man/man8/smbd.8
-%attr(-,root,root) /usr/man/man8/nmbd.8
-%attr(-,root,root) /usr/man/man8/smbpasswd.8
-%attr(-,root,root) /usr/man/man8/swat.8
+%attr(-,root,root) %{prefix}/man/man1/smbstatus.1
+%attr(-,root,root) %{prefix}/man/man1/smbclient.1
+%attr(-,root,root) %{prefix}/man/man1/make_smbcodepage.1
+%attr(-,root,root) %{prefix}/man/man1/smbrun.1
+%attr(-,root,root) %{prefix}/man/man1/smbtar.1
+%attr(-,root,root) %{prefix}/man/man1/testparm.1
+%attr(-,root,root) %{prefix}/man/man1/testprns.1
+%attr(-,root,root) %{prefix}/man/man1/nmblookup.1
+%attr(-,root,root) %{prefix}/man/man5/smb.conf.5
+%attr(-,root,root) %{prefix}/man/man5/lmhosts.5
+%attr(-,root,root) %{prefix}/man/man5/smbpasswd.5
+%attr(-,root,root) %{prefix}/man/man7/samba.7
+%attr(-,root,root) %{prefix}/man/man8/smbd.8
+%attr(-,root,root) %{prefix}/man/man8/nmbd.8
+%attr(-,root,root) %{prefix}/man/man8/smbpasswd.8
+%attr(-,root,root) %{prefix}/man/man8/swat.8
+%attr(-,root,root) %{prefix}/man/man8/smbmnt.8
+%attr(-,root,root) %{prefix}/man/man8/smbmount.8
+%attr(-,root,root) %{prefix}/man/man8/smbspool.8
 %attr(-,root,nobody) %dir /home/samba
 %attr(-,root,root) %dir /etc/codepages
 %attr(-,root,root) %dir /etc/codepages/src
index bd9a8e15bcc3e84f2b1ce7cc7669d967a0c902af..e07d15c93efab8517b1f5ddd8cea6d8c6bbdb4ab 100644 (file)
@@ -85,7 +85,7 @@
 
 # Most people will find that this option gives better performance.
 # See speed.txt and the manual pages for details
-   socket options = TCP_NODELAY 
+   socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
 
 # Configure Samba to use multiple interfaces
 # If you have multiple network interfaces then you must list them
index cc4462727315bc9188da78f150fdd2343b561774..a7f3c574a74c713474d1398b4832fc6f49d56191 100755 (executable)
@@ -8,6 +8,15 @@ $curdir = $ENV{"PWD"};
 
 # We don't want the files listed in .cvsignore in the source tree
 open(IGNORES,"../../source/.cvsignore") || die "Unable to open .cvsignore file\n";
+while (<IGNORES>) {
+  chop;
+  next if /cvs\.log/;
+  $ignores{$_}++;
+}
+close IGNORES;
+
+# We don't want the files listed in .cvsignore in the source/include tree
+open(IGNORES,"../../source/include/.cvsignore") || die "Unable to open include/.cvsignore file\n";
 while (<IGNORES>) {
   chop;
   $ignores{$_}++;
@@ -32,6 +41,7 @@ if (@sprogs) {
 }
 if (@progs) {
   @progs[0] =~ s/^.*\=//;
+  @progs[0] =~ s/\$\(\S+\)\s//g;
   @progs = split(' ',@progs[0]);
 }
 if (@mprogs) {
@@ -48,6 +58,7 @@ if (@progs2) {
 }
 if (@scripts) {
   @scripts[0] =~ s/^.*\=//;
+  @scripts[0] =~ s/\$\(srcdir\)\///g;
   @scripts = split(' ',@scripts[0]);
 }
 if (@codepage) {
@@ -177,7 +188,7 @@ while (@sorted) {
     print IDB "d 0755 root sys usr/samba/src/$nextfile $nextfile samba.src.samba\n";
   }
   else {
-    if (grep((/\.sh$/ | /\.pl$/ | /mkman$/),$nextfile)) {
+    if (grep((/\.sh$/ | /configure$/ | /configure\.developer/ | /config\.guess/ | /config\.sub/ | /\.pl$/ | /mkman$/),$nextfile)) {
        print IDB "f 0755 root sys usr/samba/src/$nextfile $nextfile samba.src.samba\n";
     }
     else {
@@ -210,7 +221,7 @@ while (@catman) {
   $nextfile = shift @catman;
   ($file = $nextfile) =~ s/^packaging\/SGI\/catman\///;
   ($dirnum = $file) =~ s/^[\D]*//;
-  $dirnum =~ s/\.Z//;
+  $dirnum =~ s/\.z//;
   if ($dirnum ne $olddirnum) {
     print IDB "d 0755 root sys usr/share/catman/u_man/cat$dirnum packaging/SGI samba.man.manpages\n";
     $olddirnum = $dirnum;
index c613a09d018b260f52aadeefc6e48d9f985d2789..248e990c4a5c316b95d298252e466932b2482647 100755 (executable)
@@ -2,7 +2,7 @@
 
 echo
 echo
-echo Samba for IRIX has been installed on your system.
+echo Samba has been installed on your system.
 echo 
 echo Your /etc/services and /etc/inetd.conf files have
 echo been modified to automatically start the
index 4de437d0ad8209ba40e07735aada33eef6fd1e21..a39ed9fdd0c52a14f76192312dfec6b023c71ee2 100755 (executable)
@@ -9,7 +9,10 @@ FILES="*.?"
 
 cd ../../docs/manpages
 for FILE in  $FILES ; do
+   if [ "$FILE" = "smbmnt.8" ]; then continue; fi;
+   if [ "$FILE" = "smbmount.8" -o "$FILE" = "smbumount.8" ]; then continue; fi;
+   if [ "$FILE" = "smbrun.1" ]; then continue; fi;
    neqn $FILE | tbl | nroff -man > ../../packaging/SGI/catman/`basename $FILE`
-   compress -f ../../packaging/SGI/catman/`basename $FILE`
+   pack -f ../../packaging/SGI/catman/`basename $FILE`
 done
 cd ../../packaging/SGI
index cfe9c1f6b860f81f35361589cafe3f3cd1a6a92a..19aa642aadd13079300e7e3f218732ea4c5b38b5 100755 (executable)
@@ -14,6 +14,7 @@
 
 doclean=""
 SGI_ABI=-n32
+ISA=-mips3
 CC=cc
 
 if [ ! -f ../../source/Makefile ]; then
@@ -25,6 +26,7 @@ if [ "$1" = "clean" ]; then
   shift
 elif [ "$1" = "5" ]; then
   SGI_ABI=-32
+  ISA=""
   shift
 fi
 
@@ -35,10 +37,11 @@ if [ "$1" = "clean" ]; then
   shift
 elif [ "$1" = "5" ]; then
   SGI_ABI=-32
+  ISA=""
   shift
 fi
 
-export SGI_ABI CC
+export SGI_ABI ISA CC
 
 if [ "$doclean" = "clean" ]; then
   cd ../../source
@@ -64,11 +67,6 @@ fi
 cd ../../source
 if [ "$doclean" = "clean" ]; then
   echo Create SGI specific Makefile
-  chmod +x configure
-  chmod +x configure.developer
-  chmod +x config.guess
-  chmod +x config.status
-  chmod +x config.sub
   ./configure --prefix=/usr/samba --mandir=/usr/share/catman --with-smbwrapper
   errstat=$?
   if [ $errstat -ne 0 ]; then
index fd0cef8f93308512a059209daae2843caebbe60b..61e62215c91b4463234fbc2876bd36fb421aea8e 100644 (file)
@@ -146,5 +146,12 @@ if ($PSFIX) {                      # are we running a "psfix"?
     system("$lpcommand $file");
 }
 
-# Remove the file only if it lives in /usr/tmp, /tmp, or /var/tmp.
-unlink($file) if $file =~ m=^(/(usr|var))?/tmp=;
+if ($file =~ m(^/)) {
+       # $file is a fully specified path
+       # Remove the file only if it lives in a directory ending in /tmp.
+       unlink($file) if ($file =~ m(/tmp/[^/]+$));
+} else {
+       # $file is NOT a fully specified path
+       # Remove the file only if current directory ends in /tmp.
+       unlink($file) if (`pwd` =~ m(/tmp$));
+}
index 9a154f8f9b55ffb073855be03ff1fc665fba85c4..68187ee288651e6a5b8836134645bbecf93d2a52 100644 (file)
    preserve case = yes
    short preserve case = yes
 
+;  These are the settings required for IRIX password sync
+   passwd program = /usr/bin/passwd %u
+   passwd chat = *ew*password:* %n\n *e-enter*new*password:* %n\n
+
+;  Uncomment the following if you wish to use encrypted passwords.
+;   encrypt passwords = yes
+
+;  Uncomment the following if you wish to sync unix and smbpasswd 
+;   unix password sync = yes
+
 [homes]
    comment = Home Directories
    browseable = no
index ab06b3fffabbc0b6e9dc193a8ed0ac445f7a940f..d195f177e90d73d85a55ad9e301d13695fd74efa 100644 (file)
@@ -1,12 +1,12 @@
-PSTAMP=Mon Sep 29 17:26:14 BST 1997
 PKG=samba
 NAME=SMB based file/printer sharing
-VERSION=1.9.17p2,REV=1
 ARCH=sparc
+VERSION=2.0.6
 CATEGORY=system
-VENDOR=samba group
+VENDOR=Samba Group
 DESC=File and printer sharing for NT workstations
+HOTLINE=Please contact your local UNIX support group
+EMAIL=samba@samba.org
 CLASSES=none
+BASEDIR=/usr/local
 INTONLY=1
-HOTLINE=Please contact your local UNIX support group
-BASEDIR=/
index 637af1781e1f249e2370dcdd144c766e341f30a2..5f20875c9ea80afca56b7e7b938e136a07ee2ccc 100644 (file)
@@ -67,7 +67,6 @@ fi
 /usr/bin/smbclient
 /usr/bin/smbmount
 /usr/bin/smbpasswd
-/usr/bin/smbrun
 /usr/bin/smbstatus
 /usr/bin/smbtar
 /usr/bin/smbumount
@@ -109,8 +108,6 @@ Samba includes the following programs (in summary):
 * smbd, the SMB server. This handles actual connections from clients.
 * nmbd, the Netbios name server, which helps clients locate servers.
 * smbclient, the Unix-hosted client program.
-* smbrun, a little 'glue' program to help the server run external
-programs. 
 * testprns, a program to test server access to printers.
 * testparm, a program to test the Samba configuration file for correctness.
 * smb.conf, the Samba configuration file.
index 247b980fa8dae1fa22de5514860b54ff3de5cc30..694e073ea1cf06e47ce3380a68fd2599351e7487 100644 (file)
@@ -1,4 +1,4 @@
-bin
+mbin
 Makefile
 config.cache
 config.h
index 9282685bbfc03d66d9de7d3e311d4e5b4f6d305a..b538a1c176633076039c78961b1cebd32b334882 100644 (file)
@@ -27,7 +27,7 @@ BINDIR = @bindir@
 # the previous releases of Samba
 SBINDIR = @bindir@
 LIBDIR = @libdir@
-VARDIR = $(BASEDIR)/var
+VARDIR = @localstatedir@
 MANDIR = @mandir@
 
 # The permissions to give the executables
@@ -36,32 +36,28 @@ INSTALLPERMS = 0755
 # set these to where to find various files
 # These can be overridden by command line switches (see smbd(8))
 # or in smb.conf (see smb.conf(5))
-LOGFILEBASE = $(VARDIR)
-SMBLOGFILE = $(LOGFILEBASE)/log.smb
-NMBLOGFILE = $(LOGFILEBASE)/log.nmb
+SMBLOGFILE = $(VARDIR)/log.smb
+NMBLOGFILE = $(VARDIR)/log.nmb
 CONFIGFILE = $(LIBDIR)/smb.conf
 LMHOSTSFILE = $(LIBDIR)/lmhosts
 DRIVERFILE = $(LIBDIR)/printers.def
-FORMSFILE = $(LIBDIR)/ntforms.def
-NTDRIVERSDIR = $(LIBDIR)
 PASSWD_PROGRAM = /bin/passwd
-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
-SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
-SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
-SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
-SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
+# This is where smbpasswd et al go
+PRIVATEDIR = @privatedir@
+
+SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd
 
 # This is where SWAT images and help files go
-SWATDIR = $(BASEDIR)/swat
+SWATDIR = @swatdir@
 
 # the directory where lock files go
-LOCKDIR = $(VARDIR)/locks
+LOCKDIR = @lockdir@
 
 # The directory where code page definition files go
 CODEPAGEDIR = $(LIBDIR)/codepages
 
 # The current codepage definition list.
-CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936
+CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI-R
 
 # where you are going to have the smbrun binary. This defaults to the 
 # install directory. This binary is needed for correct printing
@@ -71,37 +67,22 @@ CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936
 SMBRUN = $(BINDIR)/smbrun
 
 
-PASSWD_FLAGS = \
-               -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\"           \
-               -DSMB_PASSWD_PROGRAM=\"$(SMB_PASSWD_PROGRAM)\"   \
-               -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\"         \
-               -DSMB_PASSGRP_FILE=\"$(SMB_PASSGRP_FILE)\"       \
-               -DSMB_GROUP_FILE=\"$(SMB_GROUP_FILE)\"           \
-               -DSMB_ALIAS_FILE=\"$(SMB_ALIAS_FILE)\" 
-FLAGS1 = $(CFLAGS)     \
-               -Iinclude -I$(srcdir)/include \
-               -I$(srcdir)/ubiqx \
-               -I$(srcdir)/smbwrapper \
-               $(CPPFLAGS) \
-               -DLOGFILEBASE=\"$(LOGFILEBASE)\" \
-               -DSMBLOGFILE=\"$(SMBLOGFILE)\" \
-               -DNMBLOGFILE=\"$(NMBLOGFILE)\"
+PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\"
+FLAGS1 = $(CFLAGS) -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DSMBLOGFILE=\"$(SMBLOGFILE)\" -DNMBLOGFILE=\"$(NMBLOGFILE)\"
 FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"  
 FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DSMBRUN=\"$(SMBRUN)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
-FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DFORMSFILE=\"$(FORMSFILE)\" -DNTDRIVERSDIR=\"$(NTDRIVERSDIR)\"
+FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\"
 FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
-FLAGS  = $(FLAGS5) $(PASSWD_FLAGS)
-
-SPROGS = bin/smbd bin/lsarpcd bin/svcctld bin/spoolssd bin/samrd \
-         bin/srvsvcd bin/wkssvcd bin/browserd bin/netlogond bin/winregd \
-         bin/nmbd bin/swat
-PROGS1 = bin/smbclient bin/testparm bin/testprns bin/smbrun bin/smbstatus 
-PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage bin/debug2html 
-PROGS3 = @WRAP@ @WRAP32@
+FLAGS  = $(ISA) $(FLAGS5) $(PASSWD_FLAGS)
+FLAGS32  = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS)
+
+SPROGS = bin/smbd bin/nmbd bin/swat
+PROGS1 = bin/smbclient bin/smbspool bin/testparm bin/testprns bin/smbstatus @RUNPROG@
+PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage bin/make_unicodemap @WRAP@ @WRAP32@
 MPROGS = @MPROGS@
-PROGS = $(PROGS1) $(PROGS2) $(PROGS3) $(MPROGS) bin/nmblookup bin/make_printerdef 
+PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/make_printerdef 
 
-SCRIPTS = script/smbtar script/addtosmbpass script/convert_smbpasswd
+SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/addtosmbpass $(srcdir)/script/convert_smbpasswd
 
 QUOTAOBJS=@QUOTAOBJS@
 
@@ -109,102 +90,55 @@ QUOTAOBJS=@QUOTAOBJS@
 # object file lists
 ######################################################################
 
-LIBSTATUS_OBJ = lib/util_status.o 
-
 LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
-          lib/getsmbpass.o lib/interface.o lib/kanji.o \
-          lib/md5.o lib/hmacmd5.o lib/md4.o \
-          lib/membuffer.o lib/netmask.o lib/pidfile.o lib/replace.o \
+          lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \
+          lib/interfaces.o lib/pidfile.o lib/replace.o \
           lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o lib/time.o \
-                 lib/ufc.o lib/util.o lib/genrand.o lib/username.o \
-               lib/vuser.o \
-               lib/access.o lib/smbrun.o \
-         lib/bitmap.o lib/crc32.o lib/util_sid.o lib/snprintf.o \
-               lib/util_str.o lib/util_unistr.o \
-               lib/util_file.o mem_man/mem_man.o \
-               lib/util_sock.o \
-               lib/util_array.o \
-               lib/vagent.o \
-               lib/util_hnd.o
-
-LIBSRV_OBJ = lib/passcheck.o
+         lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
+         lib/bitmap.o lib/crc32.o lib/snprintf.o \
+         lib/util_str.o lib/util_sid.o \
+         lib/util_unistr.o lib/util_file.o \
+         lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o lib/fnmatch.o
 
 UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
-            ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o
+            ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o ubiqx/debugparse.o
 
 PARAM_OBJ = param/loadparm.o param/params.o 
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \
              libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
              libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
-            libsmb/passchange.o 
-
-RPC_SRVUTIL_OBJ = \
-               rpc_server/srv_pipe_hnd.o \
-               rpc_server/srv_pipe.o 
-
-RPC_SERVER_OBJ = $(RPC_SRVUTIL_OBJ)
-
-RPC_PARSE_OBJ1 = rpc_parse/parse_lsa.o \
-                rpc_parse/parse_net.o \
-                rpc_parse/parse_reg.o \
-                rpc_parse/parse_samr.o \
-               rpc_parse/parse_srv.o \
-                rpc_parse/parse_wks.o \
-                rpc_parse/parse_svc.o \
-               rpc_parse/parse_at.o \
-               rpc_parse/parse_spoolss.o \
-               rpc_parse/parse_eventlog.o \
-               rpc_parse/parse_brs.o
-
-RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o \
-               rpc_parse/parse_prs.o \
-               rpc_parse/parse_misc.o \
-               rpc_parse/parse_creds.o \
-               rpc_parse/parse_sec.o \
-               lib/msrpc-agent.o \
-               lib/msrpc-client.o \
-               lib/msrpc_use.o \
-
-RPC_PARSE_OBJ = $(RPC_PARSE_OBJ1) $(RPC_PARSE_OBJ2)
+            libsmb/passchange.o
+
+RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
+                 rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \
+                 rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \
+                 rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \
+                 rpc_server/srv_util.o rpc_server/srv_wkssvc.o \
+               rpc_server/srv_pipe.o
+
+RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \
+                rpc_parse/parse_net.o rpc_parse/parse_prs.o \
+                rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \
+                rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
+                rpc_parse/parse_wks.o rpc_parse/parse_sec.o
 
 RPC_CLIENT_OBJ = \
                rpc_client/cli_login.o    \
                rpc_client/cli_netlogon.o \
-               rpc_client/cli_reg.o \
                rpc_client/cli_pipe.o     \
-               rpc_client/cli_connect.o     \
-               rpc_client/cli_use.o     \
-               rpc_client/cli_spoolss.o   \
                rpc_client/cli_lsarpc.o   \
                rpc_client/cli_wkssvc.o   \
-               rpc_client/cli_brs.o   \
                rpc_client/cli_srvsvc.o   \
-               rpc_client/cli_svcctl.o \
-               rpc_client/cli_samr.o   \
-               rpc_client/msrpc_samr.o   \
-               rpc_client/msrpc_netlogon.o   \
-               rpc_client/msrpc_lsarpc.o   \
-               rpc_client/cli_atsvc.o \
-               rpc_client/cli_eventlog.o \
-               libsmb/clienttrust.o
+               rpc_client/cli_reg.o   \
+               rpc_client/cli_samr.o 
+
 
 LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \
               locking/shmem.o locking/shmem_sysv.o
 
-GROUPDB_OBJ = groupdb/groupdb.o groupdb/aliasdb.o groupdb/builtindb.o \
-               groupdb/groupfile.o groupdb/aliasfile.o \
-               groupdb/groupunix.o groupdb/aliasunix.o groupdb/builtinunix.o \
-               groupdb/groupldap.o groupdb/aliasldap.o groupdb/builtinldap.o \
-               passdb/passgrp.o passdb/smbpassgroup.o \
-               passdb/smbpassgroupunix.o passdb/passgrpldap.o
-
-SAMPASSDB_OBJ = passdb/sampassdb.o passdb/sampass.o passdb/sampassldap.o passdb/mysqlsampass.o
-
 PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
-             passdb/pass_check.o passdb/ldap.o passdb/nispass.o \
-             passdb/smbpasschange.o passdb/mysqlpass.o \
-             lib/util_pwdb.o lib/domain_namemap.o lib/sids.o
+             passdb/pass_check.o passdb/ldap.o passdb/nispass.o passdb/smbpasschange.o
 
 PROFILE_OBJ = profile/profile.o
 
@@ -212,139 +146,17 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
             smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
             smbd/ipc.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/$(QUOTAOBJS) smbd/reply.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 \
-               rpc_server/srv_lookup.o \
-               smbd/challenge.o
-
-PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
-
-MSRPCD_OBJ = msrpc/msrpcd.o \
-               msrpc/msrpcd_process.o \
-                rpc_parse/parse_net.o \
-               rpc_client/cli_login.o    \
-               rpc_client/cli_netlogon.o \
-               rpc_client/cli_pipe.o     \
-               rpc_client/cli_connect.o     \
-               rpc_client/cli_use.o     \
-               rpc_client/msrpc_netlogon.o   \
-               smbd/uid.o
-
-BROWSERD_OBJ1 = browserd/browserd.o \
-               passdb/smbpassfile.o \
-               rpc_parse/parse_brs.o \
-               rpc_server/srv_brs.o
-
-WKSSVCD_OBJ1 = wkssvcd/wkssvcd.o \
-               passdb/smbpassfile.o \
-                rpc_parse/parse_wks.o \
-               rpc_server/srv_wkssvc.o
-
-SRVSVCD_OBJ1 = srvsvcd/srvsvcd.o \
-               passdb/smbpassfile.o \
-               rpc_parse/parse_srv.o \
-               rpc_server/srv_srvsvc.o
-
-WINREGD_OBJ1 = winregd/winregd.o \
-               passdb/smbpassfile.o \
-                rpc_parse/parse_reg.o \
-               rpc_server/srv_reg.o
-
-NETLOGOND_OBJ1 = netlogond/netlogond.o \
-               rpc_server/srv_netlog.o \
-               rpc_server/srv_lookup.o \
-               rpc_client/cli_lsarpc.o   \
-                rpc_parse/parse_lsa.o \
-               smbd/chgpasswd.o
-
-SAMRD_OBJ1 = samrd/samrd.o \
-               rpc_server/srv_lookup.o \
-                rpc_parse/parse_samr.o \
-               rpc_client/cli_lsarpc.o   \
-                rpc_parse/parse_lsa.o \
-               rpc_server/srv_samr.o smbd/chgpasswd.o
-
-SVCCTLD_OBJ1 = svcctld/svcctld.o \
-               passdb/smbpassfile.o \
-                rpc_parse/parse_svc.o \
-               rpc_server/srv_svcctl.o
+           smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o
 
-LSARPCD_OBJ1 = lsarpcd/lsarpcd.o \
-               rpc_server/srv_lookup.o \
-               rpc_client/cli_lsarpc.o   \
-                rpc_parse/parse_lsa.o \
-               rpc_server/srv_lsa.o
-
-SPOOLSSD_OBJ1 = spoolssd/spoolssd.o \
-               rpc_server/srv_spoolss.o \
-               passdb/smbpassfile.o \
-               rpc_parse/parse_spoolss.o \
-               printing/nt_printing.o 
+PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o \
+               printing/print_cups.o
 
 SMBD_OBJ = $(SMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
            $(RPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
-           $(LOCKING_OBJ) $(SAMPASSDB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-               $(LIBSTATUS_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-SRVSVCD_OBJ = $(MSRPCD_OBJ) $(SRVSVCD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSTATUS_OBJ) $(LIBSRV_OBJ)
-
-WKSSVCD_OBJ = $(MSRPCD_OBJ) $(WKSSVCD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-BROWSERD_OBJ = $(MSRPCD_OBJ) $(BROWSERD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-WINREGD_OBJ = $(MSRPCD_OBJ) $(WINREGD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-SVCCTLD_OBJ = $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-LSARPCD_OBJ = $(MSRPCD_OBJ) $(LSARPCD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(SAMPASSDB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-               $(LIBSTATUS_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-SPOOLSSD_OBJ = $(MSRPCD_OBJ) $(SPOOLSSD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) $(PRINTING_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-NETLOGOND_OBJ = $(MSRPCD_OBJ) $(NETLOGOND_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(SAMPASSDB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-               $(LIBSTATUS_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
-
-SAMRD_OBJ = $(MSRPCD_OBJ) $(SAMRD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(UBIQX_OBJ) \
-           $(RPC_SRVUTIL_OBJ) $(RPC_PARSE_OBJ2) \
-           $(LOCKING_OBJ) $(SAMPASSDB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-               $(LIBSTATUS_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) \
-               $(LIBSRV_OBJ)
+           $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+
 
 NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
             nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
@@ -360,25 +172,28 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
             nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
 
 NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
-            $(LIB_OBJ) $(RPC_PARSE_OBJ2)
+           $(LIB_OBJ)
 
 SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
            web/swat.o $(LIBSMB_OBJ) $(LOCKING_OBJ) \
            $(PARAM_OBJ) $(PASSDB_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
-           $(UBIQX_OBJ) $(LIB_OBJ)
+           $(UBIQX_OBJ) $(LIB_OBJ) $(PRINTING_OBJ)
 
-SMBRUN_OBJ = utils/smbrun.o
+SMBRUN_OBJ = utils/smbrun.o lib/util_sec.o
 
 SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
-            $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
+            $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
 MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o $(PARAM_OBJ) \
                        $(UBIQX_OBJ) $(LIB_OBJ)
 
+MAKE_UNICODEMAP_OBJ = utils/make_unicodemap.o $(PARAM_OBJ) \
+                       $(UBIQX_OBJ) $(LIB_OBJ)
+
 MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \
                       $(UBIQX_OBJ) $(LIB_OBJ)
 
-STATUS_OBJ = utils/status.o $(LIBSTATUS_OBJ) $(LOCKING_OBJ) $(PARAM_OBJ) \
+STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
 
 TESTPARM_OBJ = utils/testparm.o \
@@ -387,34 +202,19 @@ TESTPARM_OBJ = utils/testparm.o \
 TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
                $(LIB_OBJ)
 
-SMBPASSWD_OBJ = utils/smbpasswd.o rpc_client/cli_netlogon_sync.o \
-               $(PARAM_OBJ) $(LIBSMB_OBJ) \
-               $(PASSDB_OBJ) \
+SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
                 $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ)
 
 RPCCLIENT_OBJ = rpcclient/rpcclient.o \
-               rpcclient/display_at.o \
-               rpcclient/display_event.o \
-               rpcclient/display_reg.o \
-               rpcclient/display_sam.o \
-               rpcclient/display_sec.o \
-               rpcclient/display_spool.o \
-               rpcclient/display_srv.o \
-               rpcclient/display_svc.o \
-               rpcclient/display_sync.o \
-               rpcclient/cmd_lsarpc.o \
-               rpcclient/cmd_wkssvc.o \
-               rpcclient/cmd_brs.o \
-               rpcclient/cmd_samr.o \
-               rpcclient/cmd_reg.o \
-               rpcclient/cmd_srvsvc.o \
-               rpcclient/cmd_svcctl.o \
-               rpcclient/cmd_netlogon.o \
-               rpcclient/cmd_atsvc.o \
-               rpcclient/cmd_spoolss.o \
-               rpcclient/cmd_eventlog.o \
-               $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
-               $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+             rpcclient/display.o \
+             rpcclient/cmd_lsarpc.o \
+             rpcclient/cmd_wkssvc.o \
+             rpcclient/cmd_samr.o \
+             rpcclient/cmd_reg.o \
+             rpcclient/cmd_srvsvc.o \
+             rpcclient/cmd_netlogon.o \
+             $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+             $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
 
 SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
                smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
@@ -423,9 +223,11 @@ SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
                 $(UBIQX_OBJ) $(LIB_OBJ)
 
 CLIENT_OBJ = client/client.o client/clitar.o \
-             $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
+             $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
-MOUNT_OBJ = client/smbmount.o client/clientutil.o \
+CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+
+MOUNT_OBJ = client/smbmount.o \
              $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
 MNT_OBJ = client/smbmnt.o \
@@ -434,23 +236,13 @@ MNT_OBJ = client/smbmnt.o \
 UMOUNT_OBJ = client/smbumount.o \
              $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
-NMB_AGENT_OBJ = utils/nmb-agent.o $(PARAM_OBJ) $(UBIQX_OBJ) \
-                $(LIBSMB_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
-
 NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \
-                $(LIBSMB_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ2)
-
-DEBUG2HTML_OBJ = utils/debug2html.o $(PARAM_OBJ) $(LIB_OBJ)
-
-SMB_AGENT_OBJ = utils/smb-agent.o $(LIBSMB_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
-                       $(RPC_PARSE_OBJ2) rpc_client/cli_use.o
-
-SMB_CLIENT_OBJ = smb-client.o $(PARAM_OBJ) $(LIB_OBJ)
+                $(LIBSMB_OBJ) $(LIB_OBJ)
 
-SMBTORTURE_OBJ = utils/torture.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+SMBTORTURE_OBJ = utils/torture.o utils/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
                  $(UBIQX_OBJ) $(LIB_OBJ)
 
-SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+MASKTEST_OBJ = utils/masktest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
                  $(UBIQX_OBJ) $(LIB_OBJ)
 
 RPCTORTURE_OBJ = utils/rpctorture.o \
@@ -461,15 +253,15 @@ RPCTORTURE_OBJ = utils/rpctorture.o \
              rpcclient/cmd_srvsvc.o \
              rpcclient/cmd_netlogon.o \
              $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
-             $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
-               $(PASSDB_OBJ) 
+             $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+
+DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
+
+SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+                 $(UBIQX_OBJ) $(LIB_OBJ)
 
-PROTO_OBJ = $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) $(WINREGD_OBJ1) $(SAMRD_OBJ1) \
-               $(SRVSVCD_OBJ1) $(WKSSVCD_OBJ1) $(BROWSERD_OBJ1) \
-               $(SPOOLSSD_OBJ1) $(NETLOGOND_OBJ1) \
-               $(LSARPCD_OBJ1) $(SMBD_OBJ) $(NMBD_OBJ) \
-               $(SWAT_OBJ) $(CLIENT_OBJ) \
-           $(RPCCLIENT_OBJ) $(SMBWRAPPER_OBJ) $(SMBPASSWD_OBJ)
+PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
+           $(RPCCLIENT_OBJ) $(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ)
 
 PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
 PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
@@ -480,20 +272,24 @@ PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
 
 all : CHECK $(SPROGS) $(PROGS) 
 
-smbwrapper : CHECK bin/smbsh bin/smbwrapper.so @WRAP32@
+smbwrapper : CHECK bin/smbsh bin/smbwrapper.@SHLIBEXT@ @WRAP32@
 
 smbtorture : CHECK bin/smbtorture
 
+masktest : CHECK bin/masktest
+
 rpctorture : CHECK bin/rpctorture
 
-smbfilter : CHECK bin/smbfilter
+debug2html : CHECK bin/debug2html
 
+smbfilter : CHECK bin/smbfilter
 
 .SUFFIXES:
 .SUFFIXES: .c .o .po .po32
 
 CHECK:
        @echo "Using FLAGS = $(FLAGS)"
+       @echo "Using FLAGS32 = $(FLAGS32)"
        @echo "Using LIBS = $(LIBS)"
 
 MAKEDIR = || exec false; \
@@ -516,6 +312,7 @@ MAKEDIR = || exec false; \
        @echo Compiling $*.c
        @$(CC) -I. -I$(srcdir) $(FLAGS) -c $< \
          -o $@ @MAINT@ -Wp,-MD,.deps/$@
+@BROKEN_CC@    -mv `echo $@ | sed 's%^.*/%%g'` $@
 @MAINT@        @sed 's|^'`echo $@ | sed 's,.*/,,'`':|$@:|' \
 @MAINT@          <.deps/$@ >.deps/$@d && \
 @MAINT@        rm -f .deps/$@ && : >.deps/.stamp
@@ -529,6 +326,7 @@ MAKEDIR = || exec false; \
        @echo Compiling $*.c with @PICFLAG@
        @$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< \
          -o $*.po.o @MAINT@ -Wp,-MD,.deps/$@
+@BROKEN_CC@    -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@.o
 @MAINT@        @sed 's|^'`echo $*\.po\.o | sed 's,.*/,,'`':|$@:|' \
 @MAINT@          <.deps/$@ >.deps/$@d && \
 @MAINT@        rm -f .deps/$@ && : >.deps/.stamp
@@ -542,8 +340,9 @@ MAKEDIR = || exec false; \
 @MAINT@         else dir=.deps/`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` \
 @MAINT@              $(MAKEDIR); fi; rm -f .deps/$@ .deps/$@d
        @echo Compiling $*.c with @PICFLAG@ and -32
-       @$(CC) -32 -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< \
+       @$(CC) -32 -I. -I$(srcdir) $(FLAGS32) @PICFLAG@ -c $< \
          -o $*.po32.o @MAINT@ -Wp,-MD,.deps/$@
+@BROKEN_CC@    -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po32$$%.o%'` $@.o
 @MAINT@        @sed 's|^'`echo $*.po32.o | sed 's,.*/,,'`':|$@:|' \
 @MAINT@          <.deps/$@ >.deps/$@d && \
 @MAINT@        rm -f .deps/$@ && : >.deps/.stamp
@@ -558,42 +357,6 @@ bin/smbd: $(SMBD_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LIBS) 
 
-bin/svcctld: $(SVCCTLD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SVCCTLD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/lsarpcd: $(LSARPCD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(LSARPCD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/spoolssd: $(SPOOLSSD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SPOOLSSD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/srvsvcd: $(SRVSVCD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SRVSVCD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/wkssvcd: $(WKSSVCD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(WKSSVCD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/browserd: $(BROWSERD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(BROWSERD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/winregd: $(WINREGD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(WINREGD_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/netlogond: $(NETLOGOND_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(NETLOGOND_OBJ) $(LDFLAGS) $(LIBS) 
-
-bin/samrd: $(SAMRD_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SAMRD_OBJ) $(LDFLAGS) $(LIBS) 
-
 bin/nmbd: $(NMBD_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(LIBS)
@@ -614,6 +377,10 @@ bin/smbclient: $(CLIENT_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(LIBS)
 
+bin/smbspool: $(CUPS_OBJ) bin/.dummy
+       @echo Linking $@
+       @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS)
+
 bin/smbmount: $(MOUNT_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LIBS)
@@ -646,6 +413,10 @@ bin/make_smbcodepage: $(MAKE_SMBCODEPAGE_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(MAKE_SMBCODEPAGE_OBJ) $(LDFLAGS) $(LIBS)
 
+bin/make_unicodemap: $(MAKE_UNICODEMAP_OBJ) bin/.dummy
+       @echo Linking $@
+       @$(CC) $(FLAGS) -o $@ $(MAKE_UNICODEMAP_OBJ) $(LDFLAGS) $(LIBS)
+
 bin/nmblookup: $(NMBLOOKUP_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(LIBS)
@@ -658,35 +429,27 @@ bin/smbtorture: $(SMBTORTURE_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(LIBS)
 
-bin/rpctorture: $(RPCTORTURE_OBJ) bin/.dummy
+bin/masktest: $(MASKTEST_OBJ) bin/.dummy
        @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(LIBS)
+       @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS)
 
-bin/smb-client: $(SMB_CLIENT_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SMB_CLIENT_OBJ) $(LDFLAGS) $(LIBS)
-
-bin/nmb-agent: $(NMB_AGENT_OBJ) bin/.dummy
+bin/rpctorture: $(RPCTORTURE_OBJ) bin/.dummy
        @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(NMB_AGENT_OBJ) $(LDFLAGS) $(LIBS)
+       @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(LIBS)
 
-bin/smb-agent: $(SMB_AGENT_OBJ) bin/.dummy
+bin/debug2html: $(DEBUG2HTML_OBJ) bin/.dummy
        @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SMB_AGENT_OBJ) $(LDFLAGS) $(LIBS)
+       @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(LIBS)
 
 bin/smbfilter: $(SMBFILTER_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS)
 
-bin/debug2html: $(DEBUG2HTML_OBJ) bin/.dummy
-       @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(LIBS)
-
-bin/smbwrapper.so: $(PICOBJS)
+bin/smbwrapper.@SHLIBEXT@: $(PICOBJS)
        @echo Linking shared library $@
        @$(LD) @LDSHFLAGS@ -o $@ $(PICOBJS) $(LIBS)
 
-bin/smbwrapper.32.so: $(PICOBJS32)
+bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32)
        @echo Linking shared library $@
        @$(LD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LIBS)
 
@@ -700,6 +463,9 @@ installdirs:
        $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) \
        $(BASEDIR) $(SBINDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(CODEPAGEDIR)
 
+installservers: all installdirs
+       @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(SPROGS)
+
 installbin: all installdirs
        @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(SPROGS)
        @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
@@ -737,17 +503,17 @@ uninstallcp:
        @$(SHELL) $(srcdir)/script/uninstallcp.sh $(CODEPAGEDIR) $(CODEPAGELIST)
 
 clean: 
-       -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.so
+       -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@
 
 proto: 
        @echo rebuilding include/proto.h
        @cd $(srcdir) && $(AWK) -f script/mkproto.awk `echo $(PROTO_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/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 dd519ae440fc056e5435a6f576f2eb6b02792ae7..6d5fdfa9b17a9b3a61eff7f6d7480768c6364c77 100644 (file)
@@ -1,3 +1,4 @@
+#undef HAVE_VOLATILE
 #undef HAVE_BROKEN_READDIR
 #undef HAVE_ERRNO_DECL
 #undef HAVE_LONGLONG
@@ -5,6 +6,7 @@
 #undef HAVE_REMSH
 #undef HAVE_UNSIGNED_CHAR
 #undef HAVE_UTIMBUF
+#undef HAVE_SIG_ATOMIC_T_TYPE
 #undef ssize_t
 #undef ino_t
 #undef ssize_t
 #undef AIX
 #undef BSD
 #undef IRIX
+#undef IRIX6
 #undef HPUX
 #undef QNX
 #undef SCO
 #undef OSF1
 #undef NEXT2
+#undef RELIANTUNIX
 #undef HAVE_SHARED_MMAP
+#undef HAVE_MMAP
 #undef HAVE_SYSV_IPC
 #undef HAVE_FCNTL_LOCK
 #undef HAVE_FTRUNCATE_EXTEND
+#undef FTRUNCATE_NEEDS_ROOT
 #undef HAVE_TRAPDOOR_UID
 #undef HAVE_ROOT
 #undef HAVE_UNION_SEMUN
-#undef HAVE_NETMASK_IFCONF
 #undef HAVE_GETTIMEOFDAY_TZ
 #undef HAVE_SOCK_SIN_LEN
 #undef STAT_READ_FILSYS
 #undef STAT_STATFS4
 #undef STAT_STATVFS
 #undef STAT_STATVFS64
-#undef HAVE_NETMASK_IFREQ
-#undef HAVE_NETMASK_AIX
+#undef HAVE_IFACE_AIX
+#undef HAVE_IFACE_IFCONF
+#undef HAVE_IFACE_IFREQ
 #undef HAVE_CRYPT
 #undef HAVE_PUTPRPWNAM
 #undef HAVE_SET_AUTH_PARAMETERS
-#undef WITH_MMAP
 #undef WITH_SYSLOG
 #undef WITH_PROFILE
 #undef WITH_SSL
 #undef WITH_LDAP
 #undef WITH_NISPLUS
+#undef WITH_PAM
 #undef WITH_NISPLUS_HOME
 #undef WITH_AUTOMOUNT
 #undef WITH_SMBMOUNT
-#undef HAVE_PAM_AUTHENTICATE
 #undef HAVE_BROKEN_GETGROUPS
 #undef REPLACE_GETPASS
 #undef REPLACE_INET_NTOA
 #undef HAVE_FILE_MACRO
 #undef HAVE_FUNCTION_MACRO
 #undef HAVE_SETRESUID_DECL
-#undef HAVE_CRYPT_DECL
 #undef HAVE_SETRESUID
 #undef WITH_NETATALK
 #undef HAVE_INO64_T
@@ -75,7 +79,6 @@
 #undef SIZEOF_OFF_T
 #undef STAT_STATVFS64
 #undef HAVE_LIBREADLINE
-#undef HAVE_READLINE_FCF_PROTO
 #undef HAVE_KERNEL_OPLOCKS
 #undef HAVE_IRIX_SPECIFIC_CAPABILITIES
 #undef HAVE_INT16_FROM_RPC_RPC_H
 #undef HAVE_INT32_FROM_RPC_RPC_H
 #undef HAVE_UINT32_FROM_RPC_RPC_H
 #undef KRB4_AUTH
+#undef KRB5_AUTH
 #undef SEEKDIR_RETURNS_VOID
 #undef HAVE_DIRENT_D_OFF
 #undef HAVE_GETSPNAM
 #undef HAVE_BIGCRYPT
 #undef HAVE_GETPRPWNAM
+#undef HAVE_FSTAT64
+#undef HAVE_LSTAT64
+#undef HAVE_STAT64
+#undef HAVE_SETRESGID
+#undef HAVE_SETRESGID_DECL
+#undef HAVE_SHADOW_H
+#undef HAVE_MEMSET
+#undef HAVE_STRCASECMP
+#undef HAVE_STRUCT_DIRENT64
+#undef HAVE_TRUNCATED_SALT
+#undef BROKEN_NISPLUS_INCLUDE_FILES
+#undef HAVE_RPC_AUTH_ERROR_CONFLICT
+#undef HAVE_EXPLICIT_LARGEFILE_SUPPORT
+#undef USE_BOTH_CRYPT_CALLS
+#undef HAVE_BROKEN_FCNTL64_LOCKS
+#undef HAVE_FNMATCH
+#undef USE_SETEUID
+#undef USE_SETRESUID
+#undef USE_SETREUID
+#undef USE_SETUIDX
index ff0fcefb868961d7b36749933a5f90cf94361a56..eb29792bea0eed43a63bb8e0a7ff1e9e13d52d4e 100644 (file)
@@ -7,7 +7,7 @@ Quickly scrabbled together from odd bits of mail and memory. Please update.
 This document gives a general overview of how Samba works
 internally. The Samba Team has tried to come up with a model which is
 the best possible compromise between elegance, portability, security
-and the constraints imposed by the very message SMB and CIFS
+and the constraints imposed by the very messy SMB and CIFS
 protocol. 
 
 It also tries to answer some of the frequently asked questions such as:
index 7effbfef8dd87ee1a9397c2af25267fd804de6c4..11ce0d754e8ab06b806281fe89d3e5e186134344 100644 (file)
@@ -32,7 +32,7 @@ static char this_salt[100]="";
 static char this_crypted[100]="";
 
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
 /*******************************************************************
 check on PAM authentication
 ********************************************************************/
@@ -136,6 +136,10 @@ static BOOL pam_auth(char *user,char *password)
 
 
 #ifdef WITH_AFS
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
 /*******************************************************************
 check on AFS authentication
 ********************************************************************/
@@ -158,6 +162,7 @@ static BOOL afs_auth(char *user,char *password)
                                       &reason) == 0) {
                return(True);
        }
+       DEBUG(1,("AFS authentication for \"%s\" failed (%s)\n", user, reason));
        return(False);
 }
 #endif
@@ -165,6 +170,9 @@ static BOOL afs_auth(char *user,char *password)
 
 #ifdef WITH_DFS
 
+#include <dce/dce_error.h>
+#include <dce/sec_login.h>
+
 /*****************************************************************
  This new version of the DFS_AUTH code was donated by Karsten Muuss
  <muuss@or.uni-bonn.de>. It fixes the following problems with the
@@ -195,6 +203,7 @@ static BOOL dfs_auth(char *user,char *password)
        sec_passwd_rec_t passwd_rec;
        sec_login_auth_src_t auth_src = sec_login_auth_src_network;
        unsigned char dce_errstr[dce_c_error_string_len];
+       gid_t egid;
 
        if (dcelogin_atmost_once) return(False);
 
@@ -322,14 +331,16 @@ static BOOL dfs_auth(char *user,char *password)
         * back to being root on error though. JRA.
         */
        
-       if (setregid(-1, pw->pw_gid) != 0) {
+       egid = getegid();
+
+       if (set_effective_gid(pw->pw_gid) != 0) {
                DEBUG(0,("Can't set egid to %d (%s)\n", 
                         pw->pw_gid, strerror(errno)));
                return False;
        }
 
-       if (setreuid(-1, pw->pw_uid) != 0) {
-               setgid(0);
+       if (set_effective_uid(pw->pw_uid) != 0) {
+               set_effective_gid(egid);
                DEBUG(0,("Can't set euid to %d (%s)\n", 
                         pw->pw_uid, strerror(errno)));
                return False;
@@ -340,24 +351,17 @@ static BOOL dfs_auth(char *user,char *password)
                                     &my_dce_sec_context,
                                     &err) == 0) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
                         user,dce_errstr));
-               return(False);
+               goto err;
        }
 
        sec_login_get_pwent(my_dce_sec_context, 
                            (sec_login_passwd_t*)&pw, &err);
        if (err != error_status_ok ) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        passwd_rec.version_number = sec_passwd_c_version_none;
@@ -370,24 +374,16 @@ static BOOL dfs_auth(char *user,char *password)
                                    &auth_src, &err);
        if (err != error_status_ok ) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
                         user,dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        sec_login_certify_identity(my_dce_sec_context, &err);
        if (err != error_status_ok) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        if (auth_src != sec_login_auth_src_network) { 
@@ -401,10 +397,7 @@ static BOOL dfs_auth(char *user,char *password)
                         user,dce_errstr));
                
                sec_login_purge_context(&my_dce_sec_context, &err);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        sec_login_get_pwent(my_dce_sec_context, 
@@ -412,11 +405,7 @@ static BOOL dfs_auth(char *user,char *password)
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
@@ -434,21 +423,24 @@ static BOOL dfs_auth(char *user,char *password)
        sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
        
-       setuid(0);
-       setgid(0);
+       set_effective_uid(0);
+       set_effective_gid(0);
        
        DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time))));
        
        dcelogin_atmost_once = 1;
        return (True);
+
+err:
+
+       /* Go back to root, JRA. */
+       set_effective_uid(0);
+       set_effective_gid(egid);
+       return(False);
 }
 
 void dfs_unlogin(void)
@@ -467,6 +459,9 @@ void dfs_unlogin(void)
 #endif
 
 #ifdef KRB5_AUTH
+
+#include <krb5.h>
+
 /*******************************************************************
 check on Kerberos authentication
 ********************************************************************/
@@ -614,6 +609,7 @@ static char *osf1_bigcrypt(char *password,char *salt1)
        
        StrnCpy(salt,salt1,2);
        StrnCpy(result,salt1,2);
+       result[2]='\0';
 
        for (i=0; i<parts;i++) {
                p1 = crypt(p2,salt);
@@ -680,7 +676,7 @@ core of password checking routine
 static BOOL password_check(char *password)
 {
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
        /* This falls through if the password check fails
           - if HAVE_CRYPT is not defined this causes an error msg
           saying Warning - no crypt available
@@ -691,23 +687,23 @@ static BOOL password_check(char *password)
           Hence we make a direct return to avoid a second chance!!!
        */
        return (pam_auth(this_user,password));
-#endif
+#endif /* WITH_PAM */
        
 #ifdef WITH_AFS
        if (afs_auth(this_user,password)) return(True);
-#endif
+#endif /* WITH_AFS */
        
 #ifdef WITH_DFS
        if (dfs_auth(this_user,password)) return(True);
-#endif 
+#endif /* WITH_DFS */
 
 #ifdef KRB5_AUTH
        if (krb5_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB5_AUTH */
 
 #ifdef KRB4_AUTH
        if (krb4_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB4_AUTH */
 
 #ifdef OSF1_ENH_SEC
        {
@@ -718,26 +714,42 @@ static BOOL password_check(char *password)
          }
          return ret;
        }
-#endif
+#endif /* OSF1_ENH_SEC */
 
 #ifdef ULTRIX_AUTH
        return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif
+#endif /* ULTRIX_AUTH */
 
 #ifdef LINUX_BIGCRYPT
        return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif
+#endif /* LINUX_BIGCRYPT */
+
+#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
+
+       /*
+        * Some systems have bigcrypt in the C library but might not
+        * actually use it for the password hashes (HPUX 10.20) is
+        * a noteable example. So we try bigcrypt first, followed
+        * by crypt.
+        */
+
+       if(strcmp(bigcrypt(password,this_salt),this_crypted) == 0)
+               return True;
+       else 
+               return (strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
+#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 
 #ifdef HAVE_BIGCRYPT
        return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_BIGCRYPT */
 
 #ifndef HAVE_CRYPT
        DEBUG(1,("Warning - no crypt available\n"));
        return(False);
-#else
+#else /* HAVE_CRYPT */
        return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_CRYPT */
+#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 }
 
 
@@ -753,13 +765,12 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
 {
        pstring pass2;
        int level = lp_passwordlevel();
-       const struct passwd *pass;
+       struct passwd *pass;
 
        if (password) password[pwlen] = 0;
 
 #if DEBUG_PASSWORD
-       DEBUG(100,("checking user=[%s] pass=",user));
-       dump_data(100, password, strlen(password));
+       DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
 #endif
 
        if (!password) {
@@ -785,12 +796,76 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
                return(False);
        }
 
+#ifdef HAVE_GETSPNAM
+       {
+               struct spwd *spass;
+
+               /* many shadow systems require you to be root to get
+                  the password, in most cases this should already be
+                  the case when this function is called, except
+                  perhaps for IPC password changing requests */
+
+               spass = getspnam(pass->pw_name);
+               if (spass && spass->sp_pwdp) {
+                       pstrcpy(pass->pw_passwd,spass->sp_pwdp);
+               }
+       }
+#elif defined(IA_UINFO)
+       {
+               /* Need to get password with SVR4.2's ia_ functions
+                  instead of get{sp,pw}ent functions. Required by
+                  UnixWare 2.x, tested on version
+                  2.1. (tangent@cyberport.com) */
+               uinfo_t uinfo;
+               if (ia_openinfo(pass->pw_name, &uinfo) != -1) {
+                       ia_get_logpwd(uinfo, &(pass->pw_passwd));
+               }
+       }
+#endif
+
+#ifdef HAVE_GETPRPWNAM
+       {
+               struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
+               if (pr_pw && pr_pw->ufld.fd_encrypt)
+                       pstrcpy(pass->pw_passwd,pr_pw->ufld.fd_encrypt);
+       }
+#endif
+
+#ifdef OSF1_ENH_SEC
+       {
+               struct pr_passwd *mypasswd;
+               DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",
+                        user));
+               mypasswd = getprpwnam (user);
+               if (mypasswd) { 
+                       fstrcpy(pass->pw_name,mypasswd->ufld.fd_name);
+                       fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
+               } else {
+                       DEBUG(5,("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
+                                user));
+               }
+       }
+#endif
+
+#ifdef ULTRIX_AUTH
+       {
+               AUTHORIZATION *ap = getauthuid(pass->pw_uid);
+               if (ap) {
+                       fstrcpy(pass->pw_passwd, ap->a_password);
+                       endauthent();
+               }
+       }
+#endif
+
        /* extract relevant info */
        fstrcpy(this_user,pass->pw_name);  
        fstrcpy(this_salt,pass->pw_passwd);
+
+#if defined(HAVE_TRUNCATED_SALT)
        /* crypt on some platforms (HPUX in particular)
           won't work with more than 2 salt characters. */
        this_salt[2] = 0;
+#endif
        
        fstrcpy(this_crypted,pass->pw_passwd);
        
index 180aa493bac86839ff34801c615e8f331f2ad717..292da56497b72a9f696ff15627b58f1a514021ee 100644 (file)
@@ -35,12 +35,12 @@ pstring cd_path = "";
 static pstring service;
 static pstring desthost;
 extern pstring global_myname;
-extern pstring myhostname;
 static pstring password;
 static pstring username;
 static pstring workgroup;
 static char *cmdstr;
 static BOOL got_pass;
+static int io_bufsize = 65520;
 extern struct in_addr ipzero;
 extern pstring scope;
 
@@ -149,18 +149,16 @@ static int readfile(char *b, int size, int n, FILE *f)
                return(fread(b,size,n,f));
   
        i = 0;
-       while (i < n) {
+       while (i < (n - 1) && (i < BUFFER_SIZE)) {
                if ((c = getc(f)) == EOF) {
                        break;
                }
       
                if (c == '\n') { /* change all LFs to CR/LF */
                        b[i++] = '\r';
-                       n++;
                }
       
-               if(i < n)
-                       b[i++] = c;
+               b[i++] = c;
        }
   
        return(i);
@@ -327,7 +325,7 @@ static void display_finfo(file_info *finfo)
 {
        if (do_this_one(finfo)) {
                time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
-               DEBUG(0,("  %-30s%7.7s%8.0f  %s",
+               DEBUG(0,("  %-30s%7.7s %8.0f  %s",
                         CNV_LANG(finfo->name),
                         attrib_string(finfo->mode),
                         (double)finfo->size,
@@ -349,9 +347,127 @@ static void do_du(file_info *finfo)
 
 static BOOL do_list_recurse;
 static BOOL do_list_dirs;
-static int do_list_attr;
+static char *do_list_queue = 0;
+static long do_list_queue_size = 0;
+static long do_list_queue_start = 0;
+static long do_list_queue_end = 0;
 static void (*do_list_fn)(file_info *);
 
+/****************************************************************************
+functions for do_list_queue
+  ****************************************************************************/
+
+/*
+ * The do_list_queue is a NUL-separated list of strings stored in a
+ * char*.  Since this is a FIFO, we keep track of the beginning and
+ * ending locations of the data in the queue.  When we overflow, we
+ * double the size of the char*.  When the start of the data passes
+ * the midpoint, we move everything back.  This is logically more
+ * complex than a linked list, but easier from a memory management
+ * angle.  In any memory error condition, do_list_queue is reset.
+ * Functions check to ensure that do_list_queue is non-NULL before
+ * accessing it.
+ */
+static void reset_do_list_queue(void)
+{
+       if (do_list_queue)
+       {
+               free(do_list_queue);
+       }
+       do_list_queue = 0;
+       do_list_queue_size = 0;
+       do_list_queue_start = 0;
+       do_list_queue_end = 0;
+}
+
+static void init_do_list_queue(void)
+{
+       reset_do_list_queue();
+       do_list_queue_size = 1024;
+       do_list_queue = malloc(do_list_queue_size);
+       if (do_list_queue == 0) { 
+               DEBUG(0,("malloc fail for size %d\n",
+                        (int)do_list_queue_size));
+               reset_do_list_queue();
+       } else {
+               memset(do_list_queue, 0, do_list_queue_size);
+       }
+}
+
+static void adjust_do_list_queue(void)
+{
+       /*
+        * If the starting point of the queue is more than half way through,
+        * move everything toward the beginning.
+        */
+       if (do_list_queue && (do_list_queue_start == do_list_queue_end))
+       {
+               DEBUG(4,("do_list_queue is empty\n"));
+               do_list_queue_start = do_list_queue_end = 0;
+               *do_list_queue = '\0';
+       }
+       else if (do_list_queue_start > (do_list_queue_size / 2))
+       {
+               DEBUG(4,("sliding do_list_queue backward\n"));
+               memmove(do_list_queue,
+                       do_list_queue + do_list_queue_start,
+                       do_list_queue_end - do_list_queue_start);
+               do_list_queue_end -= do_list_queue_start;
+               do_list_queue_start = 0;
+       }
+          
+}
+
+static void add_to_do_list_queue(const char* entry)
+{
+       long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
+       while (new_end > do_list_queue_size)
+       {
+               do_list_queue_size *= 2;
+               DEBUG(4,("enlarging do_list_queue to %d\n",
+                        (int)do_list_queue_size));
+               do_list_queue = Realloc(do_list_queue, do_list_queue_size);
+               if (! do_list_queue) {
+                       DEBUG(0,("failure enlarging do_list_queue to %d bytes\n",
+                                (int)do_list_queue_size));
+                       reset_do_list_queue();
+               }
+               else
+               {
+                       memset(do_list_queue + do_list_queue_size / 2,
+                              0, do_list_queue_size / 2);
+               }
+       }
+       if (do_list_queue)
+       {
+               pstrcpy(do_list_queue + do_list_queue_end, entry);
+               do_list_queue_end = new_end;
+               DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",
+                        entry, (int)do_list_queue_start, (int)do_list_queue_end));
+       }
+}
+
+static char *do_list_queue_head(void)
+{
+       return do_list_queue + do_list_queue_start;
+}
+
+static void remove_do_list_queue_head(void)
+{
+       if (do_list_queue_end > do_list_queue_start)
+       {
+               do_list_queue_start += strlen(do_list_queue_head()) + 1;
+               adjust_do_list_queue();
+               DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",
+                        (int)do_list_queue_start, (int)do_list_queue_end));
+       }
+}
+
+static int do_list_queue_empty(void)
+{
+       return (! (do_list_queue && *do_list_queue));
+}
+
 /****************************************************************************
 a helper for do_list
   ****************************************************************************/
@@ -372,11 +488,8 @@ static void do_list_helper(file_info *f, const char *mask)
                        if (!p) return;
                        p[1] = 0;
                        pstrcat(mask2, f->name);
-                       if (do_list_fn == display_finfo) {
-                               DEBUG(0,("\n%s\n",CNV_LANG(mask2)));
-                       }
                        pstrcat(mask2,"\\*");
-                       do_list(mask2, do_list_attr, do_list_fn, True, True);
+                       add_to_do_list_queue(mask2);
                }
                return;
        }
@@ -392,12 +505,68 @@ a wrapper around cli_list that adds recursion
   ****************************************************************************/
 void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
 {
+       static int in_do_list = 0;
+
+       if (in_do_list && rec)
+       {
+               fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");
+               exit(1);
+       }
+
+       in_do_list = 1;
+
        do_list_recurse = rec;
        do_list_dirs = dirs;
        do_list_fn = fn;
-       do_list_attr = attribute;
 
-       cli_list(cli, mask, attribute, do_list_helper);
+       if (rec)
+       {
+               init_do_list_queue();
+               add_to_do_list_queue(mask);
+               
+               while (! do_list_queue_empty())
+               {
+                       /*
+                        * Need to copy head so that it doesn't become
+                        * invalid inside the call to cli_list.  This
+                        * would happen if the list were expanded
+                        * during the call.
+                        * Fix from E. Jay Berkenbilt (ejb@ql.org)
+                        */
+                       pstring head;
+                       pstrcpy(head, do_list_queue_head());
+                       cli_list(cli, head, attribute, do_list_helper);
+                       remove_do_list_queue_head();
+                       if ((! do_list_queue_empty()) && (fn == display_finfo))
+                       {
+                               char* next_file = do_list_queue_head();
+                               char* save_ch = 0;
+                               if ((strlen(next_file) >= 2) &&
+                                   (next_file[strlen(next_file) - 1] == '*') &&
+                                   (next_file[strlen(next_file) - 2] == '\\'))
+                               {
+                                       save_ch = next_file +
+                                               strlen(next_file) - 2;
+                                       *save_ch = '\0';
+                               }
+                               DEBUG(0,("\n%s\n",CNV_LANG(next_file)));
+                               if (save_ch)
+                               {
+                                       *save_ch = '\\';
+                               }
+                       }
+               }
+       }
+       else
+       {
+               if (cli_list(cli, mask, attribute, do_list_helper) == -1)
+               {
+                       DEBUG(0, ("%s listing %s\n", cli_errstr(cli), mask));
+               }
+       }
+
+       in_do_list = 0;
+       reset_do_list_queue();
 }
 
 /****************************************************************************
@@ -476,7 +645,7 @@ static void do_get(char *rname,char *lname)
        BOOL newhandle = False;
        char *data;
        struct timeval tp_start;
-       int read_size = 65520;
+       int read_size = io_bufsize;
        uint16 attr;
        size_t size;
        off_t nread = 0;
@@ -517,7 +686,11 @@ static void do_get(char *rname,char *lname)
        DEBUG(2,("getting file %s of size %.0f as %s ", 
                 lname, (double)size, lname));
 
-       data = (char *)malloc(read_size);
+       if(!(data = (char *)malloc(read_size))) { 
+               DEBUG(0,("malloc fail for size %d\n", read_size));
+               cli_close(cli, fnum);
+               return;
+       }
 
        while (1) {
                int n = cli_read(cli, fnum, data, nread, read_size);
@@ -531,6 +704,13 @@ static void do_get(char *rname,char *lname)
       
                nread += n;
        }
+
+       if (nread < size) {
+               DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
+               CNV_LANG(rname), (long)nread));
+       }
+
+       free(data);
        
        if (!cli_close(cli, fnum)) {
                DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
@@ -743,7 +923,7 @@ static BOOL do_mkdir(char *name)
 
 
 /****************************************************************************
-make a directory of name "name"
+ Exit client.
 ****************************************************************************/
 static void cmd_quit(void)
 {
@@ -801,7 +981,7 @@ static void do_put(char *rname,char *lname)
        FILE *f;
        int nread=0;
        char *buf=NULL;
-       int maxwrite=65520;
+       int maxwrite=io_bufsize;
        
        struct timeval tp_start;
        GetTimeOfDay(&tp_start);
@@ -1151,6 +1331,24 @@ static void cmd_del(void)
        do_list(mask, attribute,do_del,False,False);
 }
 
+/****************************************************************************
+****************************************************************************/
+static void cmd_open(void)
+{
+       pstring mask;
+       fstring buf;
+       
+       pstrcpy(mask,cur_dir);
+       
+       if (!next_token(NULL,buf,NULL,sizeof(buf))) {
+               DEBUG(0,("del <filename>\n"));
+               return;
+       }
+       pstrcat(mask,buf);
+
+       cli_open(cli, mask, O_RDWR, DENY_ALL);
+}
+
 
 /****************************************************************************
 remove a directory
@@ -1332,6 +1530,7 @@ list a share name
 static void browse_fn(const char *name, uint32 m, const char *comment)
 {
         fstring typestr;
+
         *typestr=0;
 
         switch (m)
@@ -1375,18 +1574,40 @@ try and browse available connections on a host
 ****************************************************************************/
 static BOOL list_servers(char *wk_grp)
 {
+       if (!cli->server_domain) return False;
+
         printf("\n\tServer               Comment\n");
         printf("\t---------            -------\n");
 
-       cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, server_fn);
+       cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn);
 
         printf("\n\tWorkgroup            Master\n");
         printf("\t---------            -------\n");
 
-       cli_NetServerEnum(cli, workgroup, SV_TYPE_DOMAIN_ENUM, server_fn);
+       cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn);
        return True;
 }
 
+#if defined(HAVE_LIBREADLINE)
+#  if defined(HAVE_READLINE_HISTORY_H) || defined(HAVE_HISTORY_H)
+/****************************************************************************
+history
+****************************************************************************/
+static void cmd_history(void)
+{
+       HIST_ENTRY **hlist;
+       register int i;
+
+       hlist = history_list ();        /* Get pointer to history list */
+       
+       if (hlist)                      /* If list not empty */
+       {
+               for (i = 0; hlist[i]; i++)      /* then display it */
+                       DEBUG(0, ("%d: %s\n", i, hlist[i]->line));
+       }
+}
+#  endif 
+#endif
 
 /* Some constants for completing filename arguments */
 
@@ -1417,6 +1638,7 @@ struct
   {"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}},  
   {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
   {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
+  {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
   {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
   {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
   {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
@@ -1442,6 +1664,9 @@ struct
   {"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
   {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
   {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
+#ifdef HAVE_LIBREADLINE
+  {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
+#endif
   {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
   {"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
 };
@@ -1499,6 +1724,7 @@ static void cmd_help(void)
        }
 }
 
+#ifndef HAVE_LIBREADLINE
 /****************************************************************************
 wait for keyboard activity, swallowing network packets
 ****************************************************************************/
@@ -1514,7 +1740,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,&timeout);
       
                if (FD_ISSET(fileno(stdin),&fds))
                        return;
@@ -1529,6 +1755,7 @@ static void wait_keyboard(void)
                cli_chkpath(cli, "\\");
        }  
 }
+#endif
 
 /****************************************************************************
 process a -c command string
@@ -1571,223 +1798,58 @@ static void process_command_string(char *cmd)
        }
 }      
 
-#ifdef HAVE_LIBREADLINE
-
-/****************************************************************************
-GNU readline completion functions
-****************************************************************************/
-
-/* Argh.  This is where it gets ugly.  We really need to be able to
-   pass back from the do_list() iterator function. */
-
-static int compl_state;
-static char *compl_text;
-static pstring result;
-
-/* Iterator function for do_list() */
-
-static void complete_process_file(file_info *f)
-{
-    /* Do we have a partial match? */
-    
-    if ((compl_state >= 0) && (strncmp(compl_text, f->name, 
-                                      strlen(compl_text)) == 0)) {
-       
-       /* Return filename if we have made enough matches */
-       
-       if (compl_state == 0) {
-           pstrcpy(result, f->name);
-           compl_state = -1;
-           
-           return;
-       }
-       compl_state--;
-    }
-}
-
-/* Complete a remote file */
-
-static char *complete_remote_file(char *text, int state)
-{
-    int attribute = aDIR | aSYSTEM | aHIDDEN;
-    pstring mask;
-    
-    /* Create dir mask */
-    
-    pstrcpy(mask, cur_dir);
-    pstrcat(mask, "*");
-    
-    /* Initialise static vars for filename match */
-    
-    compl_text = text;
-    compl_state = state;
-    result[0] = '\0';
-    
-    /* Iterate over all files in directory */
-    
-    do_list(mask, attribute, complete_process_file, False, True);
-    
-    /* Return matched filename */
-    
-    if (result[0] != '\0') {
-       return strdup(result);      /* Readline will dispose of strings */
-    } else {
-       return NULL;
-    }
-}
-
-/* Complete a smbclient command */
-
-static char *complete_cmd(char *text, int state)
-{
-    static int cmd_index;
-    char *name;
-    
-    /* Initialise */
-    
-    if (state == 0) {
-       cmd_index = 0;
-    }
-    
-    /* Return the next name which partially matches the list of commands */
-    
-    while (strlen(name = commands[cmd_index++].name) > 0) {
-       if (strncmp(name, text, strlen(text)) == 0) {
-           return strdup(name);
-       }
-    }
-    
-    return NULL;
-}
-
-/* Main completion function for smbclient.  Work out which word we are
-   trying to complete and call the appropriate helper function -
-   complete_cmd() if we are completing smbclient commands,
-   comlete_remote_file() if we are completing a file on the remote end,
-   filename_completion_function() builtin to GNU readline for local 
-   files. */
-
-static char **completion_fn(char *text, int start, int end)
-{
-  int i, num_words, cmd_index;
-  char lastch = ' ';
-
-  /* If we are at the start of a word, we are completing a smbclient
-     command. */
-
-  if (start == 0) {
-    return completion_matches(text, complete_cmd);
-  }
-
-  /* Count # of words in command */
-
-  num_words = 0;
-  for (i = 0; i <= end; i++) {
-    if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
-      num_words++;
-    lastch = rl_line_buffer[i];
-  }
-
-  if (rl_line_buffer[end] == ' ')
-    num_words++;
-
-  /* Work out which command we are completing for */
-
-  for (cmd_index = 0; strcmp(commands[cmd_index].name, "") != 0; 
-       cmd_index++) {
-
-    /* Check each command in array */
-
-    if (strncmp(rl_line_buffer, commands[cmd_index].name,
-                strlen(commands[cmd_index].name)) == 0) {
-
-      /* Call appropriate completion function */
-
-      if ((num_words == 2) || (num_words == 3)) {
-        switch (commands[cmd_index].compl_args[num_words - 2]) {
-
-        case COMPL_REMOTE:
-          return completion_matches(text, complete_remote_file);
-          break;
-
-        case COMPL_LOCAL:
-          return completion_matches(text, filename_completion_function);
-          break;
-
-        default:
-            /* An invalid completion type */
-            break;
-        }
-      }
-
-      /* We're either completing an argument > 3 or found an invalid
-         completion type.  Either way do nothing about it. */
-
-      break;
-    }
-  }
-  return NULL;
-}
-
-/* To avoid filename completion being activated when no valid
-   completions are found, we assign this stub completion function
-   to the rl_completion_entry_function variable. */
-
-static char *complete_cmd_null(char *text, int state)
-{
-    return NULL;
-}
-
-#endif /* HAVE_LIBREADLINE */
-
 /****************************************************************************
 process commands on stdin
 ****************************************************************************/
 static void process_stdin(void)
 {
        pstring line;
-#ifdef HAVE_LIBREADLINE
-       pstring promptline;
-#endif
        char *ptr;
 
+#ifdef HAVE_LIBREADLINE
+/* Minimal readline support, 29Jun1999, s.xenitellis@rhbnc.ac.uk */
+#ifdef PROMPTSIZE
+#undef PROMPTSIZE
+#endif
+#define PROMPTSIZE 2048
+       char prompt_str[PROMPTSIZE];    /* This holds the buffer "smb: \dir1\> " */
+       
+        char *temp;                    /* Gets the buffer from readline() */
+       temp = (char *)NULL;
+#endif
        while (!feof(stdin)) {
                fstring tok;
                int i;
+#ifdef HAVE_LIBREADLINE
+               if ( temp != (char *)NULL )
+               {
+                       free( temp );   /* Free memory allocated every time by readline() */
+                       temp = (char *)NULL;
+               }
 
-#ifndef HAVE_LIBREADLINE
+               snprintf( prompt_str, PROMPTSIZE - 1, "smb: %s> ", CNV_LANG(cur_dir) );
+
+               temp = readline( prompt_str );          /* We read the line here */
 
+               if ( !temp )
+                       break;          /* EOF occured */
+
+               if ( *temp )            /* If non-empty line, save to history */
+                       add_history (temp);
+       
+               strncpy( line, temp, 1023 ); /* Maximum size of (pstring)line. Null is guarranteed. */
+#else 
                /* display a prompt */
                DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
                dbgflush( );
-
+               
                wait_keyboard();
                
                /* and get a response */
                if (!fgets(line,1000,stdin))
                        break;
-
-#else /* !HAVE_LIBREADLINE */
-
-               /* Read input using GNU Readline */
-               
-               slprintf(promptline, sizeof(promptline) - 1, "smb: %s> ", 
-                        CNV_LANG(cur_dir));
-
-               if (!readline(promptline))
-                   break;
-               
-               /* Copy read line to samba buffer */
-               
-               pstrcpy(line, rl_line_buffer);
-               pstrcat(line, "\n");
-               
-               /* Add line to history */
-               
-               if (strlen(line) > 0)
-                   add_history(line);          
 #endif
+
                /* input language code to internal one */
                CNV_INPUT (line);
                
@@ -1815,22 +1877,15 @@ static void process_stdin(void)
 /***************************************************** 
 return a connection to a server
 *******************************************************/
-struct cli_state *do_connect(char *server, char *share, int smb_port)
+struct cli_state *do_connect(char *server, char *share)
 {
-       struct cli_state *smb_cli;
-       struct nmb_name called, calling, stupid_smbserver_called;
+       struct cli_state *c;
+       struct nmb_name called, calling;
        char *server_n;
        struct in_addr ip;
        extern struct in_addr ipzero;
 
-       if ((smb_cli=cli_initialise(NULL)) == NULL)
-       {
-               DEBUG(1,("cli_initialise failed\n"));
-               return NULL;
-       }
-
-       if (*share == '\\')
-       {
+       if (*share == '\\') {
                server = share+2;
                share = strchr(server,'\\');
                if (!share) return NULL;
@@ -1844,52 +1899,86 @@ struct cli_state *do_connect(char *server, char *share, int smb_port)
 
        make_nmb_name(&calling, global_myname, 0x0, "");
        make_nmb_name(&called , server, name_type, "");
-       make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope);
-
-       fstrcpy(smb_cli->usr.user_name, username);
-       fstrcpy(smb_cli->usr.domain, workgroup);
 
+ again:
        ip = ipzero;
        if (have_ip) ip = dest_ip;
 
-       if (cli_set_port(smb_cli, smb_port) == 0)
-       {
+       /* have to open a new connection */
+       if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) == 0) ||
+           !cli_connect(c, server_n, &ip)) {
+               DEBUG(0,("Connection to %s failed\n", server_n));
                return NULL;
        }
 
-       /* set the password cache info */
-       if (got_pass)
-       {
-               if (password[0] == 0)
-               {
-                       pwd_set_nullpwd(&(smb_cli->usr.pwd));
+       if (!cli_session_request(c, &calling, &called)) {
+               char *p;
+               DEBUG(0,("session request to %s failed (%s)\n", 
+                        called.name, cli_errstr(c)));
+               cli_shutdown(c);
+               if ((p=strchr(called.name, '.'))) {
+                       *p = 0;
+                       goto again;
                }
-               else
-               {
-                       /* generate 16 byte hashes */
-                       pwd_make_lm_nt_16(&(smb_cli->usr.pwd), password);
+               if (strcmp(called.name, "*SMBSERVER")) {
+                       make_nmb_name(&called , "*SMBSERVER", 0x20, "");
+                       goto again;
                }
+               return NULL;
        }
-       else 
-       {
-               pwd_read(&(smb_cli->usr.pwd), "Password:", True);
+
+       DEBUG(4,(" session request ok\n"));
+
+       if (!cli_negprot(c)) {
+               DEBUG(0,("protocol negotiation failed\n"));
+               cli_shutdown(c);
+               return NULL;
        }
 
-       /* paranoia: destroy the local copy of the password */
-       bzero(password, sizeof(password)); 
+       if (!got_pass) {
+               char *pass = getpass("Password: ");
+               if (pass) {
+                       pstrcpy(password, pass);
+               }
+       }
 
-       smb_cli->use_ntlmv2 = lp_client_ntlmv2();
+       if (!cli_session_setup(c, username, 
+                              password, strlen(password),
+                              password, strlen(password),
+                              workgroup)) {
+               /* if a password was not supplied then try again with a null username */
+               if (password[0] || !username[0] || 
+                   !cli_session_setup(c, "", "", 0, "", 0, workgroup)) { 
+                       DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
+                       return NULL;
+               }
+               DEBUG(0,("Anonymous login successful\n"));
+       }
 
-       if (!cli_establish_connection(smb_cli, server, &ip, &calling, &called,
-                                     share, "?????", False, True) &&
-           !cli_establish_connection(smb_cli, server, &ip,
-                                     &calling, &stupid_smbserver_called,
-                                     share, "?????", False, True))
-       {
+       /*
+        * These next two lines are needed to emulate
+        * old client behaviour for people who have
+        * scripts based on client output.
+        * QUESTION ? Do we want to have a 'client compatibility
+        * mode to turn these on/off ? JRA.
+        */
+
+       if (*c->server_domain || *c->server_os || *c->server_type)
+               DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+                       c->server_domain,c->server_os,c->server_type));
+       
+       DEBUG(4,(" session setup ok\n"));
+
+       if (!cli_send_tconX(c, share, "?????",
+                           password, strlen(password)+1)) {
+               DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+               cli_shutdown(c);
                return NULL;
        }
-               
-       return smb_cli;
+
+       DEBUG(4,(" tconx ok\n"));
+
+       return c;
 }
 
 
@@ -1898,7 +1987,7 @@ struct cli_state *do_connect(char *server, char *share, int smb_port)
 ****************************************************************************/
 static BOOL process(char *base_directory)
 {
-       cli = do_connect(desthost, service, port);
+       cli = do_connect(desthost, service);
        if (!cli) {
                return(False);
        }
@@ -1920,11 +2009,10 @@ usage on the program
 ****************************************************************************/
 static void usage(char *pname)
 {
-  DEBUG(0,("Usage: %s service <password> ", pname));
+  DEBUG(0,("Usage: %s service <password> [options]", pname));
 
   DEBUG(0,("\nVersion %s\n",VERSION));
   DEBUG(0,("\t-s smb.conf           pathname to smb.conf file\n"));
-  DEBUG(0,("\t-B IP addr            broadcast IP address to use\n"));
   DEBUG(0,("\t-O socket_options     socket options to use\n"));
   DEBUG(0,("\t-R name resolve order use these name resolution services only\n"));
   DEBUG(0,("\t-M host               send a winpopup message to the host\n"));
@@ -1946,6 +2034,7 @@ static void usage(char *pname)
   DEBUG(0,("\t-T<c|x>IXFqgbNan      command line tar\n"));
   DEBUG(0,("\t-D directory          start from directory\n"));
   DEBUG(0,("\t-c command string     execute semicolon separated commands\n"));
+  DEBUG(0,("\t-b xmit/send buffer   changes the transmit/send buffer (default: 65520)\n"));
   DEBUG(0,("\n"));
 }
 
@@ -2013,9 +2102,9 @@ static void get_password_file(void)
 /****************************************************************************
 handle a -L query
 ****************************************************************************/
-static int do_host_query(char *query_host, int smb_port)
+static int do_host_query(char *query_host)
 {
-       cli = do_connect(query_host, "IPC$", smb_port);
+       cli = do_connect(query_host, "IPC$");
        if (!cli)
                return 1;
 
@@ -2031,10 +2120,10 @@ static int do_host_query(char *query_host, int smb_port)
 /****************************************************************************
 handle a tar operation
 ****************************************************************************/
-static int do_tar_op(int smb_port, char *base_directory)
+static int do_tar_op(char *base_directory)
 {
        int ret;
-       cli = do_connect(desthost, service, smb_port);
+       cli = do_connect(desthost, service);
        if (!cli)
                return 1;
 
@@ -2096,7 +2185,6 @@ static int do_message_op(void)
        extern int optind;
        pstring query_host;
        BOOL message = False;
-       BOOL explicit_user = False;
        extern char tar_type;
        static pstring servicesf = CONFIGFILE;
        pstring term_code;
@@ -2116,15 +2204,39 @@ static int do_message_op(void)
 
        DEBUGLEVEL = 2;
 
+#ifdef HAVE_LIBREADLINE
+       /* Allow conditional parsing of the ~/.inputrc file. */
+       rl_readline_name = "smbclient";
+#endif    
        setup_logging(pname,True);
 
-       TimeInit();
-       charset_initialise();
+       /*
+        * If the -E option is given, be careful not to clobber stdout
+        * before processing the options.  28.Feb.99, richard@hacom.nl.
+        * Also pre-parse the -s option to get the service file name.
+        */
 
-       if(!get_myname(myhostname,NULL)) {
-               DEBUG(0,("Failed to get my hostname.\n"));
+       for (opt = 1; opt < argc; opt++) {
+               if (strcmp(argv[opt], "-E") == 0)
+                       dbf = stderr;
+               else if(strncmp(argv[opt], "-s", 2) == 0) {
+                       if(argv[opt][2] != '\0')
+                               pstrcpy(servicesf, &argv[opt][2]);
+                       else if(argv[opt+1] != NULL) {
+                               /*
+                                * At least one more arg left.
+                                */
+                               pstrcpy(servicesf, argv[opt+1]);
+                       } else {
+                               usage(pname);
+                               exit(1);
+                       }
+               }
        }
 
+       TimeInit();
+       charset_initialise();
+
        in_client = True;   /* Make sure that we tell lp_load we are */
 
        if (!lp_load(servicesf,True,False,False)) {
@@ -2133,8 +2245,6 @@ static int do_message_op(void)
        
        codepage_initialise(lp_client_code_page());
 
-       interpret_coding_system(term_code);
-
 #ifdef WITH_SSL
        sslutil_init(0);
 #endif
@@ -2209,14 +2319,11 @@ static int do_message_op(void)
        }
 
        while ((opt = 
-               getopt(argc, argv,"s:B:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:")) != EOF) {
+               getopt(argc, argv,"s:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:b:")) != EOF) {
                switch (opt) {
                case 's':
                        pstrcpy(servicesf, optarg);
                        break;
-               case 'B':
-                       iface_set_default(NULL,optarg,NULL);
-                       break;
                case 'O':
                        pstrcpy(user_socket_options,optarg);
                        break;  
@@ -2270,7 +2377,6 @@ static int do_message_op(void)
                case 'U':
                        {
                                char *lp;
-                               explicit_user = True;
                                pstrcpy(username,optarg);
                                if ((lp=strchr(username,'%'))) {
                                        *lp = 0;
@@ -2281,9 +2387,10 @@ static int do_message_op(void)
                        }
                        break;
                case 'L':
-                       pstrcpy(query_host,optarg);
-                       if(!explicit_user)
-                               *username = '\0';
+                       p = optarg;
+                       while(*p == '\\' || *p == '/')
+                               p++;
+                       pstrcpy(query_host,p);
                        break;
                case 't':
                        pstrcpy(term_code, optarg);
@@ -2307,40 +2414,32 @@ static int do_message_op(void)
                        cmdstr = optarg;
                        got_pass = True;
                        break;
+               case 'b':
+                       io_bufsize = MAX(1, atoi(optarg));
+                       break;
                default:
                        usage(pname);
                        exit(1);
                }
        }
 
-       get_myname((*global_myname)?NULL:global_myname,NULL);  
+       get_myname((*global_myname)?NULL:global_myname);  
 
        if(*new_name_resolve_order)
                lp_set_name_resolve_order(new_name_resolve_order);
 
+       if (*term_code)
+               interpret_coding_system(term_code);
+
        if (!tar_type && !*query_host && !*service && !message) {
                usage(pname);
                exit(1);
        }
 
-#ifdef HAVE_LIBREADLINE
-
-       /* Initialise GNU Readline */
-       
-       rl_readline_name = "smbclient";
-       rl_attempted_completion_function = completion_fn;
-       rl_completion_entry_function = (Function *)complete_cmd_null;
-       
-       /* Initialise history list */
-       
-       using_history();
-
-#endif /* HAVE_LIBREADLINE */
-
        DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
 
        if (tar_type) {
-               return do_tar_op(port, base_directory);
+               return do_tar_op(base_directory);
        }
 
        if ((p=strchr(query_host,'#'))) {
@@ -2350,7 +2449,7 @@ static int do_message_op(void)
        }
   
        if (*query_host) {
-               return do_host_query(query_host, port);
+               return do_host_query(query_host);
        }
 
        if (message) {
@@ -2358,10 +2457,8 @@ static int do_message_op(void)
        }
 
        if (!process(base_directory)) {
-               close_sockets();
                return(1);
        }
-       close_sockets();
 
        return(0);
 }
index 0b7cf6f54d535dcd1ef89e855332b709b4217ec7..76b6ff94d58864d1e8a680c02fad8cc065e14373 100644 (file)
@@ -193,7 +193,7 @@ static void writetarheader(int f,  char *aname, int size, time_t mtime,
          memset(b, 0, l+TBLOCK+100);
          fixtarname(b, aname, l);
          i = strlen(b)+1;
-         DEBUG(5, ("File name in tar file: %s, size=%i, \n", b, strlen(b)));
+         DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
          dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
          free(b);
   }
@@ -659,7 +659,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
     {
       DEBUG(3,("skipping file %s of size %d bytes\n",
               finfo.name,
-              finfo.size));
+              (int)finfo.size));
       shallitime=0;
       ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
       ntarf++;
@@ -712,7 +712,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
     {
       DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
               finfo.name,
-              finfo.size,
+              (int)finfo.size,
               lname));
       
       /* write a tar header, don't bother with mode - just set to 100644 */
@@ -747,7 +747,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
 
       /* pad tar file with zero's if we couldn't get entire file */
       if (nread < finfo.size) {
-             DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
+             DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", (int)finfo.size, (int)nread));
              if (padit(data, sizeof(data), finfo.size - nread))
                      DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
       }
@@ -781,7 +781,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
       if (tar_noisy)
        {
          DEBUG(0, ("%10d (%7.1f kb/s) %s\n",
-              finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+              (int)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
                finfo.name));
        }
 
@@ -806,7 +806,7 @@ static void do_tar(file_info *finfo)
   if (!tar_excl && clipn) {
     pstring exclaim;
 
-    DEBUG(5, ("Excl: strlen(cur_dir) = %i\n", strlen(cur_dir)));
+    DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
 
     safe_strcpy(exclaim, cur_dir, sizeof(pstring));
     *(exclaim+strlen(exclaim)-1)='\0';
@@ -834,7 +834,7 @@ static void do_tar(file_info *finfo)
 
       safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
 
-      DEBUG(5, ("Sizeof(cur_dir)=%i, strlen(cur_dir)=%i, strlen(finfo->name)=%i\nname=%s,cur_dir=%s\n", sizeof(cur_dir), strlen(cur_dir), strlen(finfo->name), finfo->name, cur_dir));
+      DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
 
       safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
       safe_strcat(cur_dir,"\\", sizeof(cur_dir));
@@ -923,14 +923,27 @@ static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
 
     DEBUG(5, ("Reading more data into ltarbuf ...\n"));
 
-    total = 0;
+    /*
+     * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
+     * Fixes bug where read can return short if coming from
+     * a pipe.
+     */
 
-    for (bufread = read(tarhandle, ltarbuf, bufsiz); total < bufsiz; total += bufread) {
+    bufread = read(tarhandle, ltarbuf, bufsiz);
+    total = bufread;
 
-      if (bufread <= 0) { /* An error, return false */
-       return (total > 0 ? -2 : bufread);
+    while (total < bufsiz) {
+      if (bufread < 0) { /* An error, return false */
+        return (total > 0 ? -2 : bufread);
       }
-
+      if (bufread == 0) {
+        if (total <= 0) {
+            return -2;
+        }
+        break;
+      }
+      bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
+      total += bufread;
     }
 
     DEBUG(5, ("Total bytes read ... %i\n", total));
@@ -968,24 +981,27 @@ static int skip_file(int skipsize)
   return(True);
 }
 
-/* We get a file from the tar file and store it */
+/*************************************************************
+ Get a file from the tar file and store it.
+ When this is called, tarbuf already contains the first
+ file block. This is a bit broken & needs fixing.
+**************************************************************/
+
 static int get_file(file_info2 finfo)
 {
-  int fsize = finfo.size;
   int fnum = -1, pos = 0, dsize = 0, rsize = 0, bpos = 0;
 
-  DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, fsize));
+  DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, (int)finfo.size));
 
   if (ensurepath(finfo.name) && 
-      (fnum=cli_open(cli, finfo.name, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE)) == -1)
-    {
+      (fnum=cli_open(cli, finfo.name, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
       DEBUG(0, ("abandoning restore\n"));
       return(False);
-    }
+  }
 
   /* read the blocks from the tar file and write to the remote file */
 
-  rsize = fsize;  /* This is how much to write */
+  rsize = finfo.size;  /* This is how much to write */
 
   while (rsize > 0) {
 
@@ -1023,17 +1039,23 @@ static int get_file(file_info2 finfo)
 
     }
 
-    while (dsize >= TBLOCK) {
+    /*
+     * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
+     * If the file being extracted is an exact multiple of
+     * TBLOCK bytes then we don't want to extract the next
+     * block from the tarfile here, as it will be done in
+     * the caller of get_file().
+     */
 
-      if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+    while (((rsize != 0) && (dsize >= TBLOCK)) ||
+         ((rsize == 0) && (dsize > TBLOCK))) {
 
+      if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
        DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
        return False;
-
       }
 
       dsize -= TBLOCK;
-
     }
 
     bpos = dsize;
@@ -1060,7 +1082,7 @@ static int get_file(file_info2 finfo)
 
   ntarf++;
 
-  DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, finfo.size));
+  DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, (int)finfo.size));
   
   return(True);
 }
@@ -1071,7 +1093,7 @@ static int get_file(file_info2 finfo)
 static int get_dir(file_info2 finfo)
 {
 
-  DEBUG(5, ("Creating directory: %s\n", finfo.name));
+  DEBUG(0, ("restore directory %s\n", finfo.name));
 
   if (!ensurepath(finfo.name)) {
 
@@ -1079,6 +1101,8 @@ static int get_dir(file_info2 finfo)
     return(False);
 
   }
+
+  ntarf++;
   return(True);
 
 }
@@ -1094,12 +1118,12 @@ static char * get_longfilename(file_info2 finfo)
   BOOL first = True;
 
   DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
-  DEBUG(5, ("Len = %i\n", finfo.size));
+  DEBUG(5, ("Len = %d\n", (int)finfo.size));
 
   if (longname == NULL) {
 
     DEBUG(0, ("could not allocate buffer of size %d for longname\n", 
-             finfo.size + strlen(cur_dir) + 2));
+             (int)(finfo.size + strlen(cur_dir) + 2)));
     return(NULL);
   }
 
@@ -1181,7 +1205,7 @@ static void do_tarput(void)
       return;
 
     case 0: /* chksum is zero - looks like an EOF */
-      DEBUG(0, ("total of %d tar files restored to share\n", ntarf));
+      DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
       return;        /* Hmmm, bad here ... */
 
     default: 
@@ -1229,10 +1253,14 @@ static void do_tarput(void)
 
     case '0':  /* Should use symbolic names--FIXME */
 
-      /* Skip to the next block first, so we can get the file, FIXME, should
-         be in get_file ... */
+      /* 
+       * Skip to the next block first, so we can get the file, FIXME, should
+       * be in get_file ...
+       * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
+       * Fixes bug where file size in tarfile is zero.
+       */
 
-      if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+      if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
        DEBUG(0, ("Short file, bailing out...\n"));
        return;
       }
@@ -1486,7 +1514,7 @@ int process_tar(void)
     close(tarhandle);
     free(tarbuf);
     
-    DEBUG(0, ("tar: dumped %d tar files\n", ntarf));
+    DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
     DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
     break;
   }
index fa3cacb8640bfb3f30facb0f11b83906d2efa485..b7e30c3967f5ef7eaa366b5f329fa441667df0b1 100644 (file)
@@ -1,7 +1,8 @@
 /*
- *  smbmount.c
+ *  smbmnt.c
  *
  *  Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
+ *  extensively modified by Tridge
  *
  */
 
 #include <linux/fs.h>
 #endif
 
-static char *progname;
-
-
-static void
-usage(void)
-{
-        printf("usage: %s mount-point [options]\n", progname);
-        printf("Try `%s -h' for more information\n", progname);
-}
+static uid_t mount_uid;
+static gid_t mount_gid;
+static int mount_ro;
+static unsigned mount_fmask;
+static unsigned mount_dmask;
+static int user_mount;
 
 static void
 help(void)
 {
         printf("\n");
-        printf("usage: %s mount-point [options]\n", progname);
-        printf("-u uid         uid the mounted files get\n"
-               "-g gid         gid the mounted files get\n"
-               "-f mode        permission the files get (octal notation)\n"
-               "-d mode        permission the dirs get (octal notation)\n"
-              "-P pid         connection handler's pid\n\n"
-              "-s share       share name on server\n\n"
+        printf("usage: smbmnt mount-point [options]\n");
+        printf("-s share       share name on server\n"
+               "-r             mount read-only\n"
+               "-u uid         mount as uid\n"
+               "-g gid         mount as gid\n"
+               "-f mask        permission mask for files\n"
+               "-d mask        permission mask for directories\n"
                "-h             print this help text\n");
 }
 
@@ -51,55 +49,32 @@ static int
 parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
 {
         int opt;
-        struct passwd *pwd;
-        struct group  *grp;
 
-        while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
+        while ((opt = getopt (argc, argv, "s:u:g:rf:d:")) != EOF)
        {
                 switch (opt)
                {
+                case 's':
+                        *share = optarg;
+                        break;
                 case 'u':
-                        if (isdigit(optarg[0]))
-                       {
-                                data->uid = atoi(optarg);
-                        }
-                       else
-                       {
-                                pwd = getpwnam(optarg);
-                                if (pwd == NULL)
-                               {
-                                        fprintf(stderr, "Unknown user: %s\n",
-                                                optarg);
-                                        return 1;
-                                }
-                                data->uid = pwd->pw_uid;
-                        }
+                       if (!user_mount) {
+                               mount_uid = strtol(optarg, NULL, 0);
+                       }
                         break;
                 case 'g':
-                        if (isdigit(optarg[0]))
-                       {
-                                data->gid = atoi(optarg);
-                        }
-                       else
-                       {
-                                grp = getgrnam(optarg);
-                                if (grp == NULL)
-                               {
-                                        fprintf(stderr, "Unknown group: %s\n",
-                                                optarg);
-                                        return 1;
-                                }
-                                data->gid = grp->gr_gid;
-                        }
+                       if (!user_mount) {
+                               mount_gid = strtol(optarg, NULL, 0);
+                       }
+                        break;
+                case 'r':
+                        mount_ro = 1;
                         break;
                 case 'f':
-                        data->file_mode = strtol(optarg, NULL, 8);
+                        mount_fmask = strtol(optarg, NULL, 8);
                         break;
                 case 'd':
-                        data->dir_mode = strtol(optarg, NULL, 8);
-                        break;
-                case 's':
-                        *share = optarg;
+                        mount_dmask = strtol(optarg, NULL, 8);
                         break;
                 default:
                         return -1;
@@ -114,32 +89,39 @@ fullpath(const char *p)
 {
         char path[MAXPATHLEN];
 
-       if (strlen(p) > MAXPATHLEN-1)
-       {
+       if (strlen(p) > MAXPATHLEN-1) {
                return NULL;
        }
 
-        if (realpath(p, path) == NULL)
-       {
-                return strdup(p);
+        if (realpath(p, path) == NULL) {
+               fprintf(stderr,"Failed to find real path for mount point\n");
+               exit(1);
        }
        return strdup(path);
 }
 
-/* Check whether user is allowed to mount on the specified mount point */
-static int
-mount_ok(SMB_STRUCT_STAT *st)
+/* Check whether user is allowed to mount on the specified mount point. If it's
+   OK then we change into that directory - this prevents race conditions */
+static int mount_ok(char *mount_point)
 {
-        if (!S_ISDIR(st->st_mode))
-        {
+       SMB_STRUCT_STAT st;
+
+       if (chdir(mount_point) != 0) {
+               return -1;
+       }
+
+        if (sys_stat(".", &st) != 0) {
+               return -1;
+        }
+
+        if (!S_ISDIR(st.st_mode)) {
                 errno = ENOTDIR;
                 return -1;
         }
-       
-        if (   (getuid() != 0)
-            && (   (getuid() != st->st_uid)
-                || ((st->st_mode & S_IRWXU) != S_IRWXU)))
-        {
+
+        if ((getuid() != 0) && 
+           ((getuid() != st.st_uid) || 
+            ((st.st_mode & S_IRWXU) != S_IRWXU))) {
                 errno = EPERM;
                 return -1;
         }
@@ -147,53 +129,48 @@ mount_ok(SMB_STRUCT_STAT *st)
         return 0;
 }
 
-int 
-main(int argc, char *argv[])
+ int main(int argc, char *argv[])
 {
        char *mount_point, *share_name = NULL;
        FILE *mtab;
-       int fd, um;
+       int fd;
        unsigned int flags;
        struct smb_mount_data data;
-       SMB_STRUCT_STAT st;
        struct mntent ment;
 
-        progname = argv[0];
-
        memset(&data, 0, sizeof(struct smb_mount_data));
 
-       if (   (argc == 2)
-              && (argv[1][0] == '-')
-              && (argv[1][1] == 'h')
-              && (argv[1][2] == '\0'))
-       {
+       if (argc < 2) {
+               help();
+               exit(1);
+       }
+
+       if (argv[1][0] == '-') {
                help();
-               return 0;
+               exit(1);
+       }
+
+       if (getuid() != 0) {
+               user_mount = 1;
        }
 
         if (geteuid() != 0) {
-                fprintf(stderr, "%s must be installed suid root\n", progname);
+                fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid());
                 exit(1);
         }
 
-       if (argc < 2)
-       {
-               usage();
-               return 1;
-       }
+       mount_uid = getuid();
+       mount_gid = getgid();
+       mount_fmask = umask(0);
+        umask(mount_fmask);
+       mount_fmask = ~mount_fmask;
 
-        mount_point = argv[1];
+        mount_point = fullpath(argv[1]);
 
         argv += 1;
         argc -= 1;
 
-        if (sys_stat(mount_point, &st) == -1) {
-                fprintf(stderr, "could not find mount point %s: %s\n",
-                        mount_point, strerror(errno));
-                exit(1);
-        }
-
-        if (mount_ok(&st) != 0) {
+        if (mount_ok(mount_point) != 0) {
                 fprintf(stderr, "cannot mount on %s: %s\n",
                         mount_point, strerror(errno));
                 exit(1);
@@ -204,19 +181,17 @@ main(int argc, char *argv[])
         /* getuid() gives us the real uid, who may umount the fs */
         data.mounted_uid = getuid();
 
-        data.uid = getuid();
-        data.gid = getgid();
-        um = umask(0);
-        umask(um);
-        data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
-        data.dir_mode  = 0;
-
         if (parse_args(argc, argv, &data, &share_name) != 0) {
-                usage();
+                help();
                 return -1;
         }
 
-        if (data.dir_mode == 0) {
+        data.uid = mount_uid;
+        data.gid = mount_gid;
+        data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask;
+        data.dir_mode  = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask;
+
+        if (mount_dmask == 0) {
                 data.dir_mode = data.file_mode;
                 if ((data.dir_mode & S_IRUSR) != 0)
                         data.dir_mode |= S_IXUSR;
@@ -228,15 +203,23 @@ main(int argc, char *argv[])
 
        flags = MS_MGC_VAL;
 
-       if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
+       if (mount_ro) flags |= MS_RDONLY;
+
+       if (mount(share_name, ".", "smbfs", flags, (char *)&data) < 0)
        {
-               perror("mount error");
-               printf("Please refer to the smbmnt(8) manual page\n");
+               switch (errno) {
+               case ENODEV:
+                       fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n");
+                       break;
+               default:
+                       perror("mount error");
+               }
+               fprintf(stderr, "Please refer to the smbmnt(8) manual page\n");
                return -1;
        }
 
         ment.mnt_fsname = share_name ? share_name : "none";
-        ment.mnt_dir = fullpath(mount_point);
+        ment.mnt_dir = mount_point;
         ment.mnt_type = "smbfs";
         ment.mnt_opts = "";
         ment.mnt_freq = 0;
index 3fad6674fb874fd0850d76e2e09551206c228483..e25efcaf5668f4fe2f2702f66e16c8a490ff52c5 100644 (file)
@@ -1,8 +1,8 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 1.9.
-   SMB client
-   Copyright (C) Andrew Tridgell 1994-1998
+   Version 2.0.
+   SMBFS mount program
+   Copyright (C) Andrew Tridgell 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
 
 #define NO_SYSLOG
 
-#include <linux/version.h>
-#define LVERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
-#if LINUX_VERSION_CODE < LVERSION(2,1,70)
-#error this code will only compile on versions of linux after 2.1.70
-#endif
-
 #include "includes.h"
 
 #include <mntent.h>
-
 #include <asm/types.h>
 #include <linux/smb_fs.h>
-static struct smb_conn_opt conn_options;
 
-#ifndef REGISTER
-#define REGISTER 0
-#endif
-
-/* Uncomment this to allow debug the smbmount daemon */
+/* Uncomment this to allow debug the mount.smb daemon */
 /* WARNING!  This option is incompatible with autofs/automount because
        it does not close the stdout pipe back to the automount
        process, which automount depends on.  This will cause automount
        to hang!  Use with caution! */
-/* #define SMBFS_DEBUG 1       */
-
-pstring cur_dir = "\\";
-pstring cd_path = "";
-extern pstring service;
-extern pstring desthost;
-extern pstring global_myname;
-extern pstring myhostname;
-extern pstring password;
-extern pstring smb_login_passwd;
-extern pstring username;
-extern pstring workgroup;
-char *cmdstr="";
-extern BOOL got_pass;
-extern BOOL connect_as_printer;
-extern BOOL connect_as_ipc;
-extern struct in_addr ipzero;
-
-extern BOOL doencrypt;
-
-extern pstring user_socket_options;
-
-/* 30 second timeout on most commands */
-#define CLIENT_TIMEOUT (30*1000)
-#define SHORT_TIMEOUT (5*1000)
-
-/* value for unused fid field in trans2 secondary request */
-#define FID_UNUSED (0xFFFF)
-
-extern int name_type;
+/* #define SMBFS_DEBUG 1 */
 
-extern int max_protocol;
-int port = SMB_PORT;
-
-time_t newer_than = 0;
-int archive_level = 0;
-
-extern pstring debugf;
+extern struct in_addr ipzero;
 extern int DEBUGLEVEL;
 
-BOOL translation = False;
-
-extern uint16 cnum;
-extern uint16 mid;
-extern uint16 pid;
-extern uint16 vuid;
-
-extern BOOL have_ip;
-extern int max_xmit;
-
-/* clitar bits insert */
-extern int blocksize;
-extern BOOL tar_inc;
-extern BOOL tar_reset;
-/* clitar bits end */
-
-mode_t myumask = 0755;
-
 extern pstring scope;
+extern BOOL in_client;
+extern pstring user_socket_options;
 
-BOOL prompt = True;
-
-int printmode = 1;
-
-BOOL recurse = False;
-BOOL lowercase = False;
-
-struct in_addr dest_ip;
-
-#define SEPARATORS " \t\n\r"
-
-BOOL abort_mget = True;
-
-extern int Protocol;
-
-extern BOOL readbraw_supported ;
-extern BOOL writebraw_supported;
-
-pstring fileselection = "";
-
-extern file_info def_finfo;
-
-/* timing globals */
-int get_total_size = 0;
-int get_total_time_ms = 0;
-int put_total_size = 0;
-int put_total_time_ms = 0;
-
-/* totals globals */
-int dir_total = 0;
-
-extern int Client;
-
-#define USENMB
-
-#define CNV_LANG(s) dos_to_unix(s,False)
-#define CNV_INPUT(s) unix_to_dos(s,True)
-
-/****************************************************************************
-check for existance of a dir
-****************************************************************************/
-static BOOL chkpath(char *path,BOOL report)
-{
-  fstring path2;
-  pstring inbuf,outbuf;
-  char *p;
-
-  fstrcpy(path2,path);
-  trim_string(path2,NULL,"\\");
-  if (!*path2) *path2 = '\\';
-
-  memset(outbuf,'\0',smb_size);
-  set_message(outbuf,0,4 + strlen(path2),True);
-  SCVAL(outbuf,smb_com,SMBchkpth);
-  SSVAL(outbuf,smb_tid,cnum);
-  cli_setup_pkt(outbuf);
-
-  p = smb_buf(outbuf);
-  *p++ = 4;
-  fstrcpy(p,path2);
-
-#if 0
-  {
-         /* this little bit of code can be used to extract NT error codes.
-            Just feed a bunch of "cd foo" commands to smbclient then watch
-            in netmon (tridge) */
-         static int code=0;
-         SIVAL(outbuf, smb_rcls, code | 0xC0000000);
-         SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | (1<<14));
-         code++;
-  }
-#endif
-
-  send_smb(Client,outbuf);
-  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
-  if (report && CVAL(inbuf,smb_rcls) != 0)
-    DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
-
-  return(CVAL(inbuf,smb_rcls) == 0);
-}
-
-static void
-exit_parent( int sig )
+static pstring my_netbios_name;
+static pstring password;
+static pstring username;
+static pstring workgroup;
+static pstring mpoint;
+static pstring service;
+
+static struct in_addr dest_ip;
+static BOOL have_ip;
+static int smb_port = 139;
+static BOOL got_pass;
+static uid_t mount_uid;
+static gid_t mount_gid;
+static int mount_ro;
+static unsigned mount_fmask;
+static unsigned mount_dmask;
+
+static void usage(void);
+
+static void exit_parent(int sig)
 {
        /* parent simply exits when child says go... */
        exit(0);
 }
 
-static void
-daemonize(void)
+static void daemonize(void)
 {
        int j, status;
        pid_t child_pid;
 
        signal( SIGTERM, exit_parent );
 
-       if ((child_pid = fork()) < 0)
-       {
-               DEBUG(0, ("could not fork\n"));
+       if ((child_pid = fork()) < 0) {
+               fprintf(stderr,"could not fork\n");
        }
-       if (child_pid > 0)
-       {
+
+       if (child_pid > 0) {
                while( 1 ) {
                        j = waitpid( child_pid, &status, 0 );
                        if( j < 0 ) {
@@ -221,84 +91,127 @@ daemonize(void)
                /* If we get here - the child exited with some error status */
                exit(status);
        }
-       /* Programmers Note:
-               Danger Will Robinson!  Danger!
 
-               There use to be a call to setsid() here.  This does no
-               harm to normal mount operations, but it broke automounting.
-               The setsid call has been moved to just before the child
-               sends the SIGTERM to the parent.  All of our deadly embrace
-               conditions with autofs will have been cleared by then...
-               -mhw-
-       */
        signal( SIGTERM, SIG_DFL );
        chdir("/");
 }
 
-static void
-close_our_files(void)
+static void close_our_files(int client_fd)
 {
        int i;
-       for (i = 0; i < NR_OPEN; i++) {
-               if (i == Client) {
-                       continue;
-               }
+       for (i = 0; i < 256; i++) {
+               if (i == client_fd) continue;
                close(i);
        }
 }
 
-static void
-usr1_handler(int x)
+static void usr1_handler(int x)
 {
        return;
 }
 
-/*
- * Send a login and store the connection options. This is a separate
- * function to keep clientutil.c independent of linux kernel changes.
- */
-static BOOL mount_send_login(char *inbuf, char *outbuf)
+
+/***************************************************** 
+return a connection to a server
+*******************************************************/
+static struct cli_state *do_connection(char *service)
 {
-  struct connection_options opt;
-  int res = cli_send_login(inbuf, outbuf, True, True, &opt);
-
-  if (!res)
-    return res;
-
-  if( !got_pass ) {
-       /* Ok...  If we got this thing connected and got_pass is false,
-          that means that the client util prompted for a password and
-          got a good one...  We need to cache this in password and set
-          got_pass for future retries.  We don't want to prompt for the
-          $#@$#$ password everytime the network blinks!
-       */
+       struct cli_state *c;
+       struct nmb_name called, calling;
+       char *server_n;
+       struct in_addr ip;
+       extern struct in_addr ipzero;
+       pstring server;
+       char *share;
+
+       if (service[0] != '\\' || service[1] != '\\') {
+               usage();
+               exit(1);
+       }
+
+       pstrcpy(server, service+2);
+       share = strchr(server,'\\');
+       if (!share) {
+               usage();
+               exit(1);
+       }
+       *share = 0;
+       share++;
+
+       server_n = server;
+       
+       ip = ipzero;
+
+       make_nmb_name(&calling, my_netbios_name, 0x0, "");
+       make_nmb_name(&called , server, 0x20, "");
+
+ again:
+       ip = ipzero;
+       if (have_ip) ip = dest_ip;
+
+       /* have to open a new connection */
+       if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) == 0) ||
+           !cli_connect(c, server_n, &ip)) {
+               fprintf(stderr,"Connection to %s failed\n", server_n);
+               return NULL;
+       }
+
+       if (!cli_session_request(c, &calling, &called)) {
+               fprintf(stderr, "session request to %s failed\n", called.name);
+               cli_shutdown(c);
+               if (strcmp(called.name, "*SMBSERVER")) {
+                       make_nmb_name(&called , "*SMBSERVER", 0x20, "");
+                       goto again;
+               }
+               return NULL;
+       }
+
+       DEBUG(4,(" session request ok\n"));
+
+       if (!cli_negprot(c)) {
+               fprintf(stderr, "protocol negotiation failed\n");
+               cli_shutdown(c);
+               return NULL;
+       }
+
+       if (!got_pass) {
+               char *pass = getpass("Password: ");
+               if (pass) {
+                       pstrcpy(password, pass);
+               }
+       }
+
+       if (!cli_session_setup(c, username, 
+                              password, strlen(password),
+                              password, strlen(password),
+                              workgroup)) {
+               fprintf(stderr, "session setup failed: %s\n", cli_errstr(c));
+               return NULL;
+       }
+
+       DEBUG(4,(" session setup ok\n"));
+
+       if (!cli_send_tconX(c, share, "?????",
+                           password, strlen(password)+1)) {
+               fprintf(stderr,"tree connect failed: %s\n", cli_errstr(c));
+               cli_shutdown(c);
+               return NULL;
+       }
+
+       DEBUG(4,(" tconx ok\n"));
+
+       got_pass = True;
 
-      pstrcpy(password,smb_login_passwd);
-      got_pass = True;
-  }
-  conn_options.protocol = opt.protocol;
-  conn_options.case_handling = CASE_LOWER;
-  conn_options.max_xmit = opt.max_xmit;
-  conn_options.server_uid = opt.server_vuid;
-  conn_options.tid = opt.tid;
-  conn_options.secmode = opt.sec_mode;
-  conn_options.maxmux = opt.max_mux;
-  conn_options.maxvcs = opt.max_vcs;
-  conn_options.rawmode = opt.rawmode;
-  conn_options.sesskey = opt.sesskey;
-  conn_options.maxraw = opt.maxraw;
-  conn_options.capabilities = opt.capabilities;
-  conn_options.serverzone = opt.serverzone;
-
-  return True;
+       return c;
 }
 
+
 /****************************************************************************
 unmount smbfs  (this is a bailout routine to clean up if a reconnect fails)
        Code blatently stolen from smbumount.c
                -mhw-
 ****************************************************************************/
-static void smb_umount( char *mount_point )
+static void smb_umount(char *mount_point)
 {
        int fd;
         struct mntent *mnt;
@@ -314,29 +227,29 @@ static void smb_umount( char *mount_point )
                the lights to exit anyways...
        */
         if (umount(mount_point) != 0) {
-                DEBUG(0, ("Could not umount %s: %s\n",
-                        mount_point, strerror(errno)));
+                fprintf(stderr, "Could not umount %s: %s\n",
+                        mount_point, strerror(errno));
                 return;
         }
 
-        if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
-        {
-                DEBUG(0, ("Can't get "MOUNTED"~ lock file"));
+        if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
+                fprintf(stderr, "Can't get "MOUNTED"~ lock file");
                 return;
         }
+
         close(fd);
        
         if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
-                DEBUG(0, ("Can't open " MOUNTED ": %s\n",
-                        strerror(errno)));
+                fprintf(stderr, "Can't open " MOUNTED ": %s\n",
+                        strerror(errno));
                 return;
         }
 
 #define MOUNTED_TMP MOUNTED".tmp"
 
         if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
-                DEBUG(0, ("Can't open " MOUNTED_TMP ": %s\n",
-                        strerror(errno)));
+                fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
+                        strerror(errno));
                 endmntent(mtab);
                 return;
         }
@@ -350,26 +263,23 @@ static void smb_umount( char *mount_point )
         endmntent(mtab);
 
         if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
-                DEBUG(0, ("Error changing mode of %s: %s\n",
-                        MOUNTED_TMP, strerror(errno)));
+                fprintf(stderr, "Error changing mode of %s: %s\n",
+                        MOUNTED_TMP, strerror(errno));
                 return;
         }
 
         endmntent(new_mtab);
 
         if (rename(MOUNTED_TMP, MOUNTED) < 0) {
-                DEBUG(0, ("Cannot rename %s to %s: %s\n",
-                        MOUNTED, MOUNTED_TMP, strerror(errno)));
+                fprintf(stderr, "Cannot rename %s to %s: %s\n",
+                        MOUNTED, MOUNTED_TMP, strerror(errno));
                 return;
         }
 
-        if (unlink(MOUNTED"~") == -1)
-        {
-                DEBUG(0, ("Can't remove "MOUNTED"~"));
+        if (unlink(MOUNTED"~") == -1) {
+                fprintf(stderr, "Can't remove "MOUNTED"~");
                 return;
         }
-
-       return;
 }
 
 
@@ -379,136 +289,174 @@ static void smb_umount( char *mount_point )
  * not exit after open_sockets() or send_login() errors,
  * as the smbfs mount would then have no way to recover.
  */
-static void
-send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
+static void send_fs_socket(char *service, char *mount_point, struct cli_state *c)
 {
        int fd, closed = 0, res = 1;
-
        pid_t parentpid = getppid();
+       struct smb_conn_opt conn_options;
+
+       memset(&conn_options, 0, sizeof(conn_options));
 
-       while (1)
-       {
-               if ((fd = open(mount_point, O_RDONLY)) < 0)
-               {
-                       DEBUG(0, ("smbmount: can't open %s\n", mount_point));
+       while (1) {
+               if ((fd = open(mount_point, O_RDONLY)) < 0) {
+                       fprintf(stderr, "mount.smbfs: can't open %s\n", mount_point);
                        break;
                }               
 
-               /*
-                * Call the ioctl even if we couldn't get a socket ...
-                * there's no point in making smbfs wait for a timeout.
-                */
-               conn_options.fd = -1;
-               if (res)
-                       conn_options.fd = Client;
+               conn_options.fd = c->fd;
+               conn_options.protocol = c->protocol;
+               conn_options.case_handling = SMB_CASE_DEFAULT;
+               conn_options.max_xmit = c->max_xmit;
+               conn_options.server_uid = c->vuid;
+               conn_options.tid = c->cnum;
+               conn_options.secmode = c->sec_mode;
+               conn_options.rawmode = 0;
+               conn_options.sesskey = c->sesskey;
+               conn_options.maxraw = 0;
+               conn_options.capabilities = c->capabilities;
+               conn_options.serverzone = c->serverzone/60;
+
                res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
-               if (res != 0)
-               {
-                       DEBUG(0, ("smbmount: ioctl failed, res=%d\n", res));
+               if (res != 0) {
+                       fprintf(stderr, "mount.smbfs: ioctl failed, res=%d\n", res);
+                       break;
                }
 
-               if( parentpid ) {
+               if (parentpid) {
                        /* Ok...  We are going to kill the parent.  Now
                                is the time to break the process group... */
                        setsid();
                        /* Send a signal to the parent to terminate */
-                       kill( parentpid, SIGTERM );
+                       kill(parentpid, SIGTERM);
                        parentpid = 0;
                }
 
-               close_sockets();
                close(fd);
-               /*
-                * Close all open files if we haven't done so yet.
-                */
+
 #ifndef SMBFS_DEBUG
-               if (!closed)
-               {
+               /* Close all open files if we haven't done so yet. */
+               if (!closed) {
+                       extern FILE *dbf;
                        closed = 1;
-                       close_our_files();
+                       dbf = NULL;
+                       close_our_files(c?c->fd:-1);
                }
 #endif
 
-               /*
-                * Wait for a signal from smbfs ...
-                */
+               /* Wait for a signal from smbfs ... */
                CatchSignal(SIGUSR1, &usr1_handler);
                pause();
-               DEBUG(0, ("smbmount: got signal, getting new socket\n"));
+#ifdef SMBFS_DEBUG
+               DEBUG(2,("mount.smbfs: got signal, getting new socket\n"));
+#endif
+               c = do_connection(service);
+       }
 
-               res = cli_open_sockets(port);
-               if (!res)
-               {
-                       DEBUG(0, ("smbmount: can't open sockets\n"));
-                       continue;
-               }
+       smb_umount(mount_point);
+       DEBUG(2,("mount.smbfs: exit\n"));
+       exit(1);
+}
 
-               res = mount_send_login(inbuf, outbuf);
-               if (!res)
-               {
-                       DEBUG(0, ("smbmount: login failed\n"));
-                       break;
-               }
+/*********************************************************
+a strdup with exit
+**********************************************************/
+static char *xstrdup(char *s)
+{
+       s = strdup(s);
+       if (!s) {
+               fprintf(stderr,"out of memory\n");
+               exit(1);
        }
-       smb_umount( mount_point );
-       DEBUG(0, ("smbmount: exit\n"));
-       exit(1);
+       return s;
 }
 
+
 /****************************************************************************
 mount smbfs
 ****************************************************************************/
-static void cmd_mount(char *inbuf,char *outbuf)
+static void init_mount(void)
 {
-       pstring mpoint;
-       pstring share_name;
-       pstring mount_command;
-       fstring buf;
-       int retval;
        char mount_point[MAXPATHLEN+1];
-
-       if (!next_token(NULL, mpoint, NULL, sizeof(mpoint)))
-       {
-               DEBUG(0,("You must supply a mount point\n"));
+       pstring tmp;
+       pstring svc2;
+       struct cli_state *c;
+       char *args[20];
+       int i, status;
+
+       if (realpath(mpoint, mount_point) == NULL) {
+               fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
                return;
        }
 
-       memset(mount_point, 0, sizeof(mount_point));
 
-       if (realpath(mpoint, mount_point) == NULL)
-       {
-               DEBUG(0, ("Could not resolve mount point\n"));
-               return;
-       }
-
-       /*
-        * Build the service name to report on the Unix side,
-        * converting '\' to '/' and ' ' to '_'.
-        */
-       pstrcpy(share_name, service);  
-       string_replace(share_name, '\\', '/');
-       string_replace(share_name, ' ', '_');
-
-       slprintf(mount_command, sizeof(mount_command)-1,"smbmnt %s -s %s", mount_point, share_name);
-
-       while(next_token(NULL, buf, NULL, sizeof(buf)))
-       {
-               pstrcat(mount_command, " ");
-               pstrcat(mount_command, buf);
+       c = do_connection(service);
+       if (!c) {
+               fprintf(stderr,"SMB connection failed\n");
+               exit(1);
        }
 
-       DEBUG(3, ("mount command: %s\n", mount_command));
-
        /*
                Set up to return as a daemon child and wait in the parent
                until the child say it's ready...
        */
        daemonize();
 
-       if ((retval = system(mount_command)) != 0)
-       {
-               DEBUG(0,("mount failed\n"));
+       pstrcpy(svc2, service);
+       string_replace(svc2, '\\','/');
+       string_replace(svc2, ' ','_');
+
+       memset(args, 0, sizeof(args[0])*20);
+
+       i=0;
+       args[i++] = "smbmnt";
+
+       args[i++] = mount_point;
+       args[i++] = "-s";
+       args[i++] = svc2;
+
+       if (mount_ro) {
+               args[i++] = "-r";
+       }
+       if (mount_uid) {
+               slprintf(tmp, sizeof(tmp), "%d", mount_uid);
+               args[i++] = "-u";
+               args[i++] = xstrdup(tmp);
+       }
+       if (mount_gid) {
+               slprintf(tmp, sizeof(tmp), "%d", mount_gid);
+               args[i++] = "-g";
+               args[i++] = xstrdup(tmp);
+       }
+       if (mount_fmask) {
+               slprintf(tmp, sizeof(tmp), "0%o", mount_fmask);
+               args[i++] = "-f";
+               args[i++] = xstrdup(tmp);
+       }
+       if (mount_dmask) {
+               slprintf(tmp, sizeof(tmp), "0%o", mount_dmask);
+               args[i++] = "-d";
+               args[i++] = xstrdup(tmp);
+       }
+
+       if (fork() == 0) {
+               if (file_exist(BINDIR "/smbmnt", NULL)) {
+                       execv(BINDIR "/smbmnt", args);
+                       fprintf(stderr,"execv of %s failed. Error was %s.", BINDIR "/smbmnt", strerror(errno));
+               } else {
+                       execvp("smbmnt", args);
+                       fprintf(stderr,"execvp of smbmnt failed. Error was %s.", strerror(errno) );
+               }
+               exit(1);
+       }
+
+       if (waitpid(-1, &status, 0) == -1) {
+               fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
+               /* FIXME: do some proper error handling */
                exit(1);
+       }       
+
+       if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+               fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
        }
 
        /* Ok...  This is the rubicon for that mount point...  At any point
@@ -516,241 +464,157 @@ static void cmd_mount(char *inbuf,char *outbuf)
           for any reason, we will have to unmount the mount point.  There
           is no exit from the next call...
        */
-       send_fs_socket(mount_point, inbuf, outbuf);
+       send_fs_socket(service, mount_point, c);
 }
 
 
-/* This defines the commands supported by this client */
-struct
-{
-  char *name;
-  void (*fn)();
-  char *description;
-} commands[] = 
-{
-  {"mount", cmd_mount, "<mount-point options> mount an smbfs file system"},
-  {"",NULL,NULL}
-};
-
-
-/*******************************************************************
-  lookup a command string in the list of commands, including 
-  abbreviations
-  ******************************************************************/
-static int process_tok(fstring tok)
-{
-  int i = 0, matches = 0;
-  int cmd=0;
-  int tok_len = strlen(tok);
-  
-  while (commands[i].fn != NULL)
-    {
-      if (strequal(commands[i].name,tok))
-       {
-         matches = 1;
-         cmd = i;
-         break;
-       }
-      else if (strnequal(commands[i].name, tok, tok_len))
-       {
-         matches++;
-         cmd = i;
-       }
-      i++;
-    }
-  
-  if (matches == 0)
-    return(-1);
-  else if (matches == 1)
-    return(cmd);
-  else
-    return(-2);
-}
-
-/****************************************************************************
-help
-****************************************************************************/
-void cmd_help(char *dum_in, char *dum_out)
-{
-  int i=0,j;
-  fstring buf;
-
-  if (next_token(NULL,buf,NULL,sizeof(buf)))
-    {
-      if ((i = process_tok(buf)) >= 0)
-       DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));                   
-    }
-  else
-    while (commands[i].description)
-      {
-       for (j=0; commands[i].description && (j<5); j++) {
-         DEBUG(0,("%-15s",commands[i].name));
-         i++;
-       }
-       DEBUG(0,("\n"));
-      }
-}
-
 /****************************************************************************
-wait for keyboard activity, swallowing network packets
+usage on the program
 ****************************************************************************/
-static void wait_keyboard(char *buffer)
+static void usage(void)
 {
-  fd_set fds;
-  int selrtn;
-  struct timeval timeout;
-  
-  while (1) 
-    {
-      extern int Client;
-      FD_ZERO(&fds);
-      FD_SET(Client,&fds);
-      FD_SET(fileno(stdin),&fds);
-
-      timeout.tv_sec = 20;
-      timeout.tv_usec = 0;
-      selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL, &timeout);
-      
-      if (FD_ISSET(fileno(stdin),&fds))
-       return;
-
-      /* We deliberately use receive_smb instead of
-         client_receive_smb as we want to receive
-         session keepalives and then drop them here.
-       */
-      if (FD_ISSET(Client,&fds))
-       receive_smb(Client,buffer,0);
-      
-      chkpath("\\",False);
-    }  
+       printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
+
+       printf("Version %s\n\n",VERSION);
+
+       printf(
+"Options:
+      username=<arg>                  SMB username
+      password=<arg>                  SMB password
+      netbiosname=<arg>               source NetBIOS name
+      uid=<arg>                       mount uid or username
+      gid=<arg>                       mount gid or groupname
+      port=<arg>                      remote SMB port number
+      fmask=<arg>                     file umask
+      dmask=<arg>                     directory umask
+      debug=<arg>                     debug level
+      ip=<arg>                        destination host or IP address
+      workgroup=<arg>                 workgroup on destination
+      sockopt=<arg>                   TCP socket options
+      scope=<arg>                     NetBIOS scope
+      guest                           don't prompt for a password
+      ro                              mount read-only
+      rw                              mount read-write
+
+This command is designed to be run from within /bin/mount by giving
+the option '-t smbfs'. For example:
+  mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test
+");
 }
 
 
 /****************************************************************************
-  process commands from the client
-****************************************************************************/
-static BOOL process(char *base_directory)
+  Argument parsing for mount.smbfs interface
+  mount will call us like this:
+    mount.smbfs device mountpoint -o <options>
+  
+  <options> is never empty, containing at least rw or ro
+ ****************************************************************************/
+static void parse_mount_smb(int argc, char **argv)
 {
-  extern FILE *dbf;
-  pstring line;
-  char *cmd;
+       int opt;
+       char *opts;
+       char *opteq;
+       extern char *optarg;
+       int val;
+
+       if (argc < 2 || argv[1][0] == '-') {
+               usage();
+               exit(1);
+       }
+       
+       pstrcpy(service, argv[1]);
+       pstrcpy(mpoint, argv[2]);
 
-  char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-  char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+       /* Convert any '/' characters in the service name to
+          '\' characters */
+       string_replace(service, '/','\\');
+       argc -= 2;
+       argv += 2;
 
-  if ((InBuffer == NULL) || (OutBuffer == NULL)) 
-    return(False);
-  
-  memset(OutBuffer,'\0',smb_size);
-
-  if (!mount_send_login(InBuffer,OutBuffer))
-    return(False);
-
-  cmd = cmdstr;
-  if (cmd[0] != '\0') while (cmd[0] != '\0')
-    {
-      char *p;
-      fstring tok;
-      int i;
-
-      if ((p = strchr(cmd, ';')) == 0)
-       {
-         strncpy(line, cmd, 999);
-         line[1000] = '\0';
-         cmd += strlen(cmd);
-       }
-      else
-       {
-         if (p - cmd > 999) p = cmd + 999;
-         strncpy(line, cmd, p - cmd);
-         line[p - cmd] = '\0';
-         cmd = p + 1;
-       }
-
-      /* input language code to internal one */
-      CNV_INPUT (line);
-      
-      /* and get the first part of the command */
-      {
-       char *ptr = line;
-       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
-      }
-
-      if ((i = process_tok(tok)) >= 0)
-       commands[i].fn(InBuffer,OutBuffer);
-      else if (i == -2)
-       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
-      else
-       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
-    }
-  else while (!feof(stdin))
-    {
-      fstring tok;
-      int i;
-
-      memset(OutBuffer,'\0',smb_size);
-
-      /* display a prompt */
-      DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
-      dbgflush();
-
-      wait_keyboard(InBuffer);
-  
-      /* and get a response */
-      if (!fgets(line,1000,stdin))
-       break;
-
-      /* input language code to internal one */
-      CNV_INPUT (line);
-
-      /* special case - first char is ! */
-      if (*line == '!')
-       {
-         system(line + 1);
-         continue;
-       }
-      
-      /* and get the first part of the command */
-      {
-       char *ptr = line;
-       if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
-      }
-
-      if ((i = process_tok(tok)) >= 0)
-       commands[i].fn(InBuffer,OutBuffer);
-      else if (i == -2)
-       DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
-      else
-       DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
-    }
-  
-  cli_send_logout(InBuffer,OutBuffer);
-  return(True);
-}
+       opt = getopt(argc, argv, "o:");
+       if(opt != 'o') {
+               return;
+       }
 
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
-  DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
-          pname));
-
-  DEBUG(0,("\nVersion %s\n",VERSION));
-  DEBUG(0,("\t-p port               connect to the specified port\n"));
-  DEBUG(0,("\t-d debuglevel         set the debuglevel\n"));
-  DEBUG(0,("\t-l log basename.      Basename for log/debug files\n"));
-  DEBUG(0,("\t-n netbios name.      Use this name as my netbios name\n"));
-  DEBUG(0,("\t-N                    don't ask for a password\n"));
-  DEBUG(0,("\t-m max protocol       set the max protocol level\n"));
-  DEBUG(0,("\t-I dest IP            use this IP to connect to\n"));
-  DEBUG(0,("\t-E                    write messages to stderr instead of stdout\n"));
-  DEBUG(0,("\t-U username           set the network username\n"));
-  DEBUG(0,("\t-W workgroup          set the workgroup name\n"));
-  DEBUG(0,("\t-c command string     execute semicolon separated commands\n"));
-  DEBUG(0,("\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
-  DEBUG(0,("\t-D directory          start from directory\n"));
-  DEBUG(0,("\n"));
+       /*
+        * option parsing from nfsmount.c (util-linux-2.9u)
+        */
+        for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
+               DEBUG(3, ("opts: %s\n", opts));
+                if ((opteq = strchr(opts, '='))) {
+                        val = atoi(opteq + 1);
+                        *opteq = '\0';
+
+                        if (!strcmp(opts, "username") || 
+                           !strcmp(opts, "logon")) {
+                               char *lp;
+                               pstrcpy(username,opteq+1);
+                               if ((lp=strchr(username,'%'))) {
+                                       *lp = 0;
+                                       pstrcpy(password,lp+1);
+                                       got_pass = True;
+                                       memset(strchr(opteq+1,'%')+1,'X',strlen(password));
+                               }
+                               if ((lp=strchr(username,'/'))) {
+                                       *lp = 0;
+                                       pstrcpy(workgroup,lp+1);
+                               }
+                       } else if(!strcmp(opts, "passwd") ||
+                                 !strcmp(opts, "password")) {
+                               pstrcpy(password,opteq+1);
+                               got_pass = True;
+                               memset(opteq+1,'X',strlen(password));
+                       } else if(!strcmp(opts, "netbiosname")) {
+                               pstrcpy(my_netbios_name,opteq+1);
+                       } else if(!strcmp(opts, "uid")) {
+                               mount_uid = nametouid(opteq+1);
+                       } else if(!strcmp(opts, "gid")) {
+                               mount_gid = nametogid(opteq+1);
+                       } else if(!strcmp(opts, "port")) {
+                               smb_port = val;
+                       } else if(!strcmp(opts, "fmask")) {
+                               mount_fmask = strtol(opteq+1, NULL, 8);
+                       } else if(!strcmp(opts, "dmask")) {
+                               mount_dmask = strtol(opteq+1, NULL, 8);
+                       } else if(!strcmp(opts, "debug")) {
+                               DEBUGLEVEL = val;
+                       } else if(!strcmp(opts, "ip")) {
+                               dest_ip = *interpret_addr2(opteq+1);
+                               if (zero_ip(dest_ip)) {
+                                       fprintf(stderr,"Can't resolve address %s\n", opteq+1);
+                                       exit(1);
+                               }
+                               have_ip = True;
+                       } else if(!strcmp(opts, "workgroup")) {
+                               pstrcpy(workgroup,opteq+1);
+                       } else if(!strcmp(opts, "sockopt")) {
+                               pstrcpy(user_socket_options,opteq+1);
+                       } else if(!strcmp(opts, "scope")) {
+                               pstrcpy(scope,opteq+1);
+                       } else {
+                               usage();
+                               exit(1);
+                       }
+               } else {
+                       val = 1;
+                       if(!strcmp(opts, "nocaps")) {
+                               fprintf(stderr, "Unhandled option: %s\n", opteq+1);
+                               exit(1);
+                       } else if(!strcmp(opts, "guest")) {
+                               got_pass = True;
+                       } else if(!strcmp(opts, "rw")) {
+                               mount_ro = 0;
+                       } else if(!strcmp(opts, "ro")) {
+                               mount_ro = 1;
+                       }
+               }
+       }
+
+       if (!*service) {
+               usage();
+               exit(1);
+       }
 }
 
 /****************************************************************************
@@ -758,229 +622,59 @@ static void usage(char *pname)
 ****************************************************************************/
  int main(int argc,char *argv[])
 {
-  fstring base_directory;
-  char *pname = argv[0];
-  int opt;
-  extern FILE *dbf;
-  extern char *optarg;
-  extern int optind;
-  pstring query_host;
-  BOOL nt_domain_logon = False;
-  static pstring servicesf = CONFIGFILE;
-  pstring term_code;
-  char *p;
-
-#ifdef KANJI
-  pstrcpy(term_code, KANJI);
-#else /* KANJI */
-  *term_code = 0;
-#endif /* KANJI */
-
-  *query_host = 0;
-  *base_directory = 0;
-
-  DEBUGLEVEL = 2;
-
-  setup_logging(pname,True);
-
-  TimeInit();
-  charset_initialise();
-
-  pid = (uint16)getpid();
-  vuid = (uint16)getuid();
-  mid = pid + 100;
-  myumask = umask(0);
-  umask(myumask);
-
-  if (getenv("USER"))
-  {
-    pstrcpy(username,getenv("USER"));
-
-    /* modification to support userid%passwd syntax in the USER var
-       25.Aug.97, jdblair@uab.edu */
-
-    if ((p=strchr(username,'%')))
-    {
-      *p = 0;
-      pstrcpy(password,p+1);
-      got_pass = True;
-      memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
-    }
-    strupper(username);
-  }
-
- /* modification to support PASSWD environmental var
-  25.Aug.97, jdblair@uab.edu */
-
-  if (getenv("PASSWD"))
-    pstrcpy(password,getenv("PASSWD"));
-
-  if (*username == 0 && getenv("LOGNAME"))
-    {
-      pstrcpy(username,getenv("LOGNAME"));
-      strupper(username);
-    }
-
-  if (argc < 2)
-    {
-      usage(pname);
-      exit(1);
-    }
-  
-  if (*argv[1] != '-')
-    {
-
-      pstrcpy(service, argv[1]);  
-      /* Convert any '/' characters in the service name to '\' characters */
-      string_replace( service, '/','\\');
-      argc--;
-      argv++;
-
-      if (count_chars(service,'\\') < 3)
-       {
-         usage(pname);
-         printf("\n%s: Not enough '\\' characters in service\n",service);
-         exit(1);
-       }
-
-      if (argc > 1 && (*argv[1] != '-'))
-       {
-         got_pass = True;
-         pstrcpy(password,argv[1]);  
-         memset(argv[1],'X',strlen(argv[1]));
-         argc--;
-         argv++;
-       }
-    }
-
-  while ((opt = 
-         getopt(argc, argv,"s:B:O:M:S:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
-    switch (opt)
-      {
-      case 'm':
-       max_protocol = interpret_protocol(optarg,max_protocol);
-       break;
-      case 'O':
-       pstrcpy(user_socket_options,optarg);
-       break;  
-      case 'S':
-       pstrcpy(desthost,optarg);
-       strupper(desthost);
-       nt_domain_logon = True;
-       break;
-      case 'B':
-       iface_set_default(NULL,optarg,NULL);
-       break;
-      case 'D':
-       pstrcpy(base_directory,optarg);
-       break;
-      case 'i':
-       pstrcpy(scope,optarg);
-       break;
-      case 'U':
-       {
-         char *lp;
-       pstrcpy(username,optarg);
-       if ((lp=strchr(username,'%')))
-         {
-           *lp = 0;
-           pstrcpy(password,lp+1);
-           got_pass = True;
-           memset(strchr(optarg,'%')+1,'X',strlen(password));
-         }
-       }
-           
-       break;
-      case 'W':
-       pstrcpy(workgroup,optarg);
-       break;
-      case 'E':
-       dbf = stderr;
-       break;
-      case 'I':
-       {
-         dest_ip = *interpret_addr2(optarg);
-         if (zero_ip(dest_ip)) exit(1);
-         have_ip = True;
-       }
-       break;
-      case 'n':
-       pstrcpy(global_myname,optarg);
-       break;
-      case 'N':
-       got_pass = True;
-       break;
-      case 'd':
-       if (*optarg == 'A')
-         DEBUGLEVEL = 10000;
-       else
-         DEBUGLEVEL = atoi(optarg);
-       break;
-      case 'l':
-       slprintf(debugf,sizeof(debugf)-1,"%s.client",optarg);
-       break;
-      case 'p':
-       port = atoi(optarg);
-       break;
-      case 'c':
-       cmdstr = optarg;
-       got_pass = True;
-       break;
-      case 'h':
-       usage(pname);
-       exit(0);
-       break;
-      case 's':
-       pstrcpy(servicesf, optarg);
-       break;
-      case 't':
-        pstrcpy(term_code, optarg);
-       break;
-      default:
-       usage(pname);
-       exit(1);
-      }
+       extern char *optarg;
+       extern int optind;
+       static pstring servicesf = CONFIGFILE;
+       char *p;
 
-  if (!*query_host && !*service)
-    {
-      usage(pname);
-      exit(1);
-    }
+       DEBUGLEVEL = 1;
+       
+       setup_logging("mount.smbfs",True);
 
+       TimeInit();
+       charset_initialise();
+       
+       in_client = True;   /* Make sure that we tell lp_load we are */
 
-  DEBUG( 3, ( "Client started (version %s)\n", VERSION ) );
+       if (getenv("USER")) {
+               pstrcpy(username,getenv("USER"));
 
-  if(!get_myname(myhostname,NULL))
-  {
-    DEBUG(0,("Failed to get my hostname.\n"));
-  }
+               if ((p=strchr(username,'%'))) {
+                       *p = 0;
+                       pstrcpy(password,p+1);
+                       got_pass = True;
+               }
+       }
 
-  if (!lp_load(servicesf,True,False,False)) {
-    fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
-  }
+       if (getenv("PASSWD")) {
+               pstrcpy(password,getenv("PASSWD"));
+       }
 
-  codepage_initialise(lp_client_code_page());
+       if (*username == 0 && getenv("LOGNAME")) {
+               pstrcpy(username,getenv("LOGNAME"));
+       }
+
+       parse_mount_smb(argc, argv);
 
-  interpret_coding_system(term_code);
+       DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
 
-  if (*workgroup == 0)
-    pstrcpy(workgroup,lp_workgroup());
+       if (!lp_load(servicesf,True,False,False)) {
+               fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
+                       servicesf);
+       }
 
-  load_interfaces();
-  get_myname((*global_myname)?NULL:global_myname,NULL);  
-  strupper(global_myname);
+       codepage_initialise(lp_client_code_page());
+
+       if (*workgroup == 0) {
+               pstrcpy(workgroup,lp_workgroup());
+       }
 
-  if (cli_open_sockets(port))
-    {
-      if (!process(base_directory))
-       {
-         close_sockets();
-         return(1);
+       load_interfaces();
+       if (!*my_netbios_name) {
+               pstrcpy(my_netbios_name, myhostname());
        }
-      close_sockets();
-    }
-  else
-    return(1);
+       strupper(my_netbios_name);
 
-  return(0);
+       init_mount();
+       return 0;
 }
index bc8999d765e1a0880a2c1b5a9691f7710eedeeaf..dacf4ab67d08b28dab7e73a24c2c6300333801f2 100644 (file)
 #undef SMB_IOC_GETMOUNTUID
 #define        SMB_IOC_GETMOUNTUID             _IOR('u', 1, __kernel_uid_t)
 
-static char *progname;
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW     0400000
+#endif
 
 static void
 usage(void)
 {
-        printf("usage: %s mount-point\n", progname);
+        printf("usage: smbumount mountpoint\n");
 }
 
 static int
 umount_ok(const char *mount_point)
 {
-        int fid = open(mount_point, O_RDONLY, 0);
+       /* we set O_NOFOLLOW to prevent users playing games with symlinks to
+          umount filesystems they don't own */
+        int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
         __kernel_uid_t mount_uid;
-
+       
         if (fid == -1) {
                 fprintf(stderr, "Could not open %s: %s\n",
                         mount_point, strerror(errno));
@@ -49,7 +53,7 @@ umount_ok(const char *mount_point)
                 return -1;
         }
 
-        if (   (getuid() != 0)
+        if ((getuid() != 0)
             && (mount_uid != getuid())) {
                 fprintf(stderr, "You are not allowed to umount %s\n",
                         mount_point);
@@ -63,15 +67,14 @@ umount_ok(const char *mount_point)
 /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
    It is up the *caller* to ensure that the PATH is sensible.  i.e.
    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
-   is not a legal pathname for ``/dev/fd0.''  Anything we cannot parse
+   is not a legal pathname for ``/dev/fd0''  Anything we cannot parse
    we return unmodified.   */
-char *
+static char *
 canonicalize (char *path)
 {
        char *canonical = malloc (PATH_MAX + 1);
 
-       if (strlen(path) > PATH_MAX)
-       {
+       if (strlen(path) > PATH_MAX) {
                fprintf(stderr, "Mount point string too long\n");
                return NULL;
        }
@@ -91,22 +94,18 @@ int
 main(int argc, char *argv[])
 {
         int fd;
-
         char* mount_point;
-
         struct mntent *mnt;
         FILE* mtab;
         FILE* new_mtab;
 
-        progname = argv[0];
-
         if (argc != 2) {
                 usage();
                 exit(1);
         }
 
         if (geteuid() != 0) {
-                fprintf(stderr, "%s must be installed suid root\n", progname);
+                fprintf(stderr, "smbumount must be installed suid root\n");
                 exit(1);
         }
 
index 8d9ff631fba5899f5e91fee5d09f098cbf4b9635..5d636ae420a8e542a53b30ccb43105e0efb470dd 100644 (file)
@@ -21,4 +21,3 @@
 # The columns are :
 # lower    upper   map upper to lower    map lower to upper
 #
-# This file is intentionaly empty - no mappings are done.
\ No newline at end of file
index 8ec56e286a887ef8da5a3c7e857a3b9ef2045be3..695867b068e64d76fed4a3786a3e809791e6eb30 100755 (executable)
@@ -349,6 +349,9 @@ EOF
     *:OpenBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
        exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-qnx-qnx4 
+       exit 0 ;;
     i*:CYGWIN*:*)
        echo i386-unknown-cygwin32
        exit 0 ;;
@@ -425,6 +428,9 @@ EOF
                echo ${UNAME_MACHINE}-unknown-sysv32
        fi
        exit 0 ;;
+       *:UnixWare:*:*)
+               echo ${UNAME_MACHINE}-UnixWare-sysv${UNAME_RELEASE}
+               exit 0 ;;
     Intel:Mach:3*:*)
        echo i386-unknown-mach3
        exit 0 ;;
@@ -446,7 +452,9 @@ EOF
        test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
     3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
         uname -p 2>/dev/null | grep 86 >/dev/null \
-          && echo i486-ncr-sysv4.3 && exit 0 ;;
+          && echo i486-ncr-sysv4.3 && exit 0
+        uname -p 2>/dev/null | grep entium >/dev/null \
+          && echo i586-ncr-sysv4.3 && exit 0 ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         uname -p 2>/dev/null | grep 86 >/dev/null \
           && echo i486-ncr-sysv4 && exit 0 ;;
@@ -476,6 +484,9 @@ EOF
                echo ns32k-sni-sysv
        fi
        exit 0 ;;
+       *:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
     mc68*:A/UX:*:*)
        echo m68k-apple-aux${UNAME_RELEASE}
        exit 0 ;;
index 8626d1c3b1acc76793135c22315cb8422e5c17c3..822c78ded0baff802f08efe07cc579f43d8ba176 100755 (executable)
@@ -25,13 +25,19 @@ ac_help="$ac_help
   --without-dfs  Don't include DFS support (default)"
 ac_help="$ac_help
   --with-krb4=base-dir     Include Kerberos IV support
-  --without-krb4          Don't include Kerberos IV support (default)"
+  --without-krb4          Don't include Kerbers IV support (default)"
+ac_help="$ac_help
+  --with-krb5=base-dir     Include Kerberos 5 support
+  --without-krb5          Don't include Kerbers 5 support (default)"
 ac_help="$ac_help
   --with-automount     Include AUTOMOUNT support
   --without-automount  Don't include AUTOMOUNT support (default)"
 ac_help="$ac_help
   --with-smbmount     Include SMBMOUNT (Linux only) support
   --without-smbmount  Don't include SMBMOUNT support (default)"
+ac_help="$ac_help
+  --with-pam     Include PAM password database support
+  --without-pam  Don't include PAM password database support (default)"
 ac_help="$ac_help
   --with-ldap     Include LDAP support
   --without-ldap  Don't include LDAP support (default)"
@@ -43,10 +49,8 @@ ac_help="$ac_help
   --without-nisplus-home  Don't include NISPLUS_HOME support (default)"
 ac_help="$ac_help
   --with-ssl     Include SSL support
-  --without-ssl  Don't include SSL support (default)"
-ac_help="$ac_help
-  --with-mmap     Include experimental MMAP support
-  --without-mmap  Don't include MMAP support (default)"
+  --without-ssl  Don't include SSL support (default)
+  --with-sslinc=DIR Where the SSL includes are (defaults to /usr/local/ssl)"
 ac_help="$ac_help
   --with-syslog     Include experimental SYSLOG support
   --without-syslog  Don't include SYSLOG support (default)"
@@ -59,6 +63,12 @@ ac_help="$ac_help
 ac_help="$ac_help
   --with-quotas     Include experimental disk-quota support
   --without-quotas  Don't include experimental disk-quota support (default)"
+ac_help="$ac_help
+  --with-privatedir=DIR     Where to put smbpasswd ($ac_default_prefix/private)"
+ac_help="$ac_help
+  --with-lockdir=DIR     Where to put lock files ($ac_default_prefix/var/locks)"
+ac_help="$ac_help
+  --with-swatdir=DIR     Where to put SWAT files ($ac_default_prefix/swat)"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -578,13 +588,15 @@ fi
 
 
 
+
+
 # compile with optimisation and without debugging by default
 CFLAGS=${CFLAGS-"-O"}
 
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:588: checking for $ac_word" >&5
+echo "configure:600: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -613,7 +625,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:617: checking for $ac_word" >&5
+echo "configure:629: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -661,7 +673,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:665: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:677: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -671,11 +683,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 675 "configure"
+#line 687 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -695,12 +707,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:699: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:711: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:704: checking whether we are using GNU C" >&5
+echo "configure:716: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -709,7 +721,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:713: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:725: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -724,7 +736,7 @@ if test $ac_cv_prog_gcc = yes; then
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:728: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:740: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -781,7 +793,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:785: checking for a BSD compatible install" >&5
+echo "configure:797: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -835,7 +847,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:839: checking for $ac_word" >&5
+echo "configure:851: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -864,6 +876,101 @@ test -n "$AWK" && break
 done
 
 
+if test "x$CC" != xcc; then
+  echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
+echo "configure:882: checking whether $CC and cc understand -c and -o together" >&5
+else
+  echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
+echo "configure:885: checking whether cc understands -c and -o together" >&5
+fi
+set dummy $CC; ac_cc="`echo $2 |
+                      sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
+if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'foo(){}' > conftest.c
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
+if { (eval echo configure:897: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+   test -f conftest.o && { (eval echo configure:898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+then
+  eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+  if test "x$CC" != xcc; then
+    # Test first that cc exists at all.
+    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+      ac_try='cc -c conftest.c -o conftest.o 1>&5'
+      if { (eval echo configure:905: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+        test -f conftest.o && { (eval echo configure:906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+      then
+        # cc works too.
+        :
+      else
+        # cc exists but doesn't like -o.
+        eval ac_cv_prog_cc_${ac_cc}_c_o=no
+      fi
+    fi
+  fi
+else
+  eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+  cat >> confdefs.h <<\EOF
+#define NO_MINUS_C_MINUS_O 1
+EOF
+
+fi
+
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+      BROKEN_CC=
+else
+      BROKEN_CC=#
+fi
+
+
+echo $ac_n "checking that the C compiler understands volatile""... $ac_c" 1>&6
+echo "configure:940: checking that the C compiler understands volatile" >&5
+if eval "test \"`echo '$''{'samba_cv_volatile'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 946 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+volatile int i = 0
+; return 0; }
+EOF
+if { (eval echo configure:953: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_volatile=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_volatile=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_volatile" 1>&6
+if test x"$samba_cv_volatile" = x"yes"; then
+   cat >> confdefs.h <<\EOF
+#define HAVE_VOLATILE 1
+EOF
+
+fi
+
+
+
 
 # Do some error checking and defaulting for the host and target type.
 # The inputs are:
@@ -892,7 +999,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:896: checking host system type" >&5
+echo "configure:1003: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -913,7 +1020,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:917: checking target system type" >&5
+echo "configure:1024: checking target system type" >&5
 
 target_alias=$target
 case "$target_alias" in
@@ -931,7 +1038,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$target" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:935: checking build system type" >&5
+echo "configure:1042: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -956,7 +1063,7 @@ test "$host_alias" != "$target_alias" &&
 
     
     echo $ac_n "checking config.cache system type""... $ac_c" 1>&6
-echo "configure:960: checking config.cache system type" >&5
+echo "configure:1067: checking config.cache system type" >&5
     if { test x"${ac_cv_host_system_type+set}" = x"set" &&
          test x"$ac_cv_host_system_type" != x"$host"; } ||
        { test x"${ac_cv_build_system_type+set}" = x"set" &&
@@ -986,7 +1093,7 @@ fi
   # Extract the first word of "autoconf", so it can be a program name with args.
 set dummy autoconf; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:990: checking for $ac_word" >&5
+echo "configure:1097: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AUTOCONF'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1019,7 +1126,7 @@ fi
   # Extract the first word of "autoheader", so it can be a program name with args.
 set dummy autoheader; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1023: checking for $ac_word" >&5
+echo "configure:1130: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AUTOHEADER'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1059,7 +1166,7 @@ case "$host_os" in
 # Try to work out if this is the native HPUX compiler that uses the -Ae flag.
     *hpux*)
       echo $ac_n "checking whether ${CC-cc} accepts -Ae""... $ac_c" 1>&6
-echo "configure:1063: checking whether ${CC-cc} accepts -Ae" >&5
+echo "configure:1170: checking whether ${CC-cc} accepts -Ae" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_Ae'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1077,32 +1184,178 @@ echo "$ac_t""$ac_cv_prog_cc_Ae" 1>&6
       if test $ac_cv_prog_cc_Ae = yes; then
         CPPFLAGS="$CPPFLAGS -Ae"
       fi
+#
+# Defines needed for HPUX support.
+# HPUX has bigcrypt but (sometimes?) doesn't use it for
+# password hashing - hence the USE_BOTH_CRYPT_CALLS define.
+#
+      case `uname -r` in
+                       *9*|*10*)
+                               CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
+                               cat >> confdefs.h <<\EOF
+#define USE_BOTH_CRYPT_CALLS 1
+EOF
+
+                               ;;
+                       *11*)
+                               CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
+                               cat >> confdefs.h <<\EOF
+#define USE_BOTH_CRYPT_CALLS 1
+EOF
+
+                               ;;
+      esac
       ;;
 #
-# AIX4.x is *so* broken. It doesn't even admit to having large
+# AIX4.x doesn't even admit to having large
 # files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
 #
     *aix4*)
+         echo "$ac_t""enabling large file support" 1>&6
       CPPFLAGS="$CPPFLAGS -D_LARGE_FILES"
       ;;    
+#
+# Defines needed for Solaris 2.6/2.7 aka 7.0 to make it admit
+# to the existance of large files..
+# Note that -D_LARGEFILE64_SOURCE is different from the Sun
+# recommendations on large file support, however it makes the
+# compile work using gcc 2.7 and 2.8, whereas using the Sun
+# recommendation makes the compile fail on gcc2.7. JRA.
+#
+       *solaris*)
+               case `uname -r` in
+                       5.6*|5.7*)
+                       echo "$ac_t""enabling large file support" 1>&6
+                       if test "$ac_cv_prog_gcc" = yes; then
+                               ${CC-cc} -v >conftest.c 2>&1
+                               ac_cv_gcc_compiler_version_number=`grep 'gcc version' conftest.c`
+                               rm -fr conftest.c
+                               case "$ac_cv_gcc_compiler_version_number" in
+                                       *"gcc version 2.6"*|*"gcc version 2.7"*)
+                                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
+                                               ;;
+                                       *)
+                                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+                                               ;;
+                               esac
+                       else
+                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+                       fi
+                       ;;
+               esac
+               ;;
+#
+# Tests needed for SINIX large file support.
+#
+    *sysv4*)
+      if test $host = mips-sni-sysv4 ; then
+        echo $ac_n "checking for LFS support""... $ac_c" 1>&6
+echo "configure:1254: checking for LFS support" >&5
+        old_CPPFLAGS="$CPPFLAGS"
+        CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
+        if test "$cross_compiling" = yes; then
+  SINIX_LFS_SUPPORT=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1261 "configure"
+#include "confdefs.h"
+
+#include <unistd.h>
+main () {
+#if _LFS64_LARGEFILE == 1
+exit(0);
+#else
+exit(1);
+#endif
+}
+EOF
+if { (eval echo configure:1273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  SINIX_LFS_SUPPORT=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  SINIX_LFS_SUPPORT=no
+fi
+rm -fr conftest*
+fi
+
+        CPPFLAGS="$old_CPPFLAGS"
+        if test x$SINIX_LFS_SUPPORT = xyes ; then
+          CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
+          CFLAGS="`getconf LFS64_CFLAGS` $CFLAGS"
+          LDFLAGS="`getconf LFS64_LDFLAGS` $LDFLAGS"
+          LIBS="`getconf LFS64_LIBS` $LIBS"
+        fi
+      echo "$ac_t""$SINIX_LFS_SUPPORT" 1>&6
+      fi
+    ;;
+
+#
+# Tests needed for glibc 2.1 large file support.
+# 
+       *linux*)
+               echo "$ac_t""disabling large file support for glibc2.1 on Linux" 1>&6     
+               ;;
+    *hurd*)
+        echo $ac_n "checking for LFS support""... $ac_c" 1>&6
+echo "configure:1304: checking for LFS support" >&5
+        old_CPPFLAGS="$CPPFLAGS"
+        CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
+        if test "$cross_compiling" = yes; then
+  GLIBC_LFS_SUPPORT=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1311 "configure"
+#include "confdefs.h"
+
+#include <unistd.h>
+main () {
+#if _LFS64_LARGEFILE == 1
+exit(0);
+#else
+exit(1);
+#endif
+}
+EOF
+if { (eval echo configure:1323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  GLIBC_LFS_SUPPORT=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  GLIBC_LFS_SUPPORT=no
+fi
+rm -fr conftest*
+fi
+
+        CPPFLAGS="$old_CPPFLAGS"
+        if test x$GLIBC_LFS_SUPPORT = xyes ; then
+          CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
+        fi
+      echo "$ac_t""$GLIBC_LFS_SUPPORT" 1>&6
+    ;;
+
 esac
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1092: checking for inline" >&5
+echo "configure:1345: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 1099 "configure"
+#line 1352 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:1106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -1128,7 +1381,7 @@ EOF
 esac
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1132: checking how to run the C preprocessor" >&5
+echo "configure:1385: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1143,13 +1396,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1147 "configure"
+#line 1400 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1153: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1406: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1160,13 +1413,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1164 "configure"
+#line 1417 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1423: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1189,12 +1442,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1193: checking for ANSI C header files" >&5
+echo "configure:1446: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1198 "configure"
+#line 1451 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1202,7 +1455,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1459: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1219,7 +1472,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1223 "configure"
+#line 1476 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1237,7 +1490,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1241 "configure"
+#line 1494 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1258,7 +1511,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1262 "configure"
+#line 1515 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1269,7 +1522,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1297,12 +1550,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1301: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1554: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1306 "configure"
+#line 1559 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -1310,7 +1563,7 @@ int main() {
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1567: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -1335,7 +1588,7 @@ done
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1339: checking for opendir in -ldir" >&5
+echo "configure:1592: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1343,7 +1596,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1347 "configure"
+#line 1600 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1354,7 +1607,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1376,7 +1629,7 @@ fi
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1380: checking for opendir in -lx" >&5
+echo "configure:1633: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1384,7 +1637,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1388 "configure"
+#line 1641 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1395,7 +1648,7 @@ int main() {
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1418,12 +1671,12 @@ fi
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1422: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1675: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1427 "configure"
+#line 1680 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1432,7 +1685,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1436: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1689: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1453,12 +1706,12 @@ EOF
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1457: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1710: checking for sys/wait.h that is POSIX.1 compatible" >&5
 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1462 "configure"
+#line 1715 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1474,7 +1727,7 @@ wait (&s);
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:1478: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -1494,21 +1747,21 @@ EOF
 
 fi
 
-for ac_hdr in sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h
+for ac_hdr in arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1502: checking for $ac_hdr" >&5
+echo "configure:1755: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1507 "configure"
+#line 1760 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1512: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1765: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1534,21 +1787,21 @@ else
 fi
 done
 
-for ac_hdr in sys/param.h ctype.h 
+for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1542: checking for $ac_hdr" >&5
+echo "configure:1795: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1547 "configure"
+#line 1800 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1552: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1805: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1574,21 +1827,21 @@ else
 fi
 done
 
-for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/route.h net/if.h
+for ac_hdr in compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1582: checking for $ac_hdr" >&5
+echo "configure:1835: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1587 "configure"
+#line 1840 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1592: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1614,21 +1867,21 @@ else
 fi
 done
 
-for ac_hdr in compat.h rpc/rpc.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h sys/param.h ctype.h 
+for ac_hdr in sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1622: checking for $ac_hdr" >&5
+echo "configure:1875: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1627 "configure"
+#line 1880 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1632: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1885: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1654,21 +1907,21 @@ else
 fi
 done
 
-for ac_hdr in sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h sys/mman.h
+for ac_hdr in sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1662: checking for $ac_hdr" >&5
+echo "configure:1915: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1667 "configure"
+#line 1920 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1672: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1925: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1694,21 +1947,21 @@ else
 fi
 done
 
-for ac_hdr in sys/filio.h string.h strings.h stdlib.h sys/socket.h sys/un.h
+for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1702: checking for $ac_hdr" >&5
+echo "configure:1955: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1707 "configure"
+#line 1960 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1712: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1965: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1734,21 +1987,21 @@ else
 fi
 done
 
-for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h
+for ac_hdr in sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1742: checking for $ac_hdr" >&5
+echo "configure:1995: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1747 "configure"
+#line 2000 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1752: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2005: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1774,21 +2027,53 @@ else
 fi
 done
 
-for ac_hdr in sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h
+#
+# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
+# This causes configure to fail to detect it. Check for shadow separately on HPUX.
+#
+case "$host_os" in
+    *hpux*)
+               cat > conftest.$ac_ext <<EOF
+#line 2038 "configure"
+#include "confdefs.h"
+#include <shadow.h>
+int main() {
+struct spwd testme
+; return 0; }
+EOF
+if { (eval echo configure:2045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_shadow_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_shadow_h=no
+fi
+rm -f conftest*
+               if test x"$ac_cv_header_shadow_h" = x"yes"; then
+                  cat >> confdefs.h <<\EOF
+#define HAVE_SHADOW_H 1
+EOF
+
+               fi
+       ;;
+esac
+for ac_hdr in shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1782: checking for $ac_hdr" >&5
+echo "configure:2067: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1787 "configure"
+#line 2072 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1792: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2077: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1814,21 +2099,21 @@ else
 fi
 done
 
-for ac_hdr in shadow.h netinet/tcp.h sys/security.h security/pam_appl.h
+for ac_hdr in sys/security.h security/pam_appl.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1822: checking for $ac_hdr" >&5
+echo "configure:2107: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1827 "configure"
+#line 2112 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2117: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1858,17 +2143,17 @@ for ac_hdr in stropts.h poll.h readline.h history.h readline/readline.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1862: checking for $ac_hdr" >&5
+echo "configure:2147: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1867 "configure"
+#line 2152 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1872: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1898,17 +2183,17 @@ for ac_hdr in readline/history.h sys/capability.h syscall.h sys/syscall.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1902: checking for $ac_hdr" >&5
+echo "configure:2187: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1907 "configure"
+#line 2192 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1912: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1934,21 +2219,21 @@ else
 fi
 done
 
-for ac_hdr in sys/acl.h sys/cdefs.h glob.h mysql.h
+for ac_hdr in sys/acl.h sys/cdefs.h glob.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1942: checking for $ac_hdr" >&5
+echo "configure:2227: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1947 "configure"
+#line 2232 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1952: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2237: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1976,7 +2261,7 @@ done
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:1980: checking size of int" >&5
+echo "configure:2265: checking size of int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1984,7 +2269,7 @@ else
   ac_cv_sizeof_int=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 1988 "configure"
+#line 2273 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1995,7 +2280,7 @@ main()
   exit(0);
 }
 EOF
-if { (eval echo configure:1999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -2015,7 +2300,7 @@ EOF
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:2019: checking size of long" >&5
+echo "configure:2304: checking size of long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2023,7 +2308,7 @@ else
   ac_cv_sizeof_long=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 2027 "configure"
+#line 2312 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2034,7 +2319,7 @@ main()
   exit(0);
 }
 EOF
-if { (eval echo configure:2038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -2054,7 +2339,7 @@ EOF
 
 
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:2058: checking size of short" >&5
+echo "configure:2343: checking size of short" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2062,7 +2347,7 @@ else
   ac_cv_sizeof_short=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 2066 "configure"
+#line 2351 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -2073,7 +2358,7 @@ main()
   exit(0);
 }
 EOF
-if { (eval echo configure:2077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_short=`cat conftestval`
 else
@@ -2094,12 +2379,12 @@ EOF
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2098: checking for working const" >&5
+echo "configure:2383: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2103 "configure"
+#line 2388 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2148,7 +2433,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:2152: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2437: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2169,21 +2454,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:2173: checking for inline" >&5
+echo "configure:2458: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 2180 "configure"
+#line 2465 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:2187: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2472: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -2209,14 +2494,14 @@ EOF
 esac
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:2213: checking whether byte ordering is bigendian" >&5
+echo "configure:2498: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 2220 "configure"
+#line 2505 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2227,11 +2512,11 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2231: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2516: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 2235 "configure"
+#line 2520 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -2242,7 +2527,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:2246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2531: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -2262,7 +2547,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2266 "configure"
+#line 2551 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -2275,7 +2560,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:2279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -2299,14 +2584,14 @@ EOF
 fi
 
 echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-echo "configure:2303: checking whether char is unsigned" >&5
+echo "configure:2588: checking whether char is unsigned" >&5
 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$GCC" = yes; then
   # GCC predefines this symbol on systems where it applies.
 cat > conftest.$ac_ext <<EOF
-#line 2310 "configure"
+#line 2595 "configure"
 #include "confdefs.h"
 #ifdef __CHAR_UNSIGNED__
   yes
@@ -2328,7 +2613,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2332 "configure"
+#line 2617 "configure"
 #include "confdefs.h"
 /* volatile prevents gcc2 from optimizing the test away on sparcs.  */
 #if !defined(__STDC__) || __STDC__ != 1
@@ -2338,7 +2623,7 @@ main() {
   volatile char c = 255; exit(c < 0);
 }
 EOF
-if { (eval echo configure:2342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_char_unsigned=yes
 else
@@ -2363,12 +2648,12 @@ fi
 
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2367: checking return type of signal handlers" >&5
+echo "configure:2652: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2372 "configure"
+#line 2657 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -2385,7 +2670,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2674: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -2404,12 +2689,12 @@ EOF
 
 
 echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:2408: checking for uid_t in sys/types.h" >&5
+echo "configure:2693: checking for uid_t in sys/types.h" >&5
 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2413 "configure"
+#line 2698 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -2438,12 +2723,12 @@ EOF
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:2442: checking for mode_t" >&5
+echo "configure:2727: checking for mode_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2447 "configure"
+#line 2732 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2471,12 +2756,12 @@ EOF
 fi
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:2475: checking for off_t" >&5
+echo "configure:2760: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2480 "configure"
+#line 2765 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2504,12 +2789,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2508: checking for size_t" >&5
+echo "configure:2793: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2513 "configure"
+#line 2798 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2537,12 +2822,12 @@ EOF
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2541: checking for pid_t" >&5
+echo "configure:2826: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2546 "configure"
+#line 2831 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2570,12 +2855,12 @@ EOF
 fi
 
 echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:2574: checking for st_rdev in struct stat" >&5
+echo "configure:2859: checking for st_rdev in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2579 "configure"
+#line 2864 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2583,7 +2868,7 @@ int main() {
 struct stat s; s.st_rdev;
 ; return 0; }
 EOF
-if { (eval echo configure:2587: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2872: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_struct_st_rdev=yes
 else
@@ -2604,12 +2889,12 @@ EOF
 fi
 
 echo $ac_n "checking for d_off in dirent""... $ac_c" 1>&6
-echo "configure:2608: checking for d_off in dirent" >&5
+echo "configure:2893: checking for d_off in dirent" >&5
 if eval "test \"`echo '$''{'ac_cv_dirent_d_off'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2613 "configure"
+#line 2898 "configure"
 #include "confdefs.h"
 
 #include <unistd.h>
@@ -2619,7 +2904,7 @@ int main() {
 struct dirent d; d.d_off;
 ; return 0; }
 EOF
-if { (eval echo configure:2623: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2908: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_dirent_d_off=yes
 else
@@ -2640,12 +2925,12 @@ EOF
 fi
 
 echo $ac_n "checking for ino_t""... $ac_c" 1>&6
-echo "configure:2644: checking for ino_t" >&5
+echo "configure:2929: checking for ino_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ino_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2649 "configure"
+#line 2934 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2673,12 +2958,12 @@ EOF
 fi
 
 echo $ac_n "checking for loff_t""... $ac_c" 1>&6
-echo "configure:2677: checking for loff_t" >&5
+echo "configure:2962: checking for loff_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_loff_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2682 "configure"
+#line 2967 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2706,12 +2991,12 @@ EOF
 fi
 
 echo $ac_n "checking for offset_t""... $ac_c" 1>&6
-echo "configure:2710: checking for offset_t" >&5
+echo "configure:2995: checking for offset_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_offset_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2715 "configure"
+#line 3000 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2739,12 +3024,12 @@ EOF
 fi
 
 echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:2743: checking for ssize_t" >&5
+echo "configure:3028: checking for ssize_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2748 "configure"
+#line 3033 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2772,28 +3057,162 @@ EOF
 fi
 
 
+# we need libcups for CUPS support...
+echo $ac_n "checking for httpConnect in -lcups""... $ac_c" 1>&6
+echo "configure:3063: checking for httpConnect in -lcups" >&5
+ac_lib_var=`echo cups'_'httpConnect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lcups  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3071 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char httpConnect();
+
+int main() {
+httpConnect()
+; return 0; }
+EOF
+if { (eval echo configure:3082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo cups | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lcups $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# we need libdl for PAM and the new VFS code
+echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6
+echo "configure:3112: checking for main in -ldl" >&5
+ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3120 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:3127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-ldl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for sig_atomic_t type""... $ac_c" 1>&6
+echo "configure:3156: checking for sig_atomic_t type" >&5
+if eval "test \"`echo '$''{'samba_cv_sig_atomic_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 3162 "configure"
+#include "confdefs.h"
+
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <signal.h>
+int main() {
+sig_atomic_t i = 0
+; return 0; }
+EOF
+if { (eval echo configure:3175: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_sig_atomic_t=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_sig_atomic_t=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_sig_atomic_t" 1>&6
+if test x"$samba_cv_sig_atomic_t" = x"yes"; then
+   cat >> confdefs.h <<\EOF
+#define HAVE_SIG_ATOMIC_T_TYPE 1
+EOF
+
+fi
+
 echo $ac_n "checking for errno in errno.h""... $ac_c" 1>&6
-echo "configure:2777: checking for errno in errno.h" >&5
+echo "configure:3196: checking for errno in errno.h" >&5
 if eval "test \"`echo '$''{'samba_cv_errno'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 2783 "configure"
+#line 3202 "configure"
 #include "confdefs.h"
 #include <errno.h>
 int main() {
 int i = errno
 ; return 0; }
 EOF
-if { (eval echo configure:2790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3209: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_errno=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  samba_cv_have_errno_decl=no
+  samba_cv_have_errno=no
 fi
 rm -f conftest*
 fi
@@ -2808,20 +3227,20 @@ fi
 
 # stupid glibc has the functions but no declaration. grrrr.
 echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6
-echo "configure:2812: checking for setresuid declaration" >&5
+echo "configure:3231: checking for setresuid declaration" >&5
 if eval "test \"`echo '$''{'samba_cv_have_setresuid_decl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 2818 "configure"
+#line 3237 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 int main() {
 int i = (int)setresuid
 ; return 0; }
 EOF
-if { (eval echo configure:2825: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3244: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_have_setresuid_decl=yes
 else
@@ -2842,36 +3261,36 @@ EOF
 fi
 
 # stupid glibc has the functions but no declaration. grrrr.
-echo $ac_n "checking for crypt declaration""... $ac_c" 1>&6
-echo "configure:2847: checking for crypt declaration" >&5
-if eval "test \"`echo '$''{'samba_cv_have_crypt_decl'+set}'`\" = set"; then
+echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6
+echo "configure:3266: checking for setresgid declaration" >&5
+if eval "test \"`echo '$''{'samba_cv_have_setresgid_decl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 2853 "configure"
+#line 3272 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 int main() {
-int i = (int)crypt
+int i = (int)setresgid
 ; return 0; }
 EOF
-if { (eval echo configure:2860: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3279: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
-  samba_cv_have_crypt_decl=yes
+  samba_cv_have_setresgid_decl=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  samba_cv_have_crypt_decl=no
+  samba_cv_have_setresgid_decl=no
 fi
 rm -f conftest*
 fi
 
-echo "$ac_t""$samba_cv_have_crypt_decl" 1>&6
-if test x"$samba_cv_have_crypt_decl" = x"yes"; then
+echo "$ac_t""$samba_cv_have_setresgid_decl" 1>&6
+if test x"$samba_cv_have_setresgid_decl" = x"yes"; then
     cat >> confdefs.h <<\EOF
-#define HAVE_CRYPT_DECL 1
+#define HAVE_SETRESGID_DECL 1
 EOF
 
 fi
@@ -2879,7 +3298,7 @@ fi
 # and glibc has setresuid under linux but the function does
 # nothing until kernel 2.1.44! very dumb.
 echo $ac_n "checking for real setresuid""... $ac_c" 1>&6
-echo "configure:2883: checking for real setresuid" >&5
+echo "configure:3302: checking for real setresuid" >&5
 if eval "test \"`echo '$''{'samba_cv_have_setresuid'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2888,12 +3307,12 @@ else
   samba_cv_have_setresuid=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 2892 "configure"
+#line 3311 "configure"
 #include "confdefs.h"
 #include <errno.h>
 main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);}
 EOF
-if { (eval echo configure:2897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_have_setresuid=yes
 else
@@ -2915,26 +3334,66 @@ EOF
 
 fi
 
-echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:2920: checking for 8-bit clean memcmp" >&5
-if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
+# Do the same check for setresguid...
+#
+echo $ac_n "checking for real setresgid""... $ac_c" 1>&6
+echo "configure:3341: checking for real setresgid" >&5
+if eval "test \"`echo '$''{'samba_cv_have_setresgid'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_memcmp_clean=no
+  
+    if test "$cross_compiling" = yes; then
+  samba_cv_have_setresgid=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 2928 "configure"
+#line 3350 "configure"
 #include "confdefs.h"
-
-main()
-{
-  char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+#include <unistd.h>
+#include <errno.h>
+main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}
+EOF
+if { (eval echo configure:3356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_have_setresgid=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_have_setresgid=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_have_setresgid" 1>&6
+if test x"$samba_cv_have_setresgid" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_SETRESGID 1
+EOF
+
+fi
+
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
+echo "configure:3379: checking for 8-bit clean memcmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_memcmp_clean=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3387 "configure"
+#include "confdefs.h"
+
+main()
+{
+  char c0 = 0x40, c1 = 0x80, c2 = 0x81;
   exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
 }
 
 EOF
-if { (eval echo configure:2938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_memcmp_clean=yes
 else
@@ -2957,12 +3416,12 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.o"
 for ac_func in crypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2961: checking for $ac_func" >&5
+echo "configure:3420: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2966 "configure"
+#line 3425 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2985,7 +3444,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3011,7 +3470,7 @@ done
 
 if test x"$ac_cv_func_crypt" = x"no"; then
     echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:3015: checking for crypt in -lcrypt" >&5
+echo "configure:3474: checking for crypt in -lcrypt" >&5
 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3019,7 +3478,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3023 "configure"
+#line 3482 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3030,7 +3489,7 @@ int main() {
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:3034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3058,26 +3517,30 @@ fi
 
 
 ###############################################
-# test for where we get pam_authenticate() from
-# might need libdl for this to work
-if test "$ac_cv_header_security_pam_appl_h" = "yes"; then
-  echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6
-echo "configure:3066: checking for main in -ldl" >&5
-ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'`
+# test for where we get readline() from
+if test "$ac_cv_header_readline_h" = "yes" ||
+   test "$ac_cv_header_readline_readline_h" = "yes"; then
+  echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
+echo "configure:3525: checking for readline in -lreadline" >&5
+ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-ldl  $LIBS"
+LIBS="-lreadline  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3074 "configure"
+#line 3533 "configure"
 #include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char readline();
 
 int main() {
-main()
+readline()
 ; return 0; }
 EOF
-if { (eval echo configure:3081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3092,28 +3555,36 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo readline | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-ldl $LIBS"
+  LIBS="-lreadline $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
 
 fi
-for ac_func in pam_authenticate
+
+
+# The following test taken from the cvs sources
+# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
+# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
+# libsocket.so which has a bad implementation of gethostbyname (it
+# only looks in /etc/hosts), so we only look for -lsocket if we need
+# it.
+for ac_func in connect
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3112: checking for $ac_func" >&5
+echo "configure:3583: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3117 "configure"
+#line 3588 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3136,7 +3607,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3160,28 +3631,30 @@ else
 fi
 done
 
-if test x"$ac_cv_func_pam_authenticate" = x"no"; then
-    echo $ac_n "checking for pam_authenticate in -lpam""... $ac_c" 1>&6
-echo "configure:3166: checking for pam_authenticate in -lpam" >&5
-ac_lib_var=`echo pam'_'pam_authenticate | sed 'y%./+-%__p_%'`
+if test x"$ac_cv_func_connect" = x"no"; then
+    case "$LIBS" in
+    *-lnsl*) ;;
+    *) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6
+echo "configure:3639: checking for printf in -lnsl_s" >&5
+ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lpam  $LIBS"
+LIBS="-lnsl_s  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3174 "configure"
+#line 3647 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char pam_authenticate();
+char printf();
 
 int main() {
-pam_authenticate()
+printf()
 ; return 0; }
 EOF
-if { (eval echo configure:3185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3196,97 +3669,92 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  LIBS="$LIBS -lpam"
-       cat >> confdefs.h <<\EOF
-#define HAVE_PAM_AUTHENTICATE 1
+    ac_tr_lib=HAVE_LIB`echo nsl_s | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
 EOF
 
+  LIBS="-lnsl_s $LIBS"
+
 else
   echo "$ac_t""no" 1>&6
 fi
-
-fi
-
-###############################################
-# readline requires some curses routines
-if test "$ac_cv_header_readline_h" = "yes" ||
-   test "$ac_cv_header_readline_readline_h" = "yes"; then
-  for ac_func in tputs
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3218: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ ;;
+    esac
+    case "$LIBS" in
+    *-lnsl*) ;;
+    *) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6
+echo "configure:3689: checking for printf in -lnsl" >&5
+ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  cat > conftest.$ac_ext <<EOF
-#line 3223 "configure"
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3697 "configure"
 #include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func(); below.  */
-#include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char $ac_func();
+char printf();
 
 int main() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
+printf()
 ; return 0; }
 EOF
-if { (eval echo configure:3246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
-  eval "ac_cv_func_$ac_func=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_func_$ac_func=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
-fi
+LIBS="$ac_save_LIBS"
 
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
+#define $ac_tr_lib 1
 EOF
+
+  LIBS="-lnsl $LIBS"
+
 else
   echo "$ac_t""no" 1>&6
 fi
-done
-
-  echo $ac_n "checking for tputs in -lcurses""... $ac_c" 1>&6
-echo "configure:3271: checking for tputs in -lcurses" >&5
-ac_lib_var=`echo curses'_'tputs | sed 'y%./+-%__p_%'`
+ ;;
+    esac
+    case "$LIBS" in
+    *-lsocket*) ;;
+    *) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:3739: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lcurses  $LIBS"
+LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3279 "configure"
+#line 3747 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char tputs();
+char connect();
 
 int main() {
-tputs()
+connect()
 ; return 0; }
 EOF
-if { (eval echo configure:3290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3301,32 +3769,42 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  LIBS="$LIBS -lcurses"
+    ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsocket $LIBS"
+
 else
   echo "$ac_t""no" 1>&6
 fi
-
-  echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:3311: checking for readline in -lreadline" >&5
-ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
+ ;;
+    esac
+    case "$LIBS" in
+    *-linet*) ;;
+    *) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6
+echo "configure:3789: checking for connect in -linet" >&5
+ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lreadline  $LIBS"
+LIBS="-linet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3319 "configure"
+#line 3797 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char readline();
+char connect();
 
 int main() {
-readline()
+connect()
 ; return 0; }
 EOF
-if { (eval echo configure:3330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3341,73 +3819,40 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo readline | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lreadline $LIBS"
+  LIBS="-linet $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
-
-  echo $ac_n "checking for filename_completion_function proto""... $ac_c" 1>&6
-echo "configure:3358: checking for filename_completion_function proto" >&5
-if eval "test \"`echo '$''{'samba_cv_have_fcf_proto'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  
-  cat > conftest.$ac_ext <<EOF
-#line 3364 "configure"
-#include "confdefs.h"
-#include <stdio.h>
-#ifdef HAVE_READLINE_H
-#include <readline.h>
-#else
-#include <readline/readline.h>
-#endif
-int main() {
-filename_completion_function
-; return 0; }
-EOF
-if { (eval echo configure:3376: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  samba_cv_have_fcf_proto=yes
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  samba_cv_have_fcf_proto=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$samba_cv_have_fcf_proto" 1>&6
-  if test x"$samba_cv_have_fcf_proto" = x"yes"; then
-    cat >> confdefs.h <<\EOF
-#define HAVE_READLINE_FCF_PROTO 1
+ ;;
+    esac
+            if test x"$ac_cv_lib_socket_connect" = x"yes" || 
+       test x"$ac_cv_lib_inet_connect" = x"yes"; then
+        # ac_cv_func_connect=yes
+        # don't!  it would cause AC_CHECK_FUNC to succeed next time configure is run
+        cat >> confdefs.h <<\EOF
+#define HAVE_CONNECT 1
 EOF
 
-  fi
+    fi
 fi
 
-# The following test taken from the cvs sources
-# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
-# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
-# libsocket.so which has a bad implementation of gethostbyname (it
-# only looks in /etc/hosts), so we only look for -lsocket if we need
-# it.
-for ac_func in connect
+# Check if we have execl, if not we need to compile smbrun.
+for ac_func in execl
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3406: checking for $ac_func" >&5
+echo "configure:3851: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3411 "configure"
+#line 3856 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3430,7 +3875,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3454,228 +3899,131 @@ else
 fi
 done
 
-if test x"$ac_cv_func_connect" = x"no"; then
-    case "$LIBS" in
-    *-lnsl*) ;;
-    *) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6
-echo "configure:3462: checking for printf in -lnsl_s" >&5
-ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
+if test x"$ac_cv_func_execl" = x"no"; then
+    RUNPROG="bin/smbrun"
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-lnsl_s  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3470 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char printf();
-
-int main() {
-printf()
-; return 0; }
-EOF
-if { (eval echo configure:3481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
+    RUNPROG=""
 fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo nsl_s | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lnsl_s $LIBS"
 
-else
-  echo "$ac_t""no" 1>&6
-fi
- ;;
-    esac
-    case "$LIBS" in
-    *-lnsl*) ;;
-    *) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6
-echo "configure:3512: checking for printf in -lnsl" >&5
-ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+for ac_func in waitpid getcwd strdup strtoul strerror chown chmod chroot
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3912: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-lnsl  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3520 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 3917 "configure"
 #include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char printf();
+char $ac_func();
 
 int main() {
-printf()
-; return 0; }
-EOF
-if { (eval echo configure:3531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
 
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-lnsl $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
- ;;
-    esac
-    case "$LIBS" in
-    *-lsocket*) ;;
-    *) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:3562: checking for connect in -lsocket" >&5
-ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lsocket  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3570 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char connect();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
 
-int main() {
-connect()
 ; return 0; }
 EOF
-if { (eval echo configure:3581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  eval "ac_cv_func_$ac_func=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  eval "ac_cv_func_$ac_func=no"
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
-
 fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
+#define $ac_tr_func 1
 EOF
-
-  LIBS="-lsocket $LIBS"
-
 else
   echo "$ac_t""no" 1>&6
 fi
- ;;
-    esac
-    case "$LIBS" in
-    *-linet*) ;;
-    *) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6
-echo "configure:3612: checking for connect in -linet" >&5
-ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+done
+
+for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3967: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  ac_save_LIBS="$LIBS"
-LIBS="-linet  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3620 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 3972 "configure"
 #include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char connect();
+char $ac_func();
 
 int main() {
-connect()
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
 ; return 0; }
 EOF
-if { (eval echo configure:3631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
+  eval "ac_cv_func_$ac_func=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
+  eval "ac_cv_func_$ac_func=no"
 fi
 rm -f conftest*
-LIBS="$ac_save_LIBS"
-
 fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo inet | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
   cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
-  LIBS="-linet $LIBS"
-
+#define $ac_tr_func 1
+EOF
 else
   echo "$ac_t""no" 1>&6
 fi
- ;;
-    esac
-            if test x"$ac_cv_lib_socket_connect" = x"yes" || 
-       test x"$ac_cv_lib_inet_connect" = x"yes"; then
-        # ac_cv_func_connect=yes
-        # don't!  it would cause AC_CHECK_FUNC to succeed next time configure is run
-        cat >> confdefs.h <<\EOF
-#define HAVE_CONNECT 1
-EOF
-
-    fi
-fi
-
+done
 
-for ac_func in waitpid getcwd strdup strtoul strerror chown chmod chroot
+for ac_func in memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3674: checking for $ac_func" >&5
+echo "configure:4022: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3679 "configure"
+#line 4027 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3698,7 +4046,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3722,15 +4070,15 @@ else
 fi
 done
 
-for ac_func in fstat strchr utime utimes getrlimit fsync execl bzero memset
+for ac_func in strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3729: checking for $ac_func" >&5
+echo "configure:4077: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3734 "configure"
+#line 4082 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3753,7 +4101,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3757: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3777,15 +4125,15 @@ else
 fi
 done
 
-for ac_func in memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid
+for ac_func in initgroups select rdchk getgrnam getgrent pathconf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3784: checking for $ac_func" >&5
+echo "configure:4132: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3789 "configure"
+#line 4137 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3808,7 +4156,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3832,15 +4180,15 @@ else
 fi
 done
 
-for ac_func in strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent
+for ac_func in setpriv setgidx setuidx setgroups mktime rename ftruncate stat64 fstat64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3839: checking for $ac_func" >&5
+echo "configure:4187: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3844 "configure"
+#line 4192 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3863,7 +4211,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3887,15 +4235,15 @@ else
 fi
 done
 
-for ac_func in initgroups select rdchk getgrnam pathconf
+for ac_func in lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3894: checking for $ac_func" >&5
+echo "configure:4242: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3899 "configure"
+#line 4247 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3918,7 +4266,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3942,15 +4290,15 @@ else
 fi
 done
 
-for ac_func in setuidx setgroups mktime rename ftruncate stat64 fstat64 lstat64 fopen64
+for ac_func in fseek64 fseeko64 ftell64 ftello64 setluid yp_get_default_domain getpwanam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3949: checking for $ac_func" >&5
+echo "configure:4297: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3954 "configure"
+#line 4302 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3973,7 +4321,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:3977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3997,15 +4345,15 @@ else
 fi
 done
 
-for ac_func in atexit grantpt dup2 lseek64 ftruncate64
+for ac_func in srandom random srand rand setenv usleep mmap64 strcasecmp fcvt fcvtl
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4004: checking for $ac_func" >&5
+echo "configure:4352: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4009 "configure"
+#line 4357 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4028,7 +4376,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4052,15 +4400,17 @@ else
 fi
 done
 
-for ac_func in fseek64 ftell64 setluid yp_get_default_domain getpwanam
+
+# syscall() is needed for smbwrapper.
+for ac_func in syscall
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4059: checking for $ac_func" >&5
+echo "configure:4409: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4064 "configure"
+#line 4414 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4083,7 +4433,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4107,15 +4457,16 @@ else
 fi
 done
 
-for ac_func in srandom random srand rand setenv mmap64
+
+for ac_func in _dup _dup2 _opendir _readdir _seekdir _telldir _closedir
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4114: checking for $ac_func" >&5
+echo "configure:4465: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4119 "configure"
+#line 4470 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4138,7 +4489,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4162,16 +4513,15 @@ else
 fi
 done
 
-# syscall() is needed for smbwrapper.
-for ac_func in syscall
+for ac_func in __dup __dup2 __opendir __readdir __seekdir __telldir __closedir
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4170: checking for $ac_func" >&5
+echo "configure:4520: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4175 "configure"
+#line 4525 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4194,7 +4544,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4218,16 +4568,15 @@ else
 fi
 done
 
-
-for ac_func in _dup _dup2 _opendir _readdir _seekdir _telldir _closedir
+for ac_func in __getcwd _getcwd
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4226: checking for $ac_func" >&5
+echo "configure:4575: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4231 "configure"
+#line 4580 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4250,7 +4599,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4274,15 +4623,15 @@ else
 fi
 done
 
-for ac_func in __dup __dup2 __opendir __readdir __seekdir __telldir __closedir
+for ac_func in __xstat __fxstat __lxstat
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4281: checking for $ac_func" >&5
+echo "configure:4630: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4286 "configure"
+#line 4635 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4305,7 +4654,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4329,15 +4678,15 @@ else
 fi
 done
 
-for ac_func in __getcwd _getcwd
+for ac_func in _stat _lstat _fstat __stat __lstat __fstat
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4336: checking for $ac_func" >&5
+echo "configure:4685: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4341 "configure"
+#line 4690 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4360,7 +4709,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4384,15 +4733,15 @@ else
 fi
 done
 
-for ac_func in __xstat __fxstat __lxstat
+for ac_func in _acl __acl _facl __facl _open __open _chdir __chdir
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4391: checking for $ac_func" >&5
+echo "configure:4740: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4396 "configure"
+#line 4745 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4415,7 +4764,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4439,15 +4788,15 @@ else
 fi
 done
 
-for ac_func in _stat _lstat _fstat __stat __lstat __fstat
+for ac_func in _close __close _fchdir __fchdir _fcntl __fcntl
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4446: checking for $ac_func" >&5
+echo "configure:4795: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4451 "configure"
+#line 4800 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4470,7 +4819,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4474: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4494,15 +4843,15 @@ else
 fi
 done
 
-for ac_func in _acl __acl _facl __facl _open __open _chdir __chdir
+for ac_func in getdents _getdents __getdents _lseek __lseek _read __read
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4501: checking for $ac_func" >&5
+echo "configure:4850: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4506 "configure"
+#line 4855 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4525,7 +4874,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4878: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4549,15 +4898,15 @@ else
 fi
 done
 
-for ac_func in _close __close _fchdir __fchdir _fcntl __fcntl
+for ac_func in _write __write _fork __fork
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4556: checking for $ac_func" >&5
+echo "configure:4905: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4561 "configure"
+#line 4910 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4580,7 +4929,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4604,15 +4953,15 @@ else
 fi
 done
 
-for ac_func in getdents _getdents __getdents _lseek __lseek _read __read
+for ac_func in _stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4611: checking for $ac_func" >&5
+echo "configure:4960: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4616 "configure"
+#line 4965 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4635,7 +4984,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4659,15 +5008,15 @@ else
 fi
 done
 
-for ac_func in _write __write _fork __fork
+for ac_func in __sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4666: checking for $ac_func" >&5
+echo "configure:5015: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4671 "configure"
+#line 5020 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4690,7 +5039,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4714,15 +5063,15 @@ else
 fi
 done
 
-for ac_func in _stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64
+for ac_func in pread _pread __pread pread64 _pread64 __pread64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4721: checking for $ac_func" >&5
+echo "configure:5070: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4726 "configure"
+#line 5075 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4745,7 +5094,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5098: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4769,15 +5118,15 @@ else
 fi
 done
 
-for ac_func in __sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64
+for ac_func in pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4776: checking for $ac_func" >&5
+echo "configure:5125: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4781 "configure"
+#line 5130 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4800,7 +5149,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4804: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4824,15 +5173,15 @@ else
 fi
 done
 
-for ac_func in pread _pread __pread pread64 _pread64 __pread64
+for ac_func in open64 _open64 __open64 creat64
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4831: checking for $ac_func" >&5
+echo "configure:5180: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4836 "configure"
+#line 5185 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4855,7 +5204,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4879,15 +5228,179 @@ else
 fi
 done
 
-for ac_func in pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64
+
+#
+# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
+#
+
+if test x$ac_cv_func_stat64 = xno ; then
+  echo $ac_n "checking for stat64 in <sys/stat.h>""... $ac_c" 1>&6
+echo "configure:5239: checking for stat64 in <sys/stat.h>" >&5
+  cat > conftest.$ac_ext <<EOF
+#line 5241 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+int main() {
+struct stat64 st64; exit(stat64(".",&st64));
+; return 0; }
+EOF
+if { (eval echo configure:5253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_func_stat64=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+  echo "$ac_t""$ac_cv_func_stat64" 1>&6
+  if test x$ac_cv_func_stat64 = xyes ; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_STAT64 1
+EOF
+
+  fi
+fi
+
+if test x$ac_cv_func_lstat64 = xno ; then
+  echo $ac_n "checking for lstat64 in <sys/stat.h>""... $ac_c" 1>&6
+echo "configure:5272: checking for lstat64 in <sys/stat.h>" >&5
+  cat > conftest.$ac_ext <<EOF
+#line 5274 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+int main() {
+struct stat64 st64; exit(lstat64(".",&st64));
+; return 0; }
+EOF
+if { (eval echo configure:5286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_func_lstat64=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+  echo "$ac_t""$ac_cv_func_lstat64" 1>&6
+  if test x$ac_cv_func_lstat64 = xyes ; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_LSTAT64 1
+EOF
+
+  fi
+fi
+
+if test x$ac_cv_func_fstat64 = xno ; then
+  echo $ac_n "checking for fstat64 in <sys/stat.h>""... $ac_c" 1>&6
+echo "configure:5305: checking for fstat64 in <sys/stat.h>" >&5
+  cat > conftest.$ac_ext <<EOF
+#line 5307 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+
+int main() {
+struct stat64 st64; exit(fstat64(0,&st64));
+; return 0; }
+EOF
+if { (eval echo configure:5319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_func_fstat64=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+  echo "$ac_t""$ac_cv_func_fstat64" 1>&6
+  if test x$ac_cv_func_fstat64 = xyes ; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_FSTAT64 1
+EOF
+
+  fi
+fi
+
+#
+# If no strcasecmp, check for it in some known places
+# It is in -lresolv on ReliantUNIX and UnixWare
+#   -lresolve *must* follow -lnsl for name resolution to work properly
+#
+
+if test x$ac_cv_func_strcasecmp = xno ; then
+       echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6
+echo "configure:5344: checking for strcasecmp in -lresolv" >&5
+ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5352 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char strcasecmp();
+
+int main() {
+strcasecmp()
+; return 0; }
+EOF
+if { (eval echo configure:5363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBS="$LIBS -lresolv"
+               cat >> confdefs.h <<\EOF
+#define HAVE_STRCASECMP 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+#
+# Check for the functions putprpwnam, set_auth_parameters,
+# getspnam, bigcrypt and getprpwnam in -lsec and -lsecurity
+# Needed for OSF1 and HPUX.
+#
+
+case "$LIBS" in
+  *-lsecurity*) for ac_func in putprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4886: checking for $ac_func" >&5
+echo "configure:5399: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4891 "configure"
+#line 5404 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4910,7 +5423,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4933,16 +5446,63 @@ else
   echo "$ac_t""no" 1>&6
 fi
 done
+ ;;
+  *) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6
+echo "configure:5452: checking for putprpwnam in -lsecurity" >&5
+ac_lib_var=`echo security'_'putprpwnam | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsecurity  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5460 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char putprpwnam();
 
-for ac_func in open64 _open64 __open64 creat64
+int main() {
+putprpwnam()
+; return 0; }
+EOF
+if { (eval echo configure:5471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo security | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsecurity $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+     for ac_func in putprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4941: checking for $ac_func" >&5
+echo "configure:5501: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4946 "configure"
+#line 5506 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4965,7 +5525,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4989,23 +5549,19 @@ else
 fi
 done
 
-
-#
-# Check for the functions putprpwnam, set_auth_parameters,
-# getspnam, bigcrypt and getprpwnam in -lsec and -lsecurity
-# Needed for OSF1 and HPUX.
-#
+  ;;
+  esac
 
 case "$LIBS" in
-  *-lsecurity*) for ac_func in putprpwnam
+  *-lsec*) for ac_func in putprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5004: checking for $ac_func" >&5
+echo "configure:5560: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5009 "configure"
+#line 5565 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5028,7 +5584,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5052,16 +5608,16 @@ else
 fi
 done
  ;;
-  *) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:5057: checking for putprpwnam in -lsecurity" >&5
-ac_lib_var=`echo security'_'putprpwnam | sed 'y%./+-%__p_%'`
+  *) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6
+echo "configure:5613: checking for putprpwnam in -lsec" >&5
+ac_lib_var=`echo sec'_'putprpwnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lsecurity  $LIBS"
+LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5065 "configure"
+#line 5621 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5072,7 +5628,7 @@ int main() {
 putprpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5087,13 +5643,13 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo security | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo sec | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lsecurity $LIBS"
+  LIBS="-lsec $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
@@ -5102,12 +5658,12 @@ fi
      for ac_func in putprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5106: checking for $ac_func" >&5
+echo "configure:5662: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5111 "configure"
+#line 5667 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5130,7 +5686,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5157,16 +5713,17 @@ done
   ;;
   esac
 
+
 case "$LIBS" in
-  *-lsec*) for ac_func in putprpwnam
+  *-lsecurity*) for ac_func in set_auth_parameters
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5165: checking for $ac_func" >&5
+echo "configure:5722: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5170 "configure"
+#line 5727 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5189,7 +5746,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5213,27 +5770,27 @@ else
 fi
 done
  ;;
-  *) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:5218: checking for putprpwnam in -lsec" >&5
-ac_lib_var=`echo sec'_'putprpwnam | sed 'y%./+-%__p_%'`
+  *) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6
+echo "configure:5775: checking for set_auth_parameters in -lsecurity" >&5
+ac_lib_var=`echo security'_'set_auth_parameters | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lsec  $LIBS"
+LIBS="-lsecurity  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5226 "configure"
+#line 5783 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char putprpwnam();
+char set_auth_parameters();
 
 int main() {
-putprpwnam()
+set_auth_parameters()
 ; return 0; }
 EOF
-if { (eval echo configure:5237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5248,27 +5805,27 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo sec | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo security | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lsec $LIBS"
+  LIBS="-lsecurity $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
  
-     for ac_func in putprpwnam
+     for ac_func in set_auth_parameters
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5267: checking for $ac_func" >&5
+echo "configure:5824: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5272 "configure"
+#line 5829 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5291,7 +5848,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5318,17 +5875,16 @@ done
   ;;
   esac
 
-
 case "$LIBS" in
-  *-lsecurity*) for ac_func in set_auth_parameters
+  *-lsec*) for ac_func in set_auth_parameters
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5327: checking for $ac_func" >&5
+echo "configure:5883: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5332 "configure"
+#line 5888 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5351,7 +5907,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5375,16 +5931,16 @@ else
 fi
 done
  ;;
-  *) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6
-echo "configure:5380: checking for set_auth_parameters in -lsecurity" >&5
-ac_lib_var=`echo security'_'set_auth_parameters | sed 'y%./+-%__p_%'`
+  *) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6
+echo "configure:5936: checking for set_auth_parameters in -lsec" >&5
+ac_lib_var=`echo sec'_'set_auth_parameters | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lsecurity  $LIBS"
+LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5388 "configure"
+#line 5944 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5395,7 +5951,7 @@ int main() {
 set_auth_parameters()
 ; return 0; }
 EOF
-if { (eval echo configure:5399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5410,13 +5966,13 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo security | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo sec | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lsecurity $LIBS"
+  LIBS="-lsec $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
@@ -5425,12 +5981,12 @@ fi
      for ac_func in set_auth_parameters
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5429: checking for $ac_func" >&5
+echo "configure:5985: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5434 "configure"
+#line 5990 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5453,7 +6009,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5457: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5480,16 +6036,18 @@ done
   ;;
   esac
 
+
+# UnixWare 7.x has its getspnam in -lgen
 case "$LIBS" in
-  *-lsec*) for ac_func in set_auth_parameters
+  *-lgen*) for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5488: checking for $ac_func" >&5
+echo "configure:6046: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5493 "configure"
+#line 6051 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5512,7 +6070,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5536,27 +6094,27 @@ else
 fi
 done
  ;;
-  *) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6
-echo "configure:5541: checking for set_auth_parameters in -lsec" >&5
-ac_lib_var=`echo sec'_'set_auth_parameters | sed 'y%./+-%__p_%'`
+  *) echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6
+echo "configure:6099: checking for getspnam in -lgen" >&5
+ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
-LIBS="-lsec  $LIBS"
+LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5549 "configure"
+#line 6107 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
-char set_auth_parameters();
+char getspnam();
 
 int main() {
-set_auth_parameters()
+getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6118: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5571,27 +6129,27 @@ LIBS="$ac_save_LIBS"
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo sec | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    ac_tr_lib=HAVE_LIB`echo gen | sed -e 's/[^a-zA-Z0-9_]/_/g' \
     -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_lib 1
 EOF
 
-  LIBS="-lsec $LIBS"
+  LIBS="-lgen $LIBS"
 
 else
   echo "$ac_t""no" 1>&6
 fi
  
-     for ac_func in set_auth_parameters
+     for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5590: checking for $ac_func" >&5
+echo "configure:6148: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5595 "configure"
+#line 6153 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5614,7 +6172,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5646,12 +6204,12 @@ case "$LIBS" in
   *-lsecurity*) for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5650: checking for $ac_func" >&5
+echo "configure:6208: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5655 "configure"
+#line 6213 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5674,7 +6232,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5699,7 +6257,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for getspnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:5703: checking for getspnam in -lsecurity" >&5
+echo "configure:6261: checking for getspnam in -lsecurity" >&5
 ac_lib_var=`echo security'_'getspnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5707,7 +6265,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsecurity  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5711 "configure"
+#line 6269 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5718,7 +6276,7 @@ int main() {
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6280: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5748,12 +6306,12 @@ fi
      for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5752: checking for $ac_func" >&5
+echo "configure:6310: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5757 "configure"
+#line 6315 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5776,7 +6334,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5807,12 +6365,12 @@ case "$LIBS" in
   *-lsec*) for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5811: checking for $ac_func" >&5
+echo "configure:6369: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5816 "configure"
+#line 6374 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5835,7 +6393,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5860,7 +6418,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6
-echo "configure:5864: checking for getspnam in -lsec" >&5
+echo "configure:6422: checking for getspnam in -lsec" >&5
 ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -5868,7 +6426,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 5872 "configure"
+#line 6430 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -5879,7 +6437,7 @@ int main() {
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:5883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -5909,12 +6467,12 @@ fi
      for ac_func in getspnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5913: checking for $ac_func" >&5
+echo "configure:6471: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5918 "configure"
+#line 6476 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5937,7 +6495,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:5941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -5969,12 +6527,12 @@ case "$LIBS" in
   *-lsecurity*) for ac_func in bigcrypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5973: checking for $ac_func" >&5
+echo "configure:6531: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5978 "configure"
+#line 6536 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -5997,7 +6555,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6022,7 +6580,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for bigcrypt in -lsecurity""... $ac_c" 1>&6
-echo "configure:6026: checking for bigcrypt in -lsecurity" >&5
+echo "configure:6584: checking for bigcrypt in -lsecurity" >&5
 ac_lib_var=`echo security'_'bigcrypt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6030,7 +6588,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsecurity  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6034 "configure"
+#line 6592 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6041,7 +6599,7 @@ int main() {
 bigcrypt()
 ; return 0; }
 EOF
-if { (eval echo configure:6045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6071,12 +6629,12 @@ fi
      for ac_func in bigcrypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6075: checking for $ac_func" >&5
+echo "configure:6633: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6080 "configure"
+#line 6638 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6099,7 +6657,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6661: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6130,12 +6688,12 @@ case "$LIBS" in
   *-lsec*) for ac_func in bigcrypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6134: checking for $ac_func" >&5
+echo "configure:6692: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6139 "configure"
+#line 6697 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6158,7 +6716,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6183,7 +6741,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6
-echo "configure:6187: checking for bigcrypt in -lsec" >&5
+echo "configure:6745: checking for bigcrypt in -lsec" >&5
 ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6191,7 +6749,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6195 "configure"
+#line 6753 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6202,7 +6760,7 @@ int main() {
 bigcrypt()
 ; return 0; }
 EOF
-if { (eval echo configure:6206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6232,12 +6790,12 @@ fi
      for ac_func in bigcrypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6236: checking for $ac_func" >&5
+echo "configure:6794: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6241 "configure"
+#line 6799 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6260,7 +6818,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6292,12 +6850,12 @@ case "$LIBS" in
   *-lsecurity*) for ac_func in getprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6296: checking for $ac_func" >&5
+echo "configure:6854: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6301 "configure"
+#line 6859 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6320,7 +6878,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6324: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6345,7 +6903,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:6349: checking for getprpwnam in -lsecurity" >&5
+echo "configure:6907: checking for getprpwnam in -lsecurity" >&5
 ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6353,7 +6911,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsecurity  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6357 "configure"
+#line 6915 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6364,7 +6922,7 @@ int main() {
 getprpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:6368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6394,12 +6952,12 @@ fi
      for ac_func in getprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6398: checking for $ac_func" >&5
+echo "configure:6956: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6403 "configure"
+#line 6961 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6422,7 +6980,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6426: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6453,12 +7011,12 @@ case "$LIBS" in
   *-lsec*) for ac_func in getprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6457: checking for $ac_func" >&5
+echo "configure:7015: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6462 "configure"
+#line 7020 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6481,7 +7039,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6506,7 +7064,7 @@ fi
 done
  ;;
   *) echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:6510: checking for getprpwnam in -lsec" >&5
+echo "configure:7068: checking for getprpwnam in -lsec" >&5
 ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6514,7 +7072,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsec  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6518 "configure"
+#line 7076 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6525,7 +7083,7 @@ int main() {
 getprpwnam()
 ; return 0; }
 EOF
-if { (eval echo configure:6529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6555,12 +7113,12 @@ fi
      for ac_func in getprpwnam
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6559: checking for $ac_func" >&5
+echo "configure:7117: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6564 "configure"
+#line 7122 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6583,7 +7141,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:6587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7145: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6618,6 +7176,8 @@ done
 # these are the defaults, good for lots of systems
 HOST_OS="$host_os"
 LDSHFLAGS="-shared"
+PICFLAG=""
+SHLIBEXT="so"
 
 # and these are for particular systems
 case "$host_os" in
@@ -6643,6 +7203,13 @@ EOF
 #define IRIX 1
 EOF
 
+                       case "$host_os" in
+                       *irix6*) cat >> confdefs.h <<\EOF
+#define IRIX6 1
+EOF
+
+                       ;;
+                       esac
                        ATTEMPT_WRAP32_BUILD=yes
                ;;
                *aix*) cat >> confdefs.h <<\EOF
@@ -6652,7 +7219,14 @@ EOF
                *hpux*) cat >> confdefs.h <<\EOF
 #define HPUX 1
 EOF
-;;
+
+                       SHLIBEXT="sl"
+                       # Use special PIC flags for the native HP-UX compiler.
+                       if test $ac_cv_prog_cc_Ae = yes; then
+                               LDSHFLAGS="-b"
+                               PICFLAG="+z"
+                       fi
+               ;;
                *qnx*) cat >> confdefs.h <<\EOF
 #define QNX 1
 EOF
@@ -6672,7 +7246,7 @@ EOF
                *dgux*) # Extract the first word of "groff", so it can be a program name with args.
 set dummy groff; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6676: checking for $ac_word" >&5
+echo "configure:7250: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_ROFF'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6697,59 +7271,36 @@ else
   echo "$ac_t""no" 1>&6
 fi
 ;;
-               *sysv4.2*) echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6
-echo "configure:6702: checking for strcasecmp in -lresolv" >&5
-ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  ac_save_LIBS="$LIBS"
-LIBS="-lresolv  $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 6710 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char strcasecmp();
-
-int main() {
-strcasecmp()
-; return 0; }
+               *sysv4*)
+                       case "$host" in
+                               *-univel-*)     if  test "$GCC" != yes ; then
+                                                                       cat >> confdefs.h <<\EOF
+#define HAVE_MEMSET 1
 EOF
-if { (eval echo configure:6721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
 
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-    ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
-  cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
+                                                               fi
+                                                               LDSHFLAGS="-G"
+                               ;;
+                               *mips-sni-sysv4*) cat >> confdefs.h <<\EOF
+#define RELIANTUNIX 1
 EOF
-
-  LIBS="-lresolv $LIBS"
-
-else
-  echo "$ac_t""no" 1>&6
-fi
 ;;
+                       esac
+                       ;;
+               *sysv5*)
+                       if  test "$GCC" != yes ; then
+                               cat >> confdefs.h <<\EOF
+#define HAVE_MEMSET 1
+EOF
+
+                       fi
+                       LDSHFLAGS="-G"
+                       ;;
 esac
 
 # try to work out how to produce pic code with this compiler
-PICFLAG=""
 echo $ac_n "checking whether ${CC-cc} accepts -fpic""... $ac_c" 1>&6
-echo "configure:6753: checking whether ${CC-cc} accepts -fpic" >&5
+echo "configure:7304: checking whether ${CC-cc} accepts -fpic" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_fpic'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6765,11 +7316,11 @@ fi
 
 echo "$ac_t""$ac_cv_prog_cc_fpic" 1>&6
 if test $ac_cv_prog_cc_fpic = yes; then
-   PICFLAG="-fpic";
+    PICFLAG="-fpic";
 fi
 if test x$PICFLAG = x; then
   echo $ac_n "checking whether ${CC-cc} accepts -Kpic""... $ac_c" 1>&6
-echo "configure:6773: checking whether ${CC-cc} accepts -Kpic" >&5
+echo "configure:7324: checking whether ${CC-cc} accepts -Kpic" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_Kpic'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6786,11 +7337,11 @@ fi
 echo "$ac_t""$ac_cv_prog_cc_Kpic" 1>&6
   if test $ac_cv_prog_cc_Kpic = yes; then
     PICFLAG="-Kpic";
-  fi 
+  fi
 fi
 if test x$PICFLAG = x; then
   echo $ac_n "checking whether ${CC-cc} accepts -KPIC""... $ac_c" 1>&6
-echo "configure:6794: checking whether ${CC-cc} accepts -KPIC" >&5
+echo "configure:7345: checking whether ${CC-cc} accepts -KPIC" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_KPIC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6807,13 +7358,13 @@ fi
 echo "$ac_t""$ac_cv_prog_cc_KPIC" 1>&6
   if test $ac_cv_prog_cc_KPIC = yes; then
     PICFLAG="-KPIC";
-  fi 
+  fi
 fi
 
 ################
 
 echo $ac_n "checking for long long""... $ac_c" 1>&6
-echo "configure:6817: checking for long long" >&5
+echo "configure:7368: checking for long long" >&5
 if eval "test \"`echo '$''{'samba_cv_have_longlong'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6822,12 +7373,12 @@ if test "$cross_compiling" = yes; then
   samba_cv_have_longlong=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 6826 "configure"
+#line 7377 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }
 EOF
-if { (eval echo configure:6831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_have_longlong=yes
 else
@@ -6850,7 +7401,7 @@ EOF
 fi
 
 echo $ac_n "checking for 64 bit off_t""... $ac_c" 1>&6
-echo "configure:6854: checking for 64 bit off_t" >&5
+echo "configure:7405: checking for 64 bit off_t" >&5
 if eval "test \"`echo '$''{'samba_cv_SIZEOF_OFF_T'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6859,13 +7410,13 @@ if test "$cross_compiling" = yes; then
   samba_cv_SIZEOF_OFF_T=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 6863 "configure"
+#line 7414 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/stat.h>
 main() { exit((sizeof(off_t) == 8) ? 0 : 1); }
 EOF
-if { (eval echo configure:6869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_SIZEOF_OFF_T=yes
 else
@@ -6888,7 +7439,7 @@ EOF
 fi
 
 echo $ac_n "checking for off64_t""... $ac_c" 1>&6
-echo "configure:6892: checking for off64_t" >&5
+echo "configure:7443: checking for off64_t" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_OFF64_T'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6897,13 +7448,17 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_OFF64_T=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 6901 "configure"
+#line 7452 "configure"
 #include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <stdio.h>
 #include <sys/stat.h>
 main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }
 EOF
-if { (eval echo configure:6907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_OFF64_T=yes
 else
@@ -6926,7 +7481,7 @@ EOF
 fi
 
 echo $ac_n "checking for 64 bit ino_t""... $ac_c" 1>&6
-echo "configure:6930: checking for 64 bit ino_t" >&5
+echo "configure:7485: checking for 64 bit ino_t" >&5
 if eval "test \"`echo '$''{'samba_cv_SIZEOF_INO_T'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6935,13 +7490,13 @@ if test "$cross_compiling" = yes; then
   samba_cv_SIZEOF_INO_T=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 6939 "configure"
+#line 7494 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/stat.h>
 main() { exit((sizeof(ino_t) == 8) ? 0 : 1); }
 EOF
-if { (eval echo configure:6945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_SIZEOF_INO_T=yes
 else
@@ -6964,7 +7519,7 @@ EOF
 fi
 
 echo $ac_n "checking for ino64_t""... $ac_c" 1>&6
-echo "configure:6968: checking for ino64_t" >&5
+echo "configure:7523: checking for ino64_t" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_INO64_T'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6973,13 +7528,17 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_INO64_T=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 6977 "configure"
+#line 7532 "configure"
 #include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <stdio.h>
 #include <sys/stat.h>
 main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }
 EOF
-if { (eval echo configure:6983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7542: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_INO64_T=yes
 else
@@ -7001,8 +7560,47 @@ EOF
 
 fi
 
+echo $ac_n "checking for struct dirent64""... $ac_c" 1>&6
+echo "configure:7565: checking for struct dirent64" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_DIRENT64'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 7571 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <dirent.h>
+int main() {
+struct dirent64 de;
+; return 0; }
+EOF
+if { (eval echo configure:7583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_HAVE_STRUCT_DIRENT64=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_HAVE_STRUCT_DIRENT64=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_HAVE_STRUCT_DIRENT64" 1>&6
+if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_DIRENT64 1
+EOF
+
+fi
+
 echo $ac_n "checking for union semun""... $ac_c" 1>&6
-echo "configure:7006: checking for union semun" >&5
+echo "configure:7604: checking for union semun" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_UNION_SEMUN'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7011,7 +7609,7 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_UNION_SEMUN=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7015 "configure"
+#line 7613 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -7019,7 +7617,7 @@ else
 #include <sys/sem.h>
 main() { union semun ss; exit(0); }
 EOF
-if { (eval echo configure:7023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_UNION_SEMUN=yes
 else
@@ -7042,7 +7640,7 @@ EOF
 fi
 
 echo $ac_n "checking for unsigned char""... $ac_c" 1>&6
-echo "configure:7046: checking for unsigned char" >&5
+echo "configure:7644: checking for unsigned char" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_UNSIGNED_CHAR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7051,12 +7649,12 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_UNSIGNED_CHAR=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7055 "configure"
+#line 7653 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main() { char c; c=250; exit((c > 0)?0:1); }
 EOF
-if { (eval echo configure:7060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_UNSIGNED_CHAR=yes
 else
@@ -7079,13 +7677,13 @@ EOF
 fi
 
 echo $ac_n "checking for sin_len in sock""... $ac_c" 1>&6
-echo "configure:7083: checking for sin_len in sock" >&5
+echo "configure:7681: checking for sin_len in sock" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_SOCK_SIN_LEN'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7089 "configure"
+#line 7687 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -7094,7 +7692,7 @@ int main() {
 struct sockaddr_in sock; sock.sin_len = sizeof(sock);
 ; return 0; }
 EOF
-if { (eval echo configure:7098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_SOCK_SIN_LEN=yes
 else
@@ -7115,13 +7713,13 @@ EOF
 fi
 
 echo $ac_n "checking whether seekdir returns void""... $ac_c" 1>&6
-echo "configure:7119: checking whether seekdir returns void" >&5
+echo "configure:7717: checking whether seekdir returns void" >&5
 if eval "test \"`echo '$''{'samba_cv_SEEKDIR_RETURNS_VOID'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7125 "configure"
+#line 7723 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <dirent.h>
@@ -7130,7 +7728,7 @@ int main() {
 return 0;
 ; return 0; }
 EOF
-if { (eval echo configure:7134: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_SEEKDIR_RETURNS_VOID=yes
 else
@@ -7151,20 +7749,20 @@ EOF
 fi
 
 echo $ac_n "checking for __FILE__ macro""... $ac_c" 1>&6
-echo "configure:7155: checking for __FILE__ macro" >&5
+echo "configure:7753: checking for __FILE__ macro" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_FILE_MACRO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7161 "configure"
+#line 7759 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main() {
 printf("%s\n", __FILE__);
 ; return 0; }
 EOF
-if { (eval echo configure:7168: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7766: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_FILE_MACRO=yes
 else
@@ -7185,20 +7783,20 @@ EOF
 fi
 
 echo $ac_n "checking for __FUNCTION__ macro""... $ac_c" 1>&6
-echo "configure:7189: checking for __FUNCTION__ macro" >&5
+echo "configure:7787: checking for __FUNCTION__ macro" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_FUNCTION_MACRO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7195 "configure"
+#line 7793 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main() {
 printf("%s\n", __FUNCTION__);
 ; return 0; }
 EOF
-if { (eval echo configure:7202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7800: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_FUNCTION_MACRO=yes
 else
@@ -7219,7 +7817,7 @@ EOF
 fi
 
 echo $ac_n "checking if gettimeofday takes tz argument""... $ac_c" 1>&6
-echo "configure:7223: checking if gettimeofday takes tz argument" >&5
+echo "configure:7821: checking if gettimeofday takes tz argument" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_GETTIMEOFDAY_TZ'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7228,14 +7826,14 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_GETTIMEOFDAY_TZ=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7232 "configure"
+#line 7830 "configure"
 #include "confdefs.h"
 
 #include <sys/time.h>
 #include <unistd.h>
 main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}
 EOF
-if { (eval echo configure:7239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_GETTIMEOFDAY_TZ=yes
 else
@@ -7259,7 +7857,7 @@ fi
 
 
 echo $ac_n "checking for broken readdir""... $ac_c" 1>&6
-echo "configure:7263: checking for broken readdir" >&5
+echo "configure:7861: checking for broken readdir" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_READDIR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7268,7 +7866,7 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_BROKEN_READDIR=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7272 "configure"
+#line 7870 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <dirent.h>
@@ -7276,7 +7874,7 @@ main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
 if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
 di->d_name[0] == 0) exit(0); exit(1);} 
 EOF
-if { (eval echo configure:7280: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7878: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_BROKEN_READDIR=yes
 else
@@ -7299,13 +7897,13 @@ EOF
 fi
 
 echo $ac_n "checking for utimbuf""... $ac_c" 1>&6
-echo "configure:7303: checking for utimbuf" >&5
+echo "configure:7901: checking for utimbuf" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_UTIMBUF'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7309 "configure"
+#line 7907 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <utime.h>
@@ -7313,7 +7911,7 @@ int main() {
 struct utimbuf tbuf;  tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));
 ; return 0; }
 EOF
-if { (eval echo configure:7317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_UTIMBUF=yes
 else
@@ -7334,13 +7932,13 @@ EOF
 fi
 
 echo $ac_n "checking for kernel oplock type definitions""... $ac_c" 1>&6
-echo "configure:7338: checking for kernel oplock type definitions" >&5
+echo "configure:7936: checking for kernel oplock type definitions" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7344 "configure"
+#line 7942 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <fcntl.h>
@@ -7348,7 +7946,7 @@ int main() {
 oplock_stat_t t; t.os_state = OP_REVOKE; t.os_dev = 1; t.os_ino = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:7352: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_KERNEL_OPLOCKS=yes
 else
@@ -7369,7 +7967,7 @@ EOF
 fi
 
 echo $ac_n "checking for irix specific capabilities""... $ac_c" 1>&6
-echo "configure:7373: checking for irix specific capabilities" >&5
+echo "configure:7971: checking for irix specific capabilities" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7378,7 +7976,7 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7382 "configure"
+#line 7980 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/capability.h>
@@ -7393,7 +7991,7 @@ main() {
 }
 
 EOF
-if { (eval echo configure:7397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes
 else
@@ -7421,13 +8019,13 @@ fi
 #
 
 echo $ac_n "checking for int16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:7425: checking for int16 typedef included by rpc/rpc.h" >&5
+echo "configure:8023: checking for int16 typedef included by rpc/rpc.h" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_INT16_FROM_RPC_RPC_H'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7431 "configure"
+#line 8029 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if defined(HAVE_RPC_RPC_H)
@@ -7437,7 +8035,7 @@ int main() {
 int16 testvar;
 ; return 0; }
 EOF
-if { (eval echo configure:7441: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8039: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes
 else
@@ -7458,13 +8056,13 @@ EOF
 fi
 
 echo $ac_n "checking for uint16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:7462: checking for uint16 typedef included by rpc/rpc.h" >&5
+echo "configure:8060: checking for uint16 typedef included by rpc/rpc.h" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT16_FROM_RPC_RPC_H'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7468 "configure"
+#line 8066 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if defined(HAVE_RPC_RPC_H)
@@ -7474,7 +8072,7 @@ int main() {
 uint16 testvar;
 ; return 0; }
 EOF
-if { (eval echo configure:7478: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes
 else
@@ -7495,13 +8093,13 @@ EOF
 fi
 
 echo $ac_n "checking for int32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:7499: checking for int32 typedef included by rpc/rpc.h" >&5
+echo "configure:8097: checking for int32 typedef included by rpc/rpc.h" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_INT32_FROM_RPC_RPC_H'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7505 "configure"
+#line 8103 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if defined(HAVE_RPC_RPC_H)
@@ -7511,7 +8109,7 @@ int main() {
 int32 testvar;
 ; return 0; }
 EOF
-if { (eval echo configure:7515: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes
 else
@@ -7532,13 +8130,13 @@ EOF
 fi
 
 echo $ac_n "checking for uint32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:7536: checking for uint32 typedef included by rpc/rpc.h" >&5
+echo "configure:8134: checking for uint32 typedef included by rpc/rpc.h" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_UINT32_FROM_RPC_RPC_H'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 cat > conftest.$ac_ext <<EOF
-#line 7542 "configure"
+#line 8140 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if defined(HAVE_RPC_RPC_H)
@@ -7548,7 +8146,7 @@ int main() {
 uint32 testvar;
 ; return 0; }
 EOF
-if { (eval echo configure:7552: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8150: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes
 else
@@ -7568,17 +8166,59 @@ EOF
 
 fi
 
+
+echo $ac_n "checking for conflicting AUTH_ERROR define in rpc/rpc.h""... $ac_c" 1>&6
+echo "configure:8172: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 8178 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#ifdef HAVE_SYS_SECURITY_H
+#include <sys/security.h>
+#include <prot.h>
+#endif  /* HAVE_SYS_SECURITY_H */
+#if defined(HAVE_RPC_RPC_H)
+#include <rpc/rpc.h>
+#endif
+int main() {
+int testvar;
+; return 0; }
+EOF
+if { (eval echo configure:8192: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" 1>&6
+if test x"$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_RPC_AUTH_ERROR_CONFLICT 1
+EOF
+
+fi
+
 echo $ac_n "checking for test routines""... $ac_c" 1>&6
-echo "configure:7573: checking for test routines" >&5
+echo "configure:8213: checking for test routines" >&5
 if test "$cross_compiling" = yes; then
   echo "configure: warning: cannot run when cross-compiling" 1>&2
 else
   cat > conftest.$ac_ext <<EOF
-#line 7578 "configure"
+#line 8218 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/trivial.c"
 EOF
-if { (eval echo configure:7582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   echo "$ac_t""yes" 1>&6
 else
@@ -7592,7 +8232,7 @@ fi
 
 
 echo $ac_n "checking for ftruncate extend""... $ac_c" 1>&6
-echo "configure:7596: checking for ftruncate extend" >&5
+echo "configure:8236: checking for ftruncate extend" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_FTRUNCATE_EXTEND'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7601,11 +8241,11 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_FTRUNCATE_EXTEND=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7605 "configure"
+#line 8245 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/ftruncate.c"
 EOF
-if { (eval echo configure:7609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_FTRUNCATE_EXTEND=yes
 else
@@ -7628,7 +8268,7 @@ EOF
 fi
 
 echo $ac_n "checking for broken getgroups""... $ac_c" 1>&6
-echo "configure:7632: checking for broken getgroups" >&5
+echo "configure:8272: checking for broken getgroups" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_GETGROUPS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7637,11 +8277,11 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_BROKEN_GETGROUPS=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7641 "configure"
+#line 8281 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/getgroups.c"
 EOF
-if { (eval echo configure:7645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_BROKEN_GETGROUPS=yes
 else
@@ -7664,15 +8304,15 @@ EOF
 fi
 
 echo $ac_n "checking whether getpass should be replaced""... $ac_c" 1>&6
-echo "configure:7668: checking whether getpass should be replaced" >&5
+echo "configure:8308: checking whether getpass should be replaced" >&5
 if eval "test \"`echo '$''{'samba_cv_REPLACE_GETPASS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper"
 cat > conftest.$ac_ext <<EOF
-#line 7676 "configure"
+#line 8316 "configure"
 #include "confdefs.h"
 
 #define REPLACE_GETPASS 1
@@ -7685,7 +8325,7 @@ int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:7689: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8329: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_REPLACE_GETPASS=yes
 else
@@ -7707,8 +8347,45 @@ EOF
 
 fi
 
+echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
+echo "configure:8352: checking for working fnmatch" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_FNMATCH'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_FNMATCH=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8361 "configure"
+#include "confdefs.h"
+#include <fnmatch.h>
+main() { exit(fnmatch("*.o", "x.o", FNM_PATHNAME) == 0? 0: 1); }
+EOF
+if { (eval echo configure:8366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_HAVE_FNMATCH=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_HAVE_FNMATCH=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_FNMATCH" 1>&6
+if test x"$samba_cv_HAVE_FNMATCH" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_FNMATCH 1
+EOF
+
+fi
+
 echo $ac_n "checking for broken inet_ntoa""... $ac_c" 1>&6
-echo "configure:7712: checking for broken inet_ntoa" >&5
+echo "configure:8389: checking for broken inet_ntoa" >&5
 if eval "test \"`echo '$''{'samba_cv_REPLACE_INET_NTOA'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7717,238 +8394,383 @@ if test "$cross_compiling" = yes; then
   samba_cv_REPLACE_INET_NTOA=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7721 "configure"
+#line 8398 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
 #include <sys/types.h>
 #include <netinet/in.h>
+#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
+#endif
 main() { struct in_addr ip; ip.s_addr = 0x12345678;
 if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
     strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } 
 exit(1);}
 EOF
-if { (eval echo configure:7733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_REPLACE_INET_NTOA=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_REPLACE_INET_NTOA=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_REPLACE_INET_NTOA" 1>&6
+if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define REPLACE_INET_NTOA 1
+EOF
+
+fi
+
+echo $ac_n "checking for root""... $ac_c" 1>&6
+echo "configure:8435: checking for root" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_ROOT=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8444 "configure"
+#include "confdefs.h"
+main() { exit(getuid() != 0); }
+EOF
+if { (eval echo configure:8448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_HAVE_ROOT=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_HAVE_ROOT=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_ROOT" 1>&6
+if test x"$samba_cv_HAVE_ROOT" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_ROOT 1
+EOF
+
+else
+    echo "configure: warning: running as non-root will disable some tests" 1>&2
+fi
+
+##################
+# look for a method of finding the list of network interfaces
+iface=no;
+echo $ac_n "checking for iface AIX""... $ac_c" 1>&6
+echo "configure:8476: checking for iface AIX" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_AIX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_IFACE_AIX=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8485 "configure"
+#include "confdefs.h"
+
+#define HAVE_IFACE_AIX 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"
+EOF
+if { (eval echo configure:8493: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_HAVE_IFACE_AIX=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_HAVE_IFACE_AIX=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_IFACE_AIX" 1>&6
+if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then
+    iface=yes;cat >> confdefs.h <<\EOF
+#define HAVE_IFACE_AIX 1
+EOF
+
+fi
+
+if test $iface = no; then
+echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6
+echo "configure:8517: checking for iface ifconf" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFCONF'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_IFACE_IFCONF=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8526 "configure"
+#include "confdefs.h"
+
+#define HAVE_IFACE_IFCONF 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"
+EOF
+if { (eval echo configure:8534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_REPLACE_INET_NTOA=yes
+  samba_cv_HAVE_IFACE_IFCONF=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_REPLACE_INET_NTOA=no
+  samba_cv_HAVE_IFACE_IFCONF=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_REPLACE_INET_NTOA" 1>&6
-if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
-    cat >> confdefs.h <<\EOF
-#define REPLACE_INET_NTOA 1
+echo "$ac_t""$samba_cv_HAVE_IFACE_IFCONF" 1>&6
+if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then
+    iface=yes;cat >> confdefs.h <<\EOF
+#define HAVE_IFACE_IFCONF 1
 EOF
 
+fi
 fi
 
-echo $ac_n "checking for root""... $ac_c" 1>&6
-echo "configure:7756: checking for root" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then
+if test $iface = no; then
+echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6
+echo "configure:8559: checking for iface ifreq" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFREQ'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
-  samba_cv_HAVE_ROOT=cross
+  samba_cv_HAVE_IFACE_IFREQ=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7765 "configure"
+#line 8568 "configure"
 #include "confdefs.h"
-main() { exit(getuid() != 0); }
+
+#define HAVE_IFACE_IFREQ 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"
 EOF
-if { (eval echo configure:7769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_HAVE_ROOT=yes
+  samba_cv_HAVE_IFACE_IFREQ=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_HAVE_ROOT=no
+  samba_cv_HAVE_IFACE_IFREQ=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_HAVE_ROOT" 1>&6
-if test x"$samba_cv_HAVE_ROOT" = x"yes"; then
-    cat >> confdefs.h <<\EOF
-#define HAVE_ROOT 1
+echo "$ac_t""$samba_cv_HAVE_IFACE_IFREQ" 1>&6
+if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
+    iface=yes;cat >> confdefs.h <<\EOF
+#define HAVE_IFACE_IFREQ 1
 EOF
 
-else
-    echo "configure: warning: running as non-root will disable some tests" 1>&2
+fi
 fi
 
-netmask=no;
-echo $ac_n "checking for netmask ifconf""... $ac_c" 1>&6
-echo "configure:7795: checking for netmask ifconf" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_IFCONF'+set}'`\" = set"; then
+
+################################################
+# look for a method of setting the effective uid
+seteuid=no;
+if test $seteuid = no; then
+echo $ac_n "checking for setresuid""... $ac_c" 1>&6
+echo "configure:8605: checking for setresuid" >&5
+if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
-  samba_cv_HAVE_NETMASK_IFCONF=cross
+  samba_cv_USE_SETRESUID=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7804 "configure"
+#line 8614 "configure"
 #include "confdefs.h"
 
-#define HAVE_NETMASK_IFCONF 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"
+#define AUTOCONF_TEST 1
+#define USE_SETRESUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"
 EOF
-if { (eval echo configure:7811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_HAVE_NETMASK_IFCONF=yes
+  samba_cv_USE_SETRESUID=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_HAVE_NETMASK_IFCONF=no
+  samba_cv_USE_SETRESUID=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_HAVE_NETMASK_IFCONF" 1>&6
-if test x"$samba_cv_HAVE_NETMASK_IFCONF" = x"yes"; then
-    netmask=yes;cat >> confdefs.h <<\EOF
-#define HAVE_NETMASK_IFCONF 1
+echo "$ac_t""$samba_cv_USE_SETRESUID" 1>&6
+if test x"$samba_cv_USE_SETRESUID" = x"yes"; then
+    seteuid=yes;cat >> confdefs.h <<\EOF
+#define USE_SETRESUID 1
 EOF
 
 fi
+fi
+
 
-if test $netmask = no; then
-echo $ac_n "checking for netmask ifreq""... $ac_c" 1>&6
-echo "configure:7835: checking for netmask ifreq" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_IFREQ'+set}'`\" = set"; then
+if test $seteuid = no; then
+echo $ac_n "checking for setreuid""... $ac_c" 1>&6
+echo "configure:8648: checking for setreuid" >&5
+if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
-  samba_cv_HAVE_NETMASK_IFREQ=cross
+  samba_cv_USE_SETREUID=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7844 "configure"
+#line 8657 "configure"
 #include "confdefs.h"
 
-#define HAVE_NETMASK_IFREQ 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"
+#define AUTOCONF_TEST 1
+#define USE_SETREUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"
 EOF
-if { (eval echo configure:7851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_HAVE_NETMASK_IFREQ=yes
+  samba_cv_USE_SETREUID=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_HAVE_NETMASK_IFREQ=no
+  samba_cv_USE_SETREUID=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_HAVE_NETMASK_IFREQ" 1>&6
-if test x"$samba_cv_HAVE_NETMASK_IFREQ" = x"yes"; then
-    netmask=yes;cat >> confdefs.h <<\EOF
-#define HAVE_NETMASK_IFREQ 1
+echo "$ac_t""$samba_cv_USE_SETREUID" 1>&6
+if test x"$samba_cv_USE_SETREUID" = x"yes"; then
+    seteuid=yes;cat >> confdefs.h <<\EOF
+#define USE_SETREUID 1
 EOF
 
 fi
 fi
 
-if test $netmask = no; then
-echo $ac_n "checking for netmask AIX""... $ac_c" 1>&6
-echo "configure:7876: checking for netmask AIX" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_AIX'+set}'`\" = set"; then
+if test $seteuid = no; then
+echo $ac_n "checking for seteuid""... $ac_c" 1>&6
+echo "configure:8690: checking for seteuid" >&5
+if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
-  samba_cv_HAVE_NETMASK_AIX=cross
+  samba_cv_USE_SETEUID=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7885 "configure"
+#line 8699 "configure"
 #include "confdefs.h"
 
-#define HAVE_NETMASK_AIX 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"
+#define AUTOCONF_TEST 1
+#define USE_SETEUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"
 EOF
-if { (eval echo configure:7892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_HAVE_NETMASK_AIX=yes
+  samba_cv_USE_SETEUID=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_HAVE_NETMASK_AIX=no
+  samba_cv_USE_SETEUID=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_HAVE_NETMASK_AIX" 1>&6
-if test x"$samba_cv_HAVE_NETMASK_AIX" = x"yes"; then
-    netmask=yes;cat >> confdefs.h <<\EOF
-#define HAVE_NETMASK_AIX 1
+echo "$ac_t""$samba_cv_USE_SETEUID" 1>&6
+if test x"$samba_cv_USE_SETEUID" = x"yes"; then
+    seteuid=yes;cat >> confdefs.h <<\EOF
+#define USE_SETEUID 1
 EOF
 
 fi
 fi
 
-echo $ac_n "checking for trapdoor seteuid""... $ac_c" 1>&6
-echo "configure:7916: checking for trapdoor seteuid" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_TRAPDOOR_UID'+set}'`\" = set"; then
+if test $seteuid = no; then
+echo $ac_n "checking for setuidx""... $ac_c" 1>&6
+echo "configure:8732: checking for setuidx" >&5
+if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
-  :
+  samba_cv_USE_SETUIDX=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7925 "configure"
+#line 8741 "configure"
+#include "confdefs.h"
+
+#define AUTOCONF_TEST 1
+#define USE_SETUIDX 1
 #include "confdefs.h"
-#include "${srcdir-.}/tests/trapdoor.c"
+#include "${srcdir-.}/lib/util_sec.c"
 EOF
-if { (eval echo configure:7929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
-  samba_cv_HAVE_TRAPDOOR_UID=no
+  samba_cv_USE_SETUIDX=yes
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -fr conftest*
-  samba_cv_HAVE_TRAPDOOR_UID=yes
+  samba_cv_USE_SETUIDX=no
 fi
 rm -fr conftest*
 fi
 
 fi
 
-echo "$ac_t""$samba_cv_HAVE_TRAPDOOR_UID" 1>&6
-if test x"$samba_cv_HAVE_TRAPDOOR_UID" = x"yes"; then
-    cat >> confdefs.h <<\EOF
-#define HAVE_TRAPDOOR_UID 1
+echo "$ac_t""$samba_cv_USE_SETUIDX" 1>&6
+if test x"$samba_cv_USE_SETUIDX" = x"yes"; then
+    seteuid=yes;cat >> confdefs.h <<\EOF
+#define USE_SETUIDX 1
 EOF
 
 fi
+fi
+
 
 echo $ac_n "checking for shared mmap""... $ac_c" 1>&6
-echo "configure:7952: checking for shared mmap" >&5
+echo "configure:8774: checking for shared mmap" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_SHARED_MMAP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7957,11 +8779,11 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_SHARED_MMAP=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7961 "configure"
+#line 8783 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/shared_mmap.c"
 EOF
-if { (eval echo configure:7965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_SHARED_MMAP=yes
 else
@@ -7979,12 +8801,52 @@ echo "$ac_t""$samba_cv_HAVE_SHARED_MMAP" 1>&6
 if test x"$samba_cv_HAVE_SHARED_MMAP" = x"yes"; then
     cat >> confdefs.h <<\EOF
 #define HAVE_SHARED_MMAP 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6
+echo "configure:8814: checking for ftruncate needs root" >&5
+if eval "test \"`echo '$''{'samba_cv_FTRUNCATE_NEEDS_ROOT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_FTRUNCATE_NEEDS_ROOT=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8823 "configure"
+#include "confdefs.h"
+#include "${srcdir-.}/tests/ftruncroot.c"
+EOF
+if { (eval echo configure:8827: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_FTRUNCATE_NEEDS_ROOT=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_FTRUNCATE_NEEDS_ROOT=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_FTRUNCATE_NEEDS_ROOT" 1>&6
+if test x"$samba_cv_FTRUNCATE_NEEDS_ROOT" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define FTRUNCATE_NEEDS_ROOT 1
 EOF
 
 fi
 
 echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6
-echo "configure:7988: checking for fcntl locking" >&5
+echo "configure:8850: checking for fcntl locking" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_FCNTL_LOCK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7993,11 +8855,11 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_FCNTL_LOCK=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 7997 "configure"
+#line 8859 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/fcntl_lock.c"
 EOF
-if { (eval echo configure:8001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_FCNTL_LOCK=yes
 else
@@ -8019,19 +8881,60 @@ EOF
 
 fi
 
-echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6
-echo "configure:8024: checking for 64 bit fcntl locking" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then
+echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6
+echo "configure:8886: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_FCNTL64_LOCKS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
 if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 8895 "configure"
+#include "confdefs.h"
+#include "${srcdir-.}/tests/fcntl_lock64.c"
+EOF
+if { (eval echo configure:8899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" 1>&6
+if test x"$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_BROKEN_FCNTL64_LOCKS 1
+EOF
+
+
+else
+
+
+  echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6
+echo "configure:8924: checking for 64 bit fcntl locking" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+  if test "$cross_compiling" = yes; then
   samba_cv_HAVE_STRUCT_FLOCK64=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 8033 "configure"
+#line 8933 "configure"
 #include "confdefs.h"
 
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -8050,7 +8953,7 @@ exit(1);
 #endif
 }
 EOF
-if { (eval echo configure:8054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_STRUCT_FLOCK64=yes
 else
@@ -8065,15 +8968,17 @@ fi
 fi
 
 echo "$ac_t""$samba_cv_HAVE_STRUCT_FLOCK64" 1>&6
-if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
-    cat >> confdefs.h <<\EOF
+
+  if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
+      cat >> confdefs.h <<\EOF
 #define HAVE_STRUCT_FLOCK64 1
 EOF
 
+  fi
 fi
 
 echo $ac_n "checking for sysv ipc""... $ac_c" 1>&6
-echo "configure:8077: checking for sysv ipc" >&5
+echo "configure:8982: checking for sysv ipc" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_SYSV_IPC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8082,11 +8987,11 @@ if test "$cross_compiling" = yes; then
   samba_cv_HAVE_SYSV_IPC=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 8086 "configure"
+#line 8991 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/sysv_ipc.c"
 EOF
-if { (eval echo configure:8090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   samba_cv_HAVE_SYSV_IPC=yes
 else
@@ -8108,10 +9013,84 @@ EOF
 
 fi
 
+echo $ac_n "checking for a crypt that needs truncated salt""... $ac_c" 1>&6
+echo "configure:9018: checking for a crypt that needs truncated salt" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_TRUNCATED_SALT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+if test "$cross_compiling" = yes; then
+  samba_cv_HAVE_TRUNCATED_SALT=cross
+else
+  cat > conftest.$ac_ext <<EOF
+#line 9027 "configure"
+#include "confdefs.h"
+#include "${srcdir-.}/tests/crypttest.c"
+EOF
+if { (eval echo configure:9031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  samba_cv_HAVE_TRUNCATED_SALT=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  samba_cv_HAVE_TRUNCATED_SALT=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_TRUNCATED_SALT" 1>&6
+if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_TRUNCATED_SALT 1
+EOF
+
+fi
+
+echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6
+echo "configure:9054: checking for broken nisplus include files" >&5
+if eval "test \"`echo '$''{'samba_cv_BROKEN_NISPLUS_INCLUDE_FILES'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+cat > conftest.$ac_ext <<EOF
+#line 9060 "configure"
+#include "confdefs.h"
+#include <sys/acl.h>
+#if defined(HAVE_RPCSVC_NIS_H)
+#include <rpcsvc/nis.h>
+#endif
+int main() {
+return 0;
+; return 0; }
+EOF
+if { (eval echo configure:9070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" 1>&6
+if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
+    cat >> confdefs.h <<\EOF
+#define BROKEN_NISPLUS_INCLUDE_FILES 1
+EOF
+
+fi
+
+
 #################################################
 # check for smbwrapper support
 echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6
-echo "configure:8115: checking whether to use smbwrapper" >&5
+echo "configure:9094: checking whether to use smbwrapper" >&5
 # Check whether --with-smbwrapper or --without-smbwrapper was given.
 if test "${with_smbwrapper+set}" = set; then
   withval="$with_smbwrapper"
@@ -8122,12 +9101,12 @@ if test "${with_smbwrapper+set}" = set; then
 #define WITH_SMBWRAPPER 1
 EOF
 
-       WRAP="bin/smbsh bin/smbwrapper.so"
+       WRAP="bin/smbsh bin/smbwrapper.$SHLIBEXT"
 
        if test x$ATTEMPT_WRAP32_BUILD = x; then
                WRAP32=""
        else
-                       WRAP32=bin/smbwrapper.32.so
+                       WRAP32=bin/smbwrapper.32.$SHLIBEXT
        fi
 
 # Conditions under which smbwrapper should not be built.
@@ -8155,7 +9134,7 @@ fi
 #################################################
 # check for the AFS filesystem
 echo $ac_n "checking whether to use AFS""... $ac_c" 1>&6
-echo "configure:8159: checking whether to use AFS" >&5
+echo "configure:9138: checking whether to use AFS" >&5
 # Check whether --with-afs or --without-afs was given.
 if test "${with_afs+set}" = set; then
   withval="$with_afs"
@@ -8181,7 +9160,7 @@ fi
 #################################################
 # check for the DFS auth system
 echo $ac_n "checking whether to use DFS auth""... $ac_c" 1>&6
-echo "configure:8185: checking whether to use DFS auth" >&5
+echo "configure:9164: checking whether to use DFS auth" >&5
 # Check whether --with-dfs or --without-dfs was given.
 if test "${with_dfs+set}" = set; then
   withval="$with_dfs"
@@ -8206,7 +9185,7 @@ fi
 #################################################
 # check for Kerberos IV auth system
 echo $ac_n "checking whether to use Kerberos IV""... $ac_c" 1>&6
-echo "configure:8210: checking whether to use Kerberos IV" >&5
+echo "configure:9189: checking whether to use Kerberos IV" >&5
 # Check whether --with-krb4 or --without-krb4 was given.
 if test "${with_krb4+set}" = set; then
   withval="$with_krb4"
@@ -8216,7 +9195,7 @@ if test "${with_krb4+set}" = set; then
 EOF
 
     echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6
-echo "configure:8220: checking for dn_expand in -lresolv" >&5
+echo "configure:9199: checking for dn_expand in -lresolv" >&5
 ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -8224,7 +9203,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 8228 "configure"
+#line 9207 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8235,7 +9214,7 @@ int main() {
 dn_expand()
 ; return 0; }
 EOF
-if { (eval echo configure:8239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8271,10 +9250,31 @@ else
 fi
 
 
+#################################################
+# check for Kerberos 5 auth system
+echo $ac_n "checking whether to use Kerberos 5""... $ac_c" 1>&6
+echo "configure:9257: checking whether to use Kerberos 5" >&5
+# Check whether --with-krb5 or --without-krb5 was given.
+if test "${with_krb5+set}" = set; then
+  withval="$with_krb5"
+     echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define KRB5_AUTH 1
+EOF
+
+    LIBS="$LIBS -ldes425 -lkrb5 -lcrypto -lcom_err"
+    CFLAGS="$CFLAGS -I$withval/include"
+    LDFLAGS="$LDFLAGS -L$withval/lib"
+else
+  echo "$ac_t""no" 1>&6
+
+fi
+
+
 #################################################
 # check for automount support
 echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6
-echo "configure:8278: checking whether to use AUTOMOUNT" >&5
+echo "configure:9278: checking whether to use AUTOMOUNT" >&5
 # Check whether --with-automount or --without-automount was given.
 if test "${with_automount+set}" = set; then
   withval="$with_automount"
@@ -8299,7 +9299,7 @@ fi
 #################################################
 # check for smbmount support
 echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6
-echo "configure:8303: checking whether to use SMBMOUNT" >&5
+echo "configure:9303: checking whether to use SMBMOUNT" >&5
 # Check whether --with-smbmount or --without-smbmount was given.
 if test "${with_smbmount+set}" = set; then
   withval="$with_smbmount"
@@ -8324,10 +9324,38 @@ else
 fi
 
 
+
+#################################################
+# check for a PAM password database
+echo $ac_n "checking whether to use PAM password database""... $ac_c" 1>&6
+echo "configure:9332: checking whether to use PAM password database" >&5
+# Check whether --with-pam or --without-pam was given.
+if test "${with_pam+set}" = set; then
+  withval="$with_pam"
+   case "$withval" in
+  yes)
+    echo "$ac_t""yes" 1>&6
+    cat >> confdefs.h <<\EOF
+#define WITH_PAM 1
+EOF
+
+    LIBS="$LIBS -lpam"
+    ;;
+  *)
+    echo "$ac_t""no" 1>&6
+    ;;
+  esac 
+else
+  echo "$ac_t""no" 1>&6
+
+fi
+
+
+
 #################################################
 # check for a LDAP password database
 echo $ac_n "checking whether to use LDAP password database""... $ac_c" 1>&6
-echo "configure:8331: checking whether to use LDAP password database" >&5
+echo "configure:9359: checking whether to use LDAP password database" >&5
 # Check whether --with-ldap or --without-ldap was given.
 if test "${with_ldap+set}" = set; then
   withval="$with_ldap"
@@ -8338,7 +9366,7 @@ if test "${with_ldap+set}" = set; then
 #define WITH_LDAP 1
 EOF
 
-    LIBS="$LIBS -lldap -llber"
+    { echo "configure: error: LDAP password database not supported in this version." 1>&2; exit 1; }
     ;;
   *)
     echo "$ac_t""no" 1>&6
@@ -8353,7 +9381,7 @@ fi
 #################################################
 # check for a NISPLUS password database
 echo $ac_n "checking whether to use NISPLUS password database""... $ac_c" 1>&6
-echo "configure:8357: checking whether to use NISPLUS password database" >&5
+echo "configure:9385: checking whether to use NISPLUS password database" >&5
 # Check whether --with-nisplus or --without-nisplus was given.
 if test "${with_nisplus+set}" = set; then
   withval="$with_nisplus"
@@ -8378,7 +9406,7 @@ fi
 #################################################
 # check for a NISPLUS_HOME support 
 echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6
-echo "configure:8382: checking whether to use NISPLUS_HOME" >&5
+echo "configure:9410: checking whether to use NISPLUS_HOME" >&5
 # Check whether --with-nisplus-home or --without-nisplus-home was given.
 if test "${with_nisplus_home+set}" = set; then
   withval="$with_nisplus_home"
@@ -8403,7 +9431,7 @@ fi
 #################################################
 # check for the secure socket layer
 echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6
-echo "configure:8407: checking whether to use SSL" >&5
+echo "configure:9435: checking whether to use SSL" >&5
 # Check whether --with-ssl or --without-ssl was given.
 if test "${with_ssl+set}" = set; then
   withval="$with_ssl"
@@ -8414,30 +9442,39 @@ if test "${with_ssl+set}" = set; then
 #define WITH_SSL 1
 EOF
 
-    ;;
-  *)
-    echo "$ac_t""no" 1>&6
-    ;;
-  esac 
-else
-  echo "$ac_t""no" 1>&6
+    withval="/usr/local/ssl"     # default
 
-fi
+    if test "${with_sslinc+set}" = set; then
 
+       withval="$with_sslinc"
+       case "$withval" in
+       yes|no)
+         echo "configure: warning: --with-sslinc called without argument - will use default" 1>&w
+         CFLAGS="-I/usr/local/ssl/include $CFLAGS"
+         LIBS="-lssl -lcrypto $LIBS"
+         LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS"
+       ;;
+        * )
+          CFLAGS="-I${withval}/include $CFLAGS"
+         LIBS="-lssl -lcrypto $LIBS"
+         LDFLAGS="-L${withval}/lib $LDFLAGS"
+       ;;
+       esac
 
-#################################################
-# check for experimental mmap support
-echo $ac_n "checking whether to use MMAP""... $ac_c" 1>&6
-echo "configure:8432: checking whether to use MMAP" >&5
-# Check whether --with-mmap or --without-mmap was given.
-if test "${with_mmap+set}" = set; then
-  withval="$with_mmap"
-   case "$withval" in
-  yes)
-    echo "$ac_t""yes" 1>&6
-    cat >> confdefs.h <<\EOF
-#define WITH_MMAP 1
-EOF
+    else
+
+       CFLAGS="-I/usr/local/ssl/include $CFLAGS"   
+       LIBS="-lssl -lcrypto $LIBS"
+       LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
+
+    fi
+
+    if test ! -d ${withval}; then
+      echo "configure: error: called with --with-ssl, but ssl base directory ${withval} does not exist or is not a directory. Aborting config" 1>&2
+      exit 1
+    fi 
+
+    CFLAGS="-DHAVE_CRYPT_DECL $CFLAGS"  # Damn, SSLeay defines its own
 
     ;;
   *)
@@ -8453,7 +9490,7 @@ fi
 #################################################
 # check for syslog logging
 echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6
-echo "configure:8457: checking whether to use syslog logging" >&5
+echo "configure:9494: checking whether to use syslog logging" >&5
 # Check whether --with-syslog or --without-syslog was given.
 if test "${with_syslog+set}" = set; then
   withval="$with_syslog"
@@ -8478,7 +9515,7 @@ fi
 #################################################
 # check for a shared memory profiling support
 echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6
-echo "configure:8482: checking whether to use profiling" >&5
+echo "configure:9519: checking whether to use profiling" >&5
 # Check whether --with-profile or --without-profile was given.
 if test "${with_profile+set}" = set; then
   withval="$with_profile"
@@ -8504,7 +9541,7 @@ fi
 #################################################
 # check for experimental netatalk resource fork support
 echo $ac_n "checking whether to support netatalk""... $ac_c" 1>&6
-echo "configure:8508: checking whether to support netatalk" >&5
+echo "configure:9545: checking whether to support netatalk" >&5
 # Check whether --with-netatalk or --without-netatalk was given.
 if test "${with_netatalk+set}" = set; then
   withval="$with_netatalk"
@@ -8531,7 +9568,7 @@ fi
 QUOTAOBJS=noquotas.o
 
 echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6
-echo "configure:8535: checking whether to support disk-quotas" >&5
+echo "configure:9572: checking whether to support disk-quotas" >&5
 # Check whether --with-quotas or --without-quotas was given.
 if test "${with_quotas+set}" = set; then
   withval="$with_quotas"
@@ -8551,17 +9588,92 @@ fi
 
 
 
+#################################################
+# set private directory location
+# Check whether --with-privatedir or --without-privatedir was given.
+if test "${with_privatedir+set}" = set; then
+  withval="$with_privatedir"
+   case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody calls it without argument
+  #
+    echo "configure: warning: --with-privatedir called without argument - will use default" 1>&2
+    privatedir='${prefix}/private'
+  ;;
+  * )
+    privatedir="$withval"
+    ;;
+  esac
+  
+else
+  privatedir='${prefix}/private'
+   
+
+fi
+
+
+#################################################
+# set lock directory location
+# Check whether --with-lockdir or --without-lockdir was given.
+if test "${with_lockdir+set}" = set; then
+  withval="$with_lockdir"
+   case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody calls it without argument
+  #
+    echo "configure: warning: --with-lockdir called without argument - will use default" 1>&2
+    lockdir='$(VARDIR)/locks'
+  ;;
+  * )
+    lockdir="$withval"
+    ;;
+  esac
+  
+else
+  lockdir='$(VARDIR)/locks'
+   
+
+fi
+
+
+#################################################
+# set SWAT directory location
+# Check whether --with-swatdir or --without-swatdir was given.
+if test "${with_swatdir+set}" = set; then
+  withval="$with_swatdir"
+   case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody does it
+  #
+    echo "configure: warning: --with-swatdir called without argument - will use default" 1>&2
+    swatdir='${prefix}/swat'
+  ;;
+  * )
+    swatdir="$withval"
+    ;;
+  esac
+  
+else
+  swatdir='${prefix}/swat'
+   
+
+fi
+
+
 #################################################
 # these tests are taken from the GNU fileutils package
 echo "checking how to get filesystem space usage" 1>&6
-echo "configure:8558: checking how to get filesystem space usage" >&5
+echo "configure:9670: checking how to get filesystem space usage" >&5
 space=no
 
 # Test for statvfs64.
 if test $space = no; then
   # SVR4
   echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6
-echo "configure:8565: checking statvfs64 function (SVR4)" >&5
+echo "configure:9677: checking statvfs64 function (SVR4)" >&5
 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8569,18 +9681,21 @@ else
   fu_cv_sys_stat_statvfs64=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 8573 "configure"
+#line 9685 "configure"
 #include "confdefs.h"
 
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <sys/types.h>
 #include <sys/statvfs.h>
   main ()
   {
     struct statvfs64 fsd;
-    exit (statfs64 (".", &fsd));
+    exit (statvfs64 (".", &fsd));
   }
 EOF
-if { (eval echo configure:8584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statvfs64=yes
 else
@@ -8613,12 +9728,12 @@ fi
 if test $space = no; then
   # SVR4
   echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6
-echo "configure:8617: checking statvfs function (SVR4)" >&5
+echo "configure:9732: checking statvfs function (SVR4)" >&5
 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8622 "configure"
+#line 9737 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/statvfs.h>
@@ -8626,7 +9741,7 @@ int main() {
 struct statvfs fsd; statvfs (0, &fsd);
 ; return 0; }
 EOF
-if { (eval echo configure:8630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   fu_cv_sys_stat_statvfs=yes
 else
@@ -8651,7 +9766,7 @@ fi
 if test $space = no; then
   # DEC Alpha running OSF/1
   echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6
-echo "configure:8655: checking for 3-argument statfs function (DEC OSF/1)" >&5
+echo "configure:9770: checking for 3-argument statfs function (DEC OSF/1)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8659,7 +9774,7 @@ else
   fu_cv_sys_stat_statfs3_osf1=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8663 "configure"
+#line 9778 "configure"
 #include "confdefs.h"
 
 #include <sys/param.h>
@@ -8672,7 +9787,7 @@ else
     exit (statfs (".", &fsd, sizeof (struct statfs)));
   }
 EOF
-if { (eval echo configure:8676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs3_osf1=yes
 else
@@ -8699,7 +9814,7 @@ fi
 if test $space = no; then
 # AIX
   echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6
-echo "configure:8703: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
+echo "configure:9818: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8707,7 +9822,7 @@ else
   fu_cv_sys_stat_statfs2_bsize=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8711 "configure"
+#line 9826 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_PARAM_H
@@ -8726,7 +9841,7 @@ else
   exit (statfs (".", &fsd));
   }
 EOF
-if { (eval echo configure:8730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9845: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs2_bsize=yes
 else
@@ -8753,7 +9868,7 @@ fi
 if test $space = no; then
 # SVR3
   echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6
-echo "configure:8757: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
+echo "configure:9872: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8761,7 +9876,7 @@ else
   fu_cv_sys_stat_statfs4=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8765 "configure"
+#line 9880 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/statfs.h>
@@ -8771,7 +9886,7 @@ else
   exit (statfs (".", &fsd, sizeof fsd, 0));
   }
 EOF
-if { (eval echo configure:8775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs4=yes
 else
@@ -8798,7 +9913,7 @@ fi
 if test $space = no; then
 # 4.4BSD and NetBSD
   echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6
-echo "configure:8802: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
+echo "configure:9917: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8806,7 +9921,7 @@ else
   fu_cv_sys_stat_statfs2_fsize=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8810 "configure"
+#line 9925 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
@@ -8822,7 +9937,7 @@ else
   exit (statfs (".", &fsd));
   }
 EOF
-if { (eval echo configure:8826: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs2_fsize=yes
 else
@@ -8849,7 +9964,7 @@ fi
 if test $space = no; then
   # Ultrix
   echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6
-echo "configure:8853: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
+echo "configure:9968: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8857,7 +9972,7 @@ else
   fu_cv_sys_stat_fs_data=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 8861 "configure"
+#line 9976 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
@@ -8877,7 +9992,7 @@ else
   exit (statfs (".", &fsd) != 1);
   }
 EOF
-if { (eval echo configure:8881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_fs_data=yes
 else
@@ -8901,16 +10016,59 @@ EOF
   fi
 fi
 
+#
+# As a gating factor for large file support, in order to
+# use <4GB files we must have the following minimal support
+# available.
+# long long, and a 64 bit off_t or off64_t.
+# If we don't have all of these then disable large
+# file support.
+#
+echo "checking if large file support can be enabled"
+cat > conftest.$ac_ext <<EOF
+#line 10030 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
+#include <sys/types.h>
+#else
+__COMPILE_ERROR_
+#endif
+
+int main() {
+int i
+; return 0; }
+EOF
+if { (eval echo configure:10043: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=no
+fi
+rm -f conftest*
+if test x"$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT" = x"yes"; then
+    echo "yes"
+    cat >> confdefs.h <<\EOF
+#define HAVE_EXPLICIT_LARGEFILE_SUPPORT 1
+EOF
+
+else
+    echo "no"
+fi
+
 echo "checking configure summary"
 if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 8910 "configure"
+#line 10068 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/summary.c"
 EOF
-if { (eval echo configure:8914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   echo "configure OK";
 else
@@ -9058,16 +10216,19 @@ s%@oldincludedir@%$oldincludedir%g
 s%@infodir@%$infodir%g
 s%@mandir@%$mandir%g
 s%@SHELL@%$SHELL%g
+s%@RUNPROG@%$RUNPROG%g
 s%@MPROGS@%$MPROGS%g
 s%@LDSHFLAGS@%$LDSHFLAGS%g
 s%@HOST_OS@%$HOST_OS%g
 s%@WRAP@%$WRAP%g
 s%@WRAP32@%$WRAP32%g
 s%@PICFLAG@%$PICFLAG%g
+s%@SHLIBEXT@%$SHLIBEXT%g
 s%@CC@%$CC%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@AWK@%$AWK%g
+s%@BROKEN_CC@%$BROKEN_CC%g
 s%@host@%$host%g
 s%@host_alias@%$host_alias%g
 s%@host_cpu@%$host_cpu%g
@@ -9090,6 +10251,9 @@ s%@CPP@%$CPP%g
 s%@LIBOBJS@%$LIBOBJS%g
 s%@ROFF@%$ROFF%g
 s%@QUOTAOBJS@%$QUOTAOBJS%g
+s%@privatedir@%$privatedir%g
+s%@lockdir@%$lockdir%g
+s%@swatdir@%$swatdir%g
 s%@builddir@%$builddir%g
 
 CEOF
index 5b7785101c8b1b31ebe12e0bc638e271ee56850a..91fc5021d98ef42301b430d5c616b2967ec2dac4 100755 (executable)
@@ -1,3 +1,3 @@
 #!/bin/sh
-CFLAGS="-g -O2 -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"; export CFLAGS
+export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align"
 ./configure
index fe3e734bbf3ba66eccfe99cb701ae37c30392dfa..d6f9a57db335747a9fef917a399a7a5f630a1ca6 100644 (file)
@@ -6,12 +6,14 @@ AC_PREFIX_DEFAULT(/usr/local/samba)
 
 dnl Unique-to-Samba variables we'll be playing with.
 AC_SUBST(SHELL)
+AC_SUBST(RUNPROG)
 AC_SUBST(MPROGS)
 AC_SUBST(LDSHFLAGS)
 AC_SUBST(HOST_OS)
 AC_SUBST(WRAP)
 AC_SUBST(WRAP32)
 AC_SUBST(PICFLAG)
+AC_SUBST(SHLIBEXT)
 
 # compile with optimisation and without debugging by default
 CFLAGS=${CFLAGS-"-O"}
@@ -21,6 +23,25 @@ AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_AWK
 
+dnl Check if C compiler understands -c and -o at the same time
+AC_PROG_CC_C_O
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+      BROKEN_CC=
+else
+      BROKEN_CC=#
+fi
+AC_SUBST(BROKEN_CC)
+
+dnl Check if the C compiler understands volatile (it should, being ANSI).
+AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [
+    AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0],
+       samba_cv_volatile=yes,samba_cv_volatile=no)])
+if test x"$samba_cv_volatile" = x"yes"; then
+   AC_DEFINE(HAVE_VOLATILE)
+fi
+
+
+
 AC_CANONICAL_SYSTEM
 AC_VALIDATE_CACHE_SYSTEM_TYPE
 SAMBA_MAINTAINER_MODE
@@ -36,14 +57,114 @@ case "$host_os" in
       if test $ac_cv_prog_cc_Ae = yes; then
         CPPFLAGS="$CPPFLAGS -Ae"
       fi
+#
+# Defines needed for HPUX support.
+# HPUX has bigcrypt but (sometimes?) doesn't use it for
+# password hashing - hence the USE_BOTH_CRYPT_CALLS define.
+#
+      case `uname -r` in
+                       *9*|*10*)
+                               CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
+                               AC_DEFINE(USE_BOTH_CRYPT_CALLS)
+                               ;;
+                       *11*)
+                               CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
+                               AC_DEFINE(USE_BOTH_CRYPT_CALLS)
+                               ;;
+      esac
       ;;
 #
-# AIX4.x is *so* broken. It doesn't even admit to having large
+# AIX4.x doesn't even admit to having large
 # files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
 #
     *aix4*)
+         AC_MSG_RESULT([enabling large file support])
       CPPFLAGS="$CPPFLAGS -D_LARGE_FILES"
       ;;    
+#
+# Defines needed for Solaris 2.6/2.7 aka 7.0 to make it admit
+# to the existance of large files..
+# Note that -D_LARGEFILE64_SOURCE is different from the Sun
+# recommendations on large file support, however it makes the
+# compile work using gcc 2.7 and 2.8, whereas using the Sun
+# recommendation makes the compile fail on gcc2.7. JRA.
+#
+       *solaris*)
+               case `uname -r` in
+                       5.6*|5.7*)
+                       AC_MSG_RESULT([enabling large file support])
+                       if test "$ac_cv_prog_gcc" = yes; then
+                               ${CC-cc} -v >conftest.c 2>&1
+                               ac_cv_gcc_compiler_version_number=`grep 'gcc version' conftest.c`
+                               rm -fr conftest.c
+                               case "$ac_cv_gcc_compiler_version_number" in
+                                       *"gcc version 2.6"*|*"gcc version 2.7"*)
+                                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
+                                               ;;
+                                       *)
+                                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+                                               ;;
+                               esac
+                       else
+                               CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+                       fi
+                       ;;
+               esac
+               ;;
+#
+# Tests needed for SINIX large file support.
+#
+    *sysv4*)
+      if test $host = mips-sni-sysv4 ; then
+        AC_MSG_CHECKING([for LFS support])
+        old_CPPFLAGS="$CPPFLAGS"
+        CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
+        AC_TRY_RUN([
+#include <unistd.h>
+main () {
+#if _LFS64_LARGEFILE == 1
+exit(0);
+#else
+exit(1);
+#endif
+}], [SINIX_LFS_SUPPORT=yes], [SINIX_LFS_SUPPORT=no], [SINIX_LFS_SUPPORT=cross])
+        CPPFLAGS="$old_CPPFLAGS"
+        if test x$SINIX_LFS_SUPPORT = xyes ; then
+          CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
+          CFLAGS="`getconf LFS64_CFLAGS` $CFLAGS"
+          LDFLAGS="`getconf LFS64_LDFLAGS` $LDFLAGS"
+          LIBS="`getconf LFS64_LIBS` $LIBS"
+        fi
+      AC_MSG_RESULT([$SINIX_LFS_SUPPORT])
+      fi
+    ;;
+
+#
+# Tests needed for glibc 2.1 large file support.
+# 
+       *linux*)
+               AC_MSG_RESULT([disabling large file support for glibc2.1 on Linux])     
+               ;;
+    *hurd*)
+        AC_MSG_CHECKING([for LFS support])
+        old_CPPFLAGS="$CPPFLAGS"
+        CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
+        AC_TRY_RUN([
+#include <unistd.h>
+main () {
+#if _LFS64_LARGEFILE == 1
+exit(0);
+#else
+exit(1);
+#endif
+}], [GLIBC_LFS_SUPPORT=yes], [GLIBC_LFS_SUPPORT=no], [GLIBC_LFS_SUPPORT=cross])
+        CPPFLAGS="$old_CPPFLAGS"
+        if test x$GLIBC_LFS_SUPPORT = xyes ; then
+          CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
+        fi
+      AC_MSG_RESULT([$GLIBC_LFS_SUPPORT])
+    ;;
+
 esac
 
 AC_INLINE
@@ -51,18 +172,31 @@ AC_HEADER_STDC
 AC_HEADER_DIRENT
 AC_HEADER_TIME
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
-AC_CHECK_HEADERS(sys/param.h ctype.h )
-AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/route.h net/if.h)
-AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h sys/param.h ctype.h )
-AC_CHECK_HEADERS(sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h sys/mman.h)
-AC_CHECK_HEADERS(sys/filio.h string.h strings.h stdlib.h sys/socket.h sys/un.h)
-AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h)
-AC_CHECK_HEADERS(sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
-AC_CHECK_HEADERS(shadow.h netinet/tcp.h sys/security.h security/pam_appl.h)
+AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
+AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h)
+AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
+AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h)
+AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h)
+AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
+AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
+#
+# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
+# This causes configure to fail to detect it. Check for shadow separately on HPUX.
+#
+case "$host_os" in
+    *hpux*)
+               AC_TRY_COMPILE([#include <shadow.h>],[struct spwd testme],
+                       ac_cv_header_shadow_h=yes,ac_cv_header_shadow_h=no)
+               if test x"$ac_cv_header_shadow_h" = x"yes"; then
+                  AC_DEFINE(HAVE_SHADOW_H)
+               fi
+       ;;
+esac
+AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
+AC_CHECK_HEADERS(sys/security.h security/pam_appl.h)
 AC_CHECK_HEADERS(stropts.h poll.h readline.h history.h readline/readline.h)
 AC_CHECK_HEADERS(readline/history.h sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h mysql.h)
+AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
 
 AC_CHECK_SIZEOF(int,cross)
 AC_CHECK_SIZEOF(long,cross)
@@ -86,9 +220,28 @@ AC_CHECK_TYPE(loff_t,off_t)
 AC_CHECK_TYPE(offset_t,loff_t)
 AC_CHECK_TYPE(ssize_t, int)
 
+# we need libcups for CUPS support...
+AC_CHECK_LIB(cups,httpConnect)
+
+# we need libdl for PAM and the new VFS code
+AC_CHECK_LIB(dl,main)
+
+AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [
+    AC_TRY_COMPILE([
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <signal.h>],[sig_atomic_t i = 0],
+       samba_cv_sig_atomic_t=yes,samba_cv_sig_atomic_t=no)])
+if test x"$samba_cv_sig_atomic_t" = x"yes"; then
+   AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE)
+fi
+
 AC_CACHE_CHECK([for errno in errno.h],samba_cv_errno, [
     AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
-       samba_cv_errno=yes,samba_cv_have_errno_decl=no)])
+       samba_cv_errno=yes,samba_cv_have_errno=no)])
 if test x"$samba_cv_errno" = x"yes"; then
    AC_DEFINE(HAVE_ERRNO_DECL)
 fi
@@ -102,11 +255,11 @@ if test x"$samba_cv_have_setresuid_decl" = x"yes"; then
 fi
 
 # stupid glibc has the functions but no declaration. grrrr.
-AC_CACHE_CHECK([for crypt declaration],samba_cv_have_crypt_decl,[
-    AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)crypt],
-        samba_cv_have_crypt_decl=yes,samba_cv_have_crypt_decl=no)])
-if test x"$samba_cv_have_crypt_decl" = x"yes"; then
-    AC_DEFINE(HAVE_CRYPT_DECL)
+AC_CACHE_CHECK([for setresgid declaration],samba_cv_have_setresgid_decl,[
+    AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)setresgid],
+        samba_cv_have_setresgid_decl=yes,samba_cv_have_setresgid_decl=no)])
+if test x"$samba_cv_have_setresgid_decl" = x"yes"; then
+    AC_DEFINE(HAVE_SETRESGID_DECL)
 fi
 
 # and glibc has setresuid under linux but the function does
@@ -119,6 +272,17 @@ if test x"$samba_cv_have_setresuid" = x"yes"; then
     AC_DEFINE(HAVE_SETRESUID)
 fi
 
+# Do the same check for setresguid...
+#
+AC_CACHE_CHECK([for real setresgid],samba_cv_have_setresgid,[
+    AC_TRY_RUN([#include <unistd.h>
+#include <errno.h>
+main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}],
+       samba_cv_have_setresgid=yes,samba_cv_have_setresgid=no,samba_cv_have_setresgid=cross)])
+if test x"$samba_cv_have_setresgid" = x"yes"; then
+    AC_DEFINE(HAVE_SETRESGID)
+fi
+
 AC_FUNC_MEMCMP
 
 ###############################################
@@ -131,37 +295,13 @@ fi
 
 
 ###############################################
-# test for where we get pam_authenticate() from
-# might need libdl for this to work
-if test "$ac_cv_header_security_pam_appl_h" = "yes"; then
-  AC_CHECK_LIB(dl,main)
-fi
-AC_CHECK_FUNCS(pam_authenticate)
-if test x"$ac_cv_func_pam_authenticate" = x"no"; then
-    AC_CHECK_LIB(pam, pam_authenticate, [LIBS="$LIBS -lpam"
-       AC_DEFINE(HAVE_PAM_AUTHENTICATE)])
-fi
-
-###############################################
-# readline requires some curses routines
+# test for where we get readline() from
 if test "$ac_cv_header_readline_h" = "yes" ||
    test "$ac_cv_header_readline_readline_h" = "yes"; then
-  AC_CHECK_FUNCS(tputs)
-  AC_CHECK_LIB(curses, tputs, [LIBS="$LIBS -lcurses"])
   AC_CHECK_LIB(readline,readline)
-  AC_CACHE_CHECK([for filename_completion_function proto],samba_cv_have_fcf_proto,[
-  AC_TRY_COMPILE([#include <stdio.h>
-#ifdef HAVE_READLINE_H
-#include <readline.h>
-#else
-#include <readline/readline.h>
-#endif],[filename_completion_function],
-  samba_cv_have_fcf_proto=yes,samba_cv_have_fcf_proto=no)])
-  if test x"$samba_cv_have_fcf_proto" = x"yes"; then
-    AC_DEFINE(HAVE_READLINE_FCF_PROTO)
-  fi
 fi
 
+
 # The following test taken from the cvs sources
 # If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
 # The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
@@ -196,16 +336,24 @@ if test x"$ac_cv_func_connect" = x"no"; then
     fi
 fi
 
+# Check if we have execl, if not we need to compile smbrun.
+AC_CHECK_FUNCS(execl)
+if test x"$ac_cv_func_execl" = x"no"; then
+    RUNPROG="bin/smbrun"
+else
+    RUNPROG=""
+fi
 
 AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown chmod chroot)
-AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync execl bzero memset)
+AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset)
 AC_CHECK_FUNCS(memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid)
 AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent)
-AC_CHECK_FUNCS(initgroups select rdchk getgrnam pathconf)
-AC_CHECK_FUNCS(setuidx setgroups mktime rename ftruncate stat64 fstat64 lstat64 fopen64)
-AC_CHECK_FUNCS(atexit grantpt dup2 lseek64 ftruncate64)
-AC_CHECK_FUNCS(fseek64 ftell64 setluid yp_get_default_domain getpwanam)
-AC_CHECK_FUNCS(srandom random srand rand setenv mmap64)
+AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf)
+AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups mktime rename ftruncate stat64 fstat64)
+AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
+AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid yp_get_default_domain getpwanam)
+AC_CHECK_FUNCS(srandom random srand rand setenv usleep mmap64 strcasecmp fcvt fcvtl)
+
 # syscall() is needed for smbwrapper.
 AC_CHECK_FUNCS(syscall)
 
@@ -224,6 +372,63 @@ AC_CHECK_FUNCS(pread _pread __pread pread64 _pread64 __pread64)
 AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64)
 AC_CHECK_FUNCS(open64 _open64 __open64 creat64)
 
+#
+# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
+#
+
+if test x$ac_cv_func_stat64 = xno ; then
+  AC_MSG_CHECKING([for stat64 in <sys/stat.h>])
+  AC_TRY_LINK([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+], [struct stat64 st64; exit(stat64(".",&st64));], [ac_cv_func_stat64=yes])
+  AC_MSG_RESULT([$ac_cv_func_stat64])
+  if test x$ac_cv_func_stat64 = xyes ; then
+    AC_DEFINE(HAVE_STAT64)
+  fi
+fi
+
+if test x$ac_cv_func_lstat64 = xno ; then
+  AC_MSG_CHECKING([for lstat64 in <sys/stat.h>])
+  AC_TRY_LINK([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+], [struct stat64 st64; exit(lstat64(".",&st64));], [ac_cv_func_lstat64=yes])
+  AC_MSG_RESULT([$ac_cv_func_lstat64])
+  if test x$ac_cv_func_lstat64 = xyes ; then
+    AC_DEFINE(HAVE_LSTAT64)
+  fi
+fi
+
+if test x$ac_cv_func_fstat64 = xno ; then
+  AC_MSG_CHECKING([for fstat64 in <sys/stat.h>])
+  AC_TRY_LINK([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+], [struct stat64 st64; exit(fstat64(0,&st64));], [ac_cv_func_fstat64=yes])
+  AC_MSG_RESULT([$ac_cv_func_fstat64])
+  if test x$ac_cv_func_fstat64 = xyes ; then
+    AC_DEFINE(HAVE_FSTAT64)
+  fi
+fi
+
+#
+# If no strcasecmp, check for it in some known places
+# It is in -lresolv on ReliantUNIX and UnixWare
+#   -lresolve *must* follow -lnsl for name resolution to work properly
+#
+
+if test x$ac_cv_func_strcasecmp = xno ; then
+       AC_CHECK_LIB(resolv,strcasecmp,[LIBS="$LIBS -lresolv"]
+               AC_DEFINE(HAVE_STRCASECMP))
+fi
+
 #
 # Check for the functions putprpwnam, set_auth_parameters,
 # getspnam, bigcrypt and getprpwnam in -lsec and -lsecurity
@@ -236,6 +441,9 @@ AC_LIBTESTFUNC(sec, putprpwnam)
 AC_LIBTESTFUNC(security, set_auth_parameters)
 AC_LIBTESTFUNC(sec, set_auth_parameters)
 
+# UnixWare 7.x has its getspnam in -lgen
+AC_LIBTESTFUNC(gen, getspnam)
+
 AC_LIBTESTFUNC(security, getspnam)
 AC_LIBTESTFUNC(sec, getspnam)
 
@@ -252,6 +460,8 @@ AC_LIBTESTFUNC(sec, getprpwnam)
 # these are the defaults, good for lots of systems
 HOST_OS="$host_os"
 LDSHFLAGS="-shared"
+PICFLAG=""
+SHLIBEXT="so"
 
 # and these are for particular systems
 case "$host_os" in
@@ -265,35 +475,60 @@ case "$host_os" in
                *bsd*) LDSHFLAGS="-shared -Bshareable"
                ;;
                *irix*) AC_DEFINE(IRIX)
+                       case "$host_os" in
+                       *irix6*) AC_DEFINE(IRIX6)
+                       ;;
+                       esac
                        ATTEMPT_WRAP32_BUILD=yes
                ;;
                *aix*) AC_DEFINE(AIX);;
-               *hpux*) AC_DEFINE(HPUX);;
+               *hpux*) AC_DEFINE(HPUX)
+                       SHLIBEXT="sl"
+                       # Use special PIC flags for the native HP-UX compiler.
+                       if test $ac_cv_prog_cc_Ae = yes; then
+                               LDSHFLAGS="-b"
+                               PICFLAG="+z"
+                       fi
+               ;;
                *qnx*) AC_DEFINE(QNX);;
                *osf*) AC_DEFINE(OSF1);;
                *sco*) AC_DEFINE(SCO);;
                *next2*) AC_DEFINE(NEXT2);;
                *dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man]);;
-               *sysv4.2*) AC_CHECK_LIB(resolv, strcasecmp);;
+               *sysv4*)
+                       case "$host" in
+                               *-univel-*)     if [ test "$GCC" != yes ]; then
+                                                                       AC_DEFINE(HAVE_MEMSET)
+                                                               fi
+                                                               LDSHFLAGS="-G"
+                               ;;
+                               *mips-sni-sysv4*) AC_DEFINE(RELIANTUNIX);;
+                       esac
+                       ;;
+               *sysv5*)
+                       if [ test "$GCC" != yes ]; then
+                               AC_DEFINE(HAVE_MEMSET)
+                       fi
+                       LDSHFLAGS="-G"
+                       ;;
 esac
 
 # try to work out how to produce pic code with this compiler
-PICFLAG=""
 AC_PROG_CC_FLAG(fpic)
 if test $ac_cv_prog_cc_fpic = yes; then
-   PICFLAG="-fpic";
+    PICFLAG="-fpic";
 fi
 if test x$PICFLAG = x; then
   AC_PROG_CC_FLAG(Kpic)
   if test $ac_cv_prog_cc_Kpic = yes; then
     PICFLAG="-Kpic";
-  fi 
+  fi
 fi
 if test x$PICFLAG = x; then
   AC_PROG_CC_FLAG(KPIC)
   if test $ac_cv_prog_cc_KPIC = yes; then
     PICFLAG="-KPIC";
-  fi 
+  fi
 fi
 
 ################
@@ -316,7 +551,11 @@ if test x"$samba_cv_SIZEOF_OFF_T" = x"yes"; then
 fi
 
 AC_CACHE_CHECK([for off64_t],samba_cv_HAVE_OFF64_T,[
-AC_TRY_RUN([#include <stdio.h>
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdio.h>
 #include <sys/stat.h>
 main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
 samba_cv_HAVE_OFF64_T=yes,samba_cv_HAVE_OFF64_T=no,samba_cv_HAVE_OFF64_T=cross)])
@@ -334,7 +573,11 @@ if test x"$samba_cv_SIZEOF_INO_T" = x"yes"; then
 fi
 
 AC_CACHE_CHECK([for ino64_t],samba_cv_HAVE_INO64_T,[
-AC_TRY_RUN([#include <stdio.h>
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdio.h>
 #include <sys/stat.h>
 main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
 samba_cv_HAVE_INO64_T=yes,samba_cv_HAVE_INO64_T=no,samba_cv_HAVE_INO64_T=cross)])
@@ -342,6 +585,19 @@ if test x"$samba_cv_HAVE_INO64_T" = x"yes"; then
     AC_DEFINE(HAVE_INO64_T)
 fi
 
+AC_CACHE_CHECK([for struct dirent64],samba_cv_HAVE_STRUCT_DIRENT64,[
+AC_TRY_COMPILE([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <dirent.h>],
+[struct dirent64 de;],
+samba_cv_HAVE_STRUCT_DIRENT64=yes,samba_cv_HAVE_STRUCT_DIRENT64=no)])
+if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes"; then
+    AC_DEFINE(HAVE_STRUCT_DIRENT64)
+fi
+
 AC_CACHE_CHECK([for union semun],samba_cv_HAVE_UNION_SEMUN,[
 AC_TRY_RUN([
 #include <sys/types.h>
@@ -501,6 +757,28 @@ if test x"$samba_cv_HAVE_UINT32_FROM_RPC_RPC_H" = x"yes"; then
     AC_DEFINE(HAVE_UINT32_FROM_RPC_RPC_H)
 fi
 
+dnl
+dnl Some systems (SCO) have a problem including
+dnl <prot.h> and <rpc/rpc.h> due to AUTH_ERROR being defined
+dnl as a #define in <prot.h> and as part of an enum
+dnl in <rpc/rpc.h>.
+dnl
+
+AC_CACHE_CHECK([for conflicting AUTH_ERROR define in rpc/rpc.h],samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT,[
+AC_TRY_COMPILE([#include <sys/types.h>
+#ifdef HAVE_SYS_SECURITY_H
+#include <sys/security.h>
+#include <prot.h>
+#endif  /* HAVE_SYS_SECURITY_H */
+#if defined(HAVE_RPC_RPC_H)
+#include <rpc/rpc.h>
+#endif],
+[int testvar;],
+samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no,samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=yes)])
+if test x"$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" = x"yes"; then
+    AC_DEFINE(HAVE_RPC_AUTH_ERROR_CONFLICT)
+fi
+
 AC_MSG_CHECKING([for test routines])
 AC_TRY_RUN([#include "${srcdir-.}/tests/trivial.c"],
            AC_MSG_RESULT(yes),
@@ -523,7 +801,7 @@ fi
 
 AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
 SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper"
 AC_TRY_COMPILE([
 #define REPLACE_GETPASS 1
 #define NO_CONFIG_H 1
@@ -537,12 +815,22 @@ if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then
        AC_DEFINE(REPLACE_GETPASS)
 fi
 
+AC_CACHE_CHECK([for working fnmatch],samba_cv_HAVE_FNMATCH,[
+AC_TRY_RUN([#include <fnmatch.h>
+main() { exit(fnmatch("*.o", "x.o", FNM_PATHNAME) == 0? 0: 1); }],
+samba_cv_HAVE_FNMATCH=yes,samba_cv_HAVE_FNMATCH=no,samba_cv_HAVE_FNMATCH=cross)])
+if test x"$samba_cv_HAVE_FNMATCH" = x"yes"; then
+    AC_DEFINE(HAVE_FNMATCH)
+fi
+
 AC_CACHE_CHECK([for broken inet_ntoa],samba_cv_REPLACE_INET_NTOA,[
 AC_TRY_RUN([
 #include <stdio.h>
 #include <sys/types.h>
 #include <netinet/in.h>
+#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
+#endif
 main() { struct in_addr ip; ip.s_addr = 0x12345678;
 if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
     strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } 
@@ -561,53 +849,117 @@ else
     AC_MSG_WARN(running as non-root will disable some tests)
 fi
 
-netmask=no;
-AC_CACHE_CHECK([for netmask ifconf],samba_cv_HAVE_NETMASK_IFCONF,[
+##################
+# look for a method of finding the list of network interfaces
+iface=no;
+AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[
 AC_TRY_RUN([
-#define HAVE_NETMASK_IFCONF 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"],
-           samba_cv_HAVE_NETMASK_IFCONF=yes,samba_cv_HAVE_NETMASK_IFCONF=no,samba_cv_HAVE_NETMASK_IFCONF=cross)])
-if test x"$samba_cv_HAVE_NETMASK_IFCONF" = x"yes"; then
-    netmask=yes;AC_DEFINE(HAVE_NETMASK_IFCONF)
+#define HAVE_IFACE_AIX 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"],
+           samba_cv_HAVE_IFACE_AIX=yes,samba_cv_HAVE_IFACE_AIX=no,samba_cv_HAVE_IFACE_AIX=cross)])
+if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then
+    iface=yes;AC_DEFINE(HAVE_IFACE_AIX)
 fi
 
-if test $netmask = no; then
-AC_CACHE_CHECK([for netmask ifreq],samba_cv_HAVE_NETMASK_IFREQ,[
+if test $iface = no; then
+AC_CACHE_CHECK([for iface ifconf],samba_cv_HAVE_IFACE_IFCONF,[
 AC_TRY_RUN([
-#define HAVE_NETMASK_IFREQ 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"],
-           samba_cv_HAVE_NETMASK_IFREQ=yes,samba_cv_HAVE_NETMASK_IFREQ=no,samba_cv_HAVE_NETMASK_IFREQ=cross)])
-if test x"$samba_cv_HAVE_NETMASK_IFREQ" = x"yes"; then
-    netmask=yes;AC_DEFINE(HAVE_NETMASK_IFREQ)
+#define HAVE_IFACE_IFCONF 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"],
+           samba_cv_HAVE_IFACE_IFCONF=yes,samba_cv_HAVE_IFACE_IFCONF=no,samba_cv_HAVE_IFACE_IFCONF=cross)])
+if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then
+    iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF)
 fi
 fi
 
-if test $netmask = no; then
-AC_CACHE_CHECK([for netmask AIX],samba_cv_HAVE_NETMASK_AIX,[
+if test $iface = no; then
+AC_CACHE_CHECK([for iface ifreq],samba_cv_HAVE_IFACE_IFREQ,[
 AC_TRY_RUN([
-#define HAVE_NETMASK_AIX 1
-#define AUTOCONF 1
-#include "${srcdir-.}/lib/netmask.c"],
-           samba_cv_HAVE_NETMASK_AIX=yes,samba_cv_HAVE_NETMASK_AIX=no,samba_cv_HAVE_NETMASK_AIX=cross)])
-if test x"$samba_cv_HAVE_NETMASK_AIX" = x"yes"; then
-    netmask=yes;AC_DEFINE(HAVE_NETMASK_AIX)
+#define HAVE_IFACE_IFREQ 1
+#define AUTOCONF_TEST 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/interfaces.c"],
+           samba_cv_HAVE_IFACE_IFREQ=yes,samba_cv_HAVE_IFACE_IFREQ=no,samba_cv_HAVE_IFACE_IFREQ=cross)])
+if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
+    iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ)
 fi
 fi
 
-AC_CACHE_CHECK([for trapdoor seteuid],samba_cv_HAVE_TRAPDOOR_UID,[
-AC_TRY_RUN([#include "${srcdir-.}/tests/trapdoor.c"],
-          samba_cv_HAVE_TRAPDOOR_UID=no,samba_cv_HAVE_TRAPDOOR_UID=yes,:)])
-if test x"$samba_cv_HAVE_TRAPDOOR_UID" = x"yes"; then
-    AC_DEFINE(HAVE_TRAPDOOR_UID)
+
+################################################
+# look for a method of setting the effective uid
+seteuid=no;
+if test $seteuid = no; then
+AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[
+AC_TRY_RUN([
+#define AUTOCONF_TEST 1
+#define USE_SETRESUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"],
+           samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)])
+if test x"$samba_cv_USE_SETRESUID" = x"yes"; then
+    seteuid=yes;AC_DEFINE(USE_SETRESUID)
+fi
 fi
 
+
+if test $seteuid = no; then
+AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[
+AC_TRY_RUN([
+#define AUTOCONF_TEST 1
+#define USE_SETREUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"],
+           samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)])
+if test x"$samba_cv_USE_SETREUID" = x"yes"; then
+    seteuid=yes;AC_DEFINE(USE_SETREUID)
+fi
+fi
+
+if test $seteuid = no; then
+AC_CACHE_CHECK([for seteuid],samba_cv_USE_SETEUID,[
+AC_TRY_RUN([
+#define AUTOCONF_TEST 1
+#define USE_SETEUID 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"],
+           samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)])
+if test x"$samba_cv_USE_SETEUID" = x"yes"; then
+    seteuid=yes;AC_DEFINE(USE_SETEUID)
+fi
+fi
+
+if test $seteuid = no; then
+AC_CACHE_CHECK([for setuidx],samba_cv_USE_SETUIDX,[
+AC_TRY_RUN([
+#define AUTOCONF_TEST 1
+#define USE_SETUIDX 1
+#include "confdefs.h"
+#include "${srcdir-.}/lib/util_sec.c"],
+           samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)])
+if test x"$samba_cv_USE_SETUIDX" = x"yes"; then
+    seteuid=yes;AC_DEFINE(USE_SETUIDX)
+fi
+fi
+
+
 AC_CACHE_CHECK([for shared mmap],samba_cv_HAVE_SHARED_MMAP,[
 AC_TRY_RUN([#include "${srcdir-.}/tests/shared_mmap.c"],
            samba_cv_HAVE_SHARED_MMAP=yes,samba_cv_HAVE_SHARED_MMAP=no,samba_cv_HAVE_SHARED_MMAP=cross)])
 if test x"$samba_cv_HAVE_SHARED_MMAP" = x"yes"; then
     AC_DEFINE(HAVE_SHARED_MMAP)
+    AC_DEFINE(HAVE_MMAP)
+fi
+
+AC_CACHE_CHECK([for ftruncate needs root],samba_cv_FTRUNCATE_NEEDS_ROOT,[
+AC_TRY_RUN([#include "${srcdir-.}/tests/ftruncroot.c"],
+           samba_cv_FTRUNCATE_NEEDS_ROOT=yes,samba_cv_FTRUNCATE_NEEDS_ROOT=no,samba_cv_FTRUNCATE_NEEDS_ROOT=cross)])
+if test x"$samba_cv_FTRUNCATE_NEEDS_ROOT" = x"yes"; then
+    AC_DEFINE(FTRUNCATE_NEEDS_ROOT)
 fi
 
 AC_CACHE_CHECK([for fcntl locking],samba_cv_HAVE_FCNTL_LOCK,[
@@ -617,8 +969,24 @@ if test x"$samba_cv_HAVE_FCNTL_LOCK" = x"yes"; then
     AC_DEFINE(HAVE_FCNTL_LOCK)
 fi
 
-AC_CACHE_CHECK([for 64 bit fcntl locking],samba_cv_HAVE_STRUCT_FLOCK64,[
-AC_TRY_RUN([
+AC_CACHE_CHECK([for broken (glibc2.1/x86) 64 bit fcntl locking],samba_cv_HAVE_BROKEN_FCNTL64_LOCKS,[
+AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock64.c"],
+           samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=no,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross)])
+if test x"$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" = x"yes"; then
+    AC_DEFINE(HAVE_BROKEN_FCNTL64_LOCKS)
+
+else
+
+dnl
+dnl Don't check for 64 bit fcntl locking if we know that the
+dnl glibc2.1 broken check has succeeded.
+dnl 
+
+  AC_CACHE_CHECK([for 64 bit fcntl locking],samba_cv_HAVE_STRUCT_FLOCK64,[
+  AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -637,8 +1005,10 @@ exit(1);
 #endif
 }],
        samba_cv_HAVE_STRUCT_FLOCK64=yes,samba_cv_HAVE_STRUCT_FLOCK64=no,samba_cv_HAVE_STRUCT_FLOCK64=cross)])
-if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
-    AC_DEFINE(HAVE_STRUCT_FLOCK64)
+
+  if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
+      AC_DEFINE(HAVE_STRUCT_FLOCK64)
+  fi
 fi
 
 AC_CACHE_CHECK([for sysv ipc],samba_cv_HAVE_SYSV_IPC,[
@@ -648,6 +1018,25 @@ if test x"$samba_cv_HAVE_SYSV_IPC" = x"yes"; then
     AC_DEFINE(HAVE_SYSV_IPC)
 fi
 
+AC_CACHE_CHECK([for a crypt that needs truncated salt],samba_cv_HAVE_TRUNCATED_SALT,[
+AC_TRY_RUN([#include "${srcdir-.}/tests/crypttest.c"],
+           samba_cv_HAVE_TRUNCATED_SALT=no,samba_cv_HAVE_TRUNCATED_SALT=yes,samba_cv_HAVE_TRUNCATED_SALT=cross)])
+if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then
+    AC_DEFINE(HAVE_TRUNCATED_SALT)
+fi
+
+AC_CACHE_CHECK([for broken nisplus include files],samba_cv_BROKEN_NISPLUS_INCLUDE_FILES,[
+AC_TRY_COMPILE([#include <sys/acl.h>
+#if defined(HAVE_RPCSVC_NIS_H)
+#include <rpcsvc/nis.h>
+#endif],
+[return 0;],
+samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no,samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes)])
+if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
+    AC_DEFINE(BROKEN_NISPLUS_INCLUDE_FILES)
+fi
+
+
 #################################################
 # check for smbwrapper support
 AC_MSG_CHECKING(whether to use smbwrapper)
@@ -658,12 +1047,12 @@ AC_ARG_WITH(smbwrapper,
   yes)
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_SMBWRAPPER)
-       WRAP="bin/smbsh bin/smbwrapper.so"
+       WRAP="bin/smbsh bin/smbwrapper.$SHLIBEXT"
 
        if test x$ATTEMPT_WRAP32_BUILD = x; then
                WRAP32=""
        else
-                       WRAP32=bin/smbwrapper.32.so
+                       WRAP32=bin/smbwrapper.32.$SHLIBEXT
        fi
 
 # Conditions under which smbwrapper should not be built.
@@ -727,7 +1116,7 @@ AC_ARG_WITH(dfs,
 AC_MSG_CHECKING(whether to use Kerberos IV)
 AC_ARG_WITH(krb4,
 [  --with-krb4=base-dir     Include Kerberos IV support
-  --without-krb4          Don't include Kerberos IV support (default)],
+  --without-krb4          Don't include Kerbers IV support (default)],
 [   AC_MSG_RESULT(yes)
     AC_DEFINE(KRB4_AUTH)
     AC_CHECK_LIB(resolv, dn_expand)
@@ -737,6 +1126,20 @@ AC_ARG_WITH(krb4,
   AC_MSG_RESULT(no)
 )
 
+#################################################
+# check for Kerberos 5 auth system
+AC_MSG_CHECKING(whether to use Kerberos 5)
+AC_ARG_WITH(krb5,
+[  --with-krb5=base-dir     Include Kerberos 5 support
+  --without-krb5          Don't include Kerbers 5 support (default)],
+[   AC_MSG_RESULT(yes)
+    AC_DEFINE(KRB5_AUTH)
+    LIBS="$LIBS -ldes425 -lkrb5 -lcrypto -lcom_err"
+    CFLAGS="$CFLAGS -I$withval/include"
+    LDFLAGS="$LDFLAGS -L$withval/lib"],
+  AC_MSG_RESULT(no)
+)
+
 #################################################
 # check for automount support
 AC_MSG_CHECKING(whether to use AUTOMOUNT)
@@ -776,6 +1179,27 @@ AC_ARG_WITH(smbmount,
   MPROGS=
 )
 
+
+#################################################
+# check for a PAM password database
+AC_MSG_CHECKING(whether to use PAM password database)
+AC_ARG_WITH(pam,
+[  --with-pam     Include PAM password database support
+  --without-pam  Don't include PAM password database support (default)],
+[ case "$withval" in
+  yes)
+    AC_MSG_RESULT(yes)
+    AC_DEFINE(WITH_PAM)
+    LIBS="$LIBS -lpam"
+    ;;
+  *)
+    AC_MSG_RESULT(no)
+    ;;
+  esac ],
+  AC_MSG_RESULT(no)
+)
+
+
 #################################################
 # check for a LDAP password database
 AC_MSG_CHECKING(whether to use LDAP password database)
@@ -786,7 +1210,7 @@ AC_ARG_WITH(ldap,
   yes)
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_LDAP)
-    LIBS="$LIBS -lldap -llber"
+    AC_MSG_ERROR([LDAP password database not supported in this version.])
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -836,29 +1260,46 @@ AC_ARG_WITH(nisplus-home,
 AC_MSG_CHECKING(whether to use SSL)
 AC_ARG_WITH(ssl,
 [  --with-ssl     Include SSL support
-  --without-ssl  Don't include SSL support (default)],
+  --without-ssl  Don't include SSL support (default)
+  --with-sslinc=DIR Where the SSL includes are (defaults to /usr/local/ssl)],
 [ case "$withval" in
   yes)
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_SSL)
-    ;;
-  *)
-    AC_MSG_RESULT(no)
-    ;;
-  esac ],
-  AC_MSG_RESULT(no)
-)
+    withval="/usr/local/ssl"     # default
+
+    if test "${with_sslinc+set}" = set; then
+
+       withval="$with_sslinc"
+       case "$withval" in
+       yes|no)
+         echo "configure: warning: --with-sslinc called without argument - will use default" 1>&w
+         CFLAGS="-I/usr/local/ssl/include $CFLAGS"
+         LIBS="-lssl -lcrypto $LIBS"
+         LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS"
+       ;;
+        * )
+          CFLAGS="-I${withval}/include $CFLAGS"
+         LIBS="-lssl -lcrypto $LIBS"
+         LDFLAGS="-L${withval}/lib $LDFLAGS"
+       ;;
+       esac
+
+    else
+
+       CFLAGS="-I/usr/local/ssl/include $CFLAGS"   
+       LIBS="-lssl -lcrypto $LIBS"
+       LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
+
+    fi
+
+    if test ! -d ${withval}; then
+      echo "configure: error: called with --with-ssl, but ssl base directory ${withval} does not exist or is not a directory. Aborting config" 1>&2
+      exit 1
+    fi 
+
+    CFLAGS="-DHAVE_CRYPT_DECL $CFLAGS"  # Damn, SSLeay defines its own
 
-#################################################
-# check for experimental mmap support
-AC_MSG_CHECKING(whether to use MMAP)
-AC_ARG_WITH(mmap,
-[  --with-mmap     Include experimental MMAP support
-  --without-mmap  Don't include MMAP support (default)],
-[ case "$withval" in
-  yes)
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(WITH_MMAP)
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -943,6 +1384,69 @@ AC_ARG_WITH(quotas,
 )
 AC_SUBST(QUOTAOBJS)
 
+#################################################
+# set private directory location
+AC_ARG_WITH(privatedir,
+[  --with-privatedir=DIR     Where to put smbpasswd ($ac_default_prefix/private)],
+[ case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody calls it without argument
+  #
+    AC_MSG_WARN([--with-privatedir called without argument - will use default])
+    privatedir='${prefix}/private'
+  ;;
+  * )
+    privatedir="$withval"
+    ;;
+  esac
+  AC_SUBST(privatedir)],
+  [privatedir='${prefix}/private'
+   AC_SUBST(privatedir)]
+)
+
+#################################################
+# set lock directory location
+AC_ARG_WITH(lockdir,
+[  --with-lockdir=DIR     Where to put lock files ($ac_default_prefix/var/locks)],
+[ case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody calls it without argument
+  #
+    AC_MSG_WARN([--with-lockdir called without argument - will use default])
+    lockdir='$(VARDIR)/locks'
+  ;;
+  * )
+    lockdir="$withval"
+    ;;
+  esac
+  AC_SUBST(lockdir)],
+  [lockdir='$(VARDIR)/locks'
+   AC_SUBST(lockdir)]
+)
+
+#################################################
+# set SWAT directory location
+AC_ARG_WITH(swatdir,
+[  --with-swatdir=DIR     Where to put SWAT files ($ac_default_prefix/swat)],
+[ case "$withval" in
+  yes|no)
+  #
+  # Just in case anybody does it
+  #
+    AC_MSG_WARN([--with-swatdir called without argument - will use default])
+    swatdir='${prefix}/swat'
+  ;;
+  * )
+    swatdir="$withval"
+    ;;
+  esac
+  AC_SUBST(swatdir)],
+  [swatdir='${prefix}/swat'
+   AC_SUBST(swatdir)]
+)
+
 #################################################
 # these tests are taken from the GNU fileutils package
 AC_CHECKING(how to get filesystem space usage)
@@ -953,12 +1457,15 @@ if test $space = no; then
   # SVR4
   AC_CACHE_CHECK([statvfs64 function (SVR4)], fu_cv_sys_stat_statvfs64,
   [AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 #include <sys/types.h>
 #include <sys/statvfs.h>
   main ()
   {
     struct statvfs64 fsd;
-    exit (statfs64 (".", &fsd));
+    exit (statvfs64 (".", &fsd));
   }],
   fu_cv_sys_stat_statvfs64=yes,
   fu_cv_sys_stat_statvfs64=no,
@@ -1124,6 +1631,31 @@ if test $space = no; then
   fi
 fi
 
+#
+# As a gating factor for large file support, in order to
+# use <4GB files we must have the following minimal support
+# available.
+# long long, and a 64 bit off_t or off64_t.
+# If we don't have all of these then disable large
+# file support.
+#
+echo "checking if large file support can be enabled"
+AC_TRY_COMPILE([
+#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
+#include <sys/types.h>
+#else
+__COMPILE_ERROR_
+#endif
+],
+[int i],
+samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes,samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=no)
+if test x"$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT" = x"yes"; then
+    echo "yes"
+    AC_DEFINE(HAVE_EXPLICIT_LARGEFILE_SUPPORT)
+else
+    echo "no"
+fi
+
 echo "checking configure summary"
 AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
            echo "configure OK";,
index b787012b4d2729d4dc935deb0dc8a0a02d15e2a4..e5e6ebfa53f179e0c527dd33602609eff26fee8c 100644 (file)
 extern int DEBUGLEVEL;
 
 extern fstring global_sam_name;
-extern DOM_SID global_sam_sid;
 
 /*
  * NOTE. All these functions are abstracted into a structure
  * that points to the correct function for the selected database. JRA.
  */
 
-static struct aliasdb_ops *aldb_ops = NULL;
+static struct aliasdb_ops *aldb_ops;
 
 /***************************************************************
  Initialise the alias db operations.
@@ -50,8 +49,8 @@ BOOL initialise_alias_db(void)
   aldb_ops =  nisplus_initialise_alias_db();
 #elif defined(WITH_LDAP)
   aldb_ops = ldap_initialise_alias_db();
-#elif defined(USE_SMBUNIX_DB)
-  aldb_ops = unix_initialise_alias_db();
+#else 
+  aldb_ops = file_initialise_alias_db();
 #endif 
 
   return (aldb_ops != NULL);
@@ -68,28 +67,7 @@ BOOL initialise_alias_db(void)
 *************************************************************************/
 LOCAL_GRP *iterate_getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
 {
-       DOM_NAME_MAP gmep;
-       uint32 rid;
-       if (!lookupsmbgrpgid(gid, &gmep))
-       {
-               DEBUG(0,("iterate_getaliasgid: gid %d does not map to one of our Domain's Aliases\n", gid));
-               return NULL;
-       }
-
-       if (gmep.type != SID_NAME_ALIAS )
-       {
-               DEBUG(0,("iterate_getaliasgid: gid %d does not map to one of our Domain's Aliases\n", gid));
-               return NULL;
-       }
-
-       sid_split_rid(&gmep.sid, &rid);
-       if (!sid_equal(&gmep.sid, &global_sam_sid))
-       {
-               DEBUG(0,("iterate_getaliasgid: gid %d does not map into our Domain SID\n", gid));
-               return NULL;
-       }
-
-       return iterate_getaliasrid(rid, mem, num_mem);
+       return iterate_getaliasrid(pwdb_gid_to_alias_rid(gid), mem, num_mem);
 }
 
 /************************************************************************
@@ -114,7 +92,6 @@ LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
 
        while ((als = getaliasent(fp, mem, num_mem)) != NULL && als->rid != rid)
        {
-               DEBUG(10,("iterate: %s 0x%x", als->name, als->rid));
        }
 
        if (als != NULL)
@@ -130,7 +107,7 @@ LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
  Utility function to search alias database by name.  use this if your database
  does not have search facilities.
 *************************************************************************/
-LOCAL_GRP *iterate_getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+LOCAL_GRP *iterate_getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
 {
        LOCAL_GRP *als = NULL;
        void *fp = NULL;
@@ -189,11 +166,11 @@ BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als)
 /*************************************************************************
  checks to see if a user is a member of a domain alias
  *************************************************************************/
-static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
+static BOOL user_is_member(char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
 {
        int i;
        pstring name;
-       slprintf(name, sizeof(name)-1, "%s\\%s", global_sam_name, user_name);
+       slprintf(name, sizeof(name)-1, "\\%s\\%s", global_sam_name, user_name);
 
        for (i = 0; i < num_mem; i++)
        {
@@ -212,16 +189,16 @@ static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num
  gets an array of aliases that a user is in.  use this if your database
  does not have search facilities
  *************************************************************************/
-BOOL iterate_getuseraliasntnam(const char *user_name, LOCAL_GRP **alss, int *num_alss)
+BOOL iterate_getuseraliasnam(char *user_name, LOCAL_GRP **alss, int *num_alss)
 {
-       LOCAL_GRP *als = NULL;
+       LOCAL_GRP *als;
        LOCAL_GRP_MEMBER *mem = NULL;
        int num_mem = 0;
        void *fp = NULL;
 
        DEBUG(10, ("search for useralias by name: %s\n", user_name));
 
-       if (user_name == NULL || alss == NULL || num_alss == NULL)
+       if (user_name == NULL || als == NULL || num_alss == NULL)
        {
                return False;
        }
@@ -277,12 +254,12 @@ BOOL iterate_getuseraliasntnam(const char *user_name, LOCAL_GRP **alss, int *num
  *************************************************************************/
 BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss)
 {
-       LOCAL_GRP *als = NULL;
+       LOCAL_GRP *als;
        void *fp = NULL;
 
        DEBUG(10, ("enum user aliases\n"));
 
-       if (alss == NULL || num_alss == NULL)
+       if (als == NULL || num_alss == NULL)
        {
                return False;
        }
@@ -348,25 +325,11 @@ LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
 
 /************************************************************************
  Routine to add an entry to the alias database file.
- on entry, the entry is added by name.
- on exit, the RID is expected to have been set.
 *************************************************************************/
-BOOL add_alias_entry(LOCAL_GRP *newgrp)
-{
-       BOOL ret;
-       if (newgrp->rid != 0xffffffff)
+
+BOOL add_alias_entry(LOCAL_GRP *newals)
 {
-               DEBUG(0,("add_alias_entry - RID must be 0xffffffff, \
-database instance is responsible for allocating the RID, not you.\n"));
-               return False;
-       }
-       ret = aldb_ops->add_alias_entry(newgrp);
-       if (newgrp->rid == 0xffffffff)
-       {
-               DEBUG(0,("add_alias_entry - RID has not been set by database\n"));
-               return False;
-       }
-       return ret;
+       return aldb_ops->add_alias_entry(newals);
 }
 
 /************************************************************************
@@ -379,36 +342,13 @@ BOOL mod_alias_entry(LOCAL_GRP* als)
        return aldb_ops->mod_alias_entry(als);
 }
 
-/************************************************************************
- Routine to delete alias database entry matching by rid.
-************************************************************************/
-BOOL del_alias_entry(uint32 rid)
-{
-       return aldb_ops->del_alias_entry(rid);
-}
-
-/************************************************************************
- Routine to add a member to an entry in the alias database file.
-*************************************************************************/
-BOOL add_alias_member(uint32 rid, DOM_SID *member_sid)
-{
-       return aldb_ops->add_alias_member(rid, member_sid);
-}
-
-/************************************************************************
- Routine to delete a member from an entry in the alias database file.
-*************************************************************************/
-BOOL del_alias_member(uint32 rid, DOM_SID *member_sid)
-{
-       return aldb_ops->del_alias_member(rid, member_sid);
-}
 /************************************************************************
  Routine to search alias database by name.
 *************************************************************************/
 
-LOCAL_GRP *getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+LOCAL_GRP *getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
 {
-       return aldb_ops->getaliasntnam(name, mem, num_mem);
+       return aldb_ops->getaliasnam(name, mem, num_mem);
 }
 
 /************************************************************************
@@ -432,65 +372,18 @@ LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
 /*************************************************************************
  gets an array of aliases that a user is in.
  *************************************************************************/
-BOOL getuseraliasntnam(const char *user_name, LOCAL_GRP **als, int *num_alss)
+BOOL getuseraliasnam(char *user_name, LOCAL_GRP **als, int *num_alss)
 {
-       return aldb_ops->getuseraliasntnam(user_name, als, num_alss);
+       return aldb_ops->getuseraliasnam(user_name, als, num_alss);
 }
 
 /*************************************************************
  initialises a LOCAL_GRP.
  **************************************************************/
+
 void aldb_init_als(LOCAL_GRP *als)
 {
        if (als == NULL) return;
        ZERO_STRUCTP(als);
 }
 
-/*************************************************************
- turns an alias entry into a string.
- **************************************************************/
-BOOL make_alias_line(char *p, int max_len,
-                               LOCAL_GRP *als,
-                               LOCAL_GRP_MEMBER **mem, int *num_mem)
-{
-       int i;
-       int len;
-       len = slprintf(p, max_len-1, "%s:%s:%d:", als->name, als->comment, als->rid);
-
-       if (len == -1)
-       {
-               DEBUG(0,("make_alias_line: cannot create entry\n"));
-               return False;
-       }
-
-       p += len;
-       max_len -= len;
-
-       if (mem == NULL || num_mem == NULL)
-       {
-               return True;
-       }
-
-       for (i = 0; i < (*num_mem); i++)
-       {
-               len = strlen((*mem)[i].name);
-               p = safe_strcpy(p, (*mem)[i].name, max_len); 
-
-               if (p == NULL)
-               {
-                       DEBUG(0, ("make_alias_line: out of space for aliases!\n"));
-                       return False;
-               }
-
-               max_len -= len;
-
-               if (i != (*num_mem)-1)
-               {
-                       *p = ',';
-                       p++;
-                       max_len--;
-               }
-       }
-
-       return True;
-}
index c09d6cc23ed613d869c5036f96f6d7ac84649b30..4b8bbe3079fdb699ea6301f5e7bab0866df95b92 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "includes.h"
 
-#ifdef USE_SMBGROUP_DB
+#ifdef USE_SMBPASS_DB
 
 static int al_file_lock_depth = 0;
 extern int DEBUGLEVEL;
@@ -33,7 +33,7 @@ static char s_readbuf[1024];
 
 static void *startalsfilepwent(BOOL update)
 {
-       return startfileent(lp_smb_alias_file(),
+       return startfilepwent(lp_smb_alias_file(),
                              s_readbuf, sizeof(s_readbuf),
                              &al_file_lock_depth, update);
 }
@@ -44,7 +44,7 @@ static void *startalsfilepwent(BOOL update)
 
 static void endalsfilepwent(void *vp)
 {
-       endfileent(vp, &al_file_lock_depth);
+       endfilepwent(vp, &al_file_lock_depth);
 }
 
 /*************************************************************************
@@ -65,6 +65,51 @@ static BOOL setalsfilepwpos(void *vp, SMB_BIG_UINT tok)
        return setfilepwpos(vp, tok);
 }
 
+static BOOL make_alias_line(char *p, int max_len,
+                               LOCAL_GRP *als,
+                               LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+       int i;
+       int len;
+       len = slprintf(p, max_len-1, "%s:%s:%d:", als->name, als->comment, als->rid);
+
+       if (len == -1)
+       {
+               DEBUG(0,("make_alias_line: cannot create entry\n"));
+               return False;
+       }
+
+       p += len;
+       max_len -= len;
+
+       if (mem == NULL || num_mem == NULL)
+       {
+               return True;
+       }
+
+       for (i = 0; i < (*num_mem); i++)
+       {
+               len = strlen((*mem)[i].name);
+               p = safe_strcpy(p, (*mem)[i].name, max_len); 
+
+               if (p == NULL)
+               {
+                       DEBUG(0, ("make_alias_line: out of space for aliases!\n"));
+                       return False;
+               }
+
+               max_len -= len;
+
+               if (i != (*num_mem)-1)
+               {
+                       *p = ',';
+                       p++;
+                       max_len--;
+               }
+       }
+
+       return True;
+}
 
 /*************************************************************************
  Routine to return the next entry in the smbdomainalias list.
@@ -85,36 +130,24 @@ static char *get_alias_members(char *p, int *num_mem, LOCAL_GRP_MEMBER **members
        {
                DOM_SID sid;
                uint8 type;
-               BOOL found = False;
 
-               if (strnequal(name, "S-", 2))
+               if (lookup_sid(name, &sid, &type))
                {
-                       /* sid entered directly */
-                       string_to_sid(&sid, name);
-                       found = lookup_sid(&sid, name, &type) == 0x0;
+                       (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
+                       (*num_mem)++;
                }
                else
-               {
-                       found = lookup_name(name, &sid, &type) == 0x0;
-               }
-
-               if (!found)
                {
                        DEBUG(0,("alias database: could not resolve alias named %s\n", name));
                        continue;
                }
-
-               (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
-
                if ((*members) == NULL)
                {
                        return NULL;
                }
-
-               fstrcpy((*members)[*num_mem].name, name);
-               (*members)[*num_mem].sid_use = type;
-               sid_copy(&(*members)[*num_mem].sid, &sid);
-               (*num_mem)++;
+               fstrcpy((*members)[(*num_mem)-1].name, name);
+               (*members)[(*num_mem)-1].sid_use = type;
+               sid_copy(&(*members)[(*num_mem)-1].sid, &sid);
        }
        return p;
 }
@@ -131,17 +164,15 @@ static LOCAL_GRP *getalsfilepwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
 
        pstring linebuf;
        char  *p;
-       uint8 type;
+       size_t            linebuf_len;
 
        aldb_init_als(&al_buf);
 
        /*
         * Scan the file, a line at a time and check if the name matches.
         */
-       while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
+       while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
        {
-               DOM_NAME_MAP gmep;
-
                /* get alias name */
 
                p = strncpyn(al_buf.name, linebuf, sizeof(al_buf.name), ':');
@@ -193,25 +224,9 @@ static LOCAL_GRP *getalsfilepwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
                        }
                }
 
-               /*
-                * look up the gid, turn it into a rid.  the _correct_ type of rid */
-                */
+               /* ok, set up the static data structure and return it */
 
-               if (!lookupsmbgrpgid((gid_t)gidval, &gmep))
-               {
-                       continue;
-               }
-               if (gmep.type != SID_NAME_DOM_GRP &&
-                   gmep.type != SID_NAME_WKN_GRP))
-               {
-                       continue;
-               }
-
-               sid_split_rid(&gmep.sid, &gp_buf.rid);
-               if (!sid_equal(&gmep.sid, &global_sam_sid))
-               {
-                       continue;
-               }
+               al_buf.rid     = pwdb_gid_to_alias_rid((gid_t)gidval);
 
                make_alias_line(linebuf, sizeof(linebuf), &al_buf, mem, num_mem);
                DEBUG(10,("line: '%s'\n", linebuf));
@@ -235,7 +250,11 @@ static BOOL add_alsfileals_entry(LOCAL_GRP *newals)
 
 /************************************************************************
  Routine to search the aliasdb file for an entry matching the aliasname.
- and then modify its alias entry. 
+ and then modify its alias entry. We can't use the startalspwent()/
+ getalspwent()/endalspwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out alias or NO PASS
 ************************************************************************/
 
 static BOOL mod_alsfileals_entry(LOCAL_GRP* als)
@@ -252,7 +271,7 @@ static struct aliasdb_ops file_ops =
        getalsfilepwpos,
        setalsfilepwpos,
 
-       iterate_getaliasntnam,          /* In aliasdb.c */
+       iterate_getaliasnam,          /* In aliasdb.c */
        iterate_getaliasgid,          /* In aliasdb.c */
        iterate_getaliasrid,          /* In aliasdb.c */
        getalsfilepwent,
@@ -260,7 +279,7 @@ static struct aliasdb_ops file_ops =
        add_alsfileals_entry,
        mod_alsfileals_entry,
 
-       iterate_getuseraliasntnam      /* in aliasdb.c */
+       iterate_getuseraliasnam      /* in aliasdb.c */
 };
 
 struct aliasdb_ops *file_initialise_alias_db(void)
index ed09560b3a8883e5ad05a6798332ecb7fe13d603..b8952358fbc1735f8ed1dc79f24fb735cc76695e 100644 (file)
 #include "nterr.h"
 
 extern int DEBUGLEVEL;
-extern DOM_SID global_sam_sid;
 
 /*
  * NOTE. All these functions are abstracted into a structure
  * that points to the correct function for the selected database. JRA.
  */
 
-static struct groupdb_ops *gpdb_ops = NULL;
+static struct groupdb_ops *gpdb_ops;
 
 /***************************************************************
  Initialise the group db operations.
@@ -48,8 +47,8 @@ BOOL initialise_group_db(void)
   gpdb_ops =  nisplus_initialise_group_db();
 #elif defined(WITH_LDAP)
   gpdb_ops = ldap_initialise_group_db();
-#elif defined(USE_SMBUNIX_DB)
-  gpdb_ops = unix_initialise_group_db();
+#else 
+  gpdb_ops = file_initialise_group_db();
 #endif 
 
   return (gpdb_ops != NULL);
@@ -66,28 +65,7 @@ BOOL initialise_group_db(void)
 *************************************************************************/
 DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 {
-       DOM_NAME_MAP gmep;
-       uint32 rid;
-       if (!lookupsmbgrpgid(gid, &gmep))
-       {
-               DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
-               return NULL;
-       }
-
-       if (gmep.type != SID_NAME_DOM_GRP && gmep.type != SID_NAME_WKN_GRP)
-       {
-               DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
-               return NULL;
-       }
-
-       sid_split_rid(&gmep.sid, &rid);
-       if (!sid_equal(&gmep.sid, &global_sam_sid))
-       {
-               DEBUG(0,("iterate_getgroupgid: gid %d does not map into our Domain SID\n", gid));
-               return NULL;
-       }
-
-       return iterate_getgrouprid(rid, mem, num_mem);
+       return iterate_getgrouprid(pwdb_gid_to_group_rid(gid), mem, num_mem);
 }
 
 /************************************************************************
@@ -127,7 +105,7 @@ DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_me
  Utility function to search group database by name.  use this if your database
  does not have search facilities.
 *************************************************************************/
-DOMAIN_GRP *iterate_getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+DOMAIN_GRP *iterate_getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 {
        DOMAIN_GRP *grp = NULL;
        void *fp = NULL;
@@ -187,7 +165,7 @@ BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
 /*************************************************************************
  checks to see if a user is a member of a domain group
  *************************************************************************/
-static BOOL user_is_member(const char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
+static BOOL user_is_member(char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
 {
        int i;
        for (i = 0; i < num_mem; i++)
@@ -207,16 +185,16 @@ static BOOL user_is_member(const char *user_name, DOMAIN_GRP_MEMBER *mem, int nu
  gets an array of groups that a user is in.  use this if your database
  does not have search facilities
  *************************************************************************/
-BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num_grps)
+BOOL iterate_getusergroupsnam(char *user_name, DOMAIN_GRP **grps, int *num_grps)
 {
-       DOMAIN_GRP *grp = NULL;
+       DOMAIN_GRP *grp;
        DOMAIN_GRP_MEMBER *mem = NULL;
        int num_mem = 0;
        void *fp = NULL;
 
        DEBUG(10, ("search for usergroups by name: %s\n", user_name));
 
-       if (user_name == NULL || grps == NULL || num_grps == NULL)
+       if (user_name == NULL || grp == NULL || num_grps == NULL)
        {
                return False;
        }
@@ -272,12 +250,12 @@ BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num
  *************************************************************************/
 BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps)
 {
-       DOMAIN_GRP *grp = NULL;
+       DOMAIN_GRP *grp;
        void *fp = NULL;
 
        DEBUG(10, ("enum user groups\n"));
 
-       if (grps == NULL || num_grps == NULL)
+       if (grp == NULL || num_grps == NULL)
        {
                return False;
        }
@@ -343,38 +321,15 @@ DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 
 /************************************************************************
  Routine to add an entry to the group database file.
- on entry, the entry is added by name.
- on exit, the RID is expected to have been set.
 *************************************************************************/
 
 BOOL add_group_entry(DOMAIN_GRP *newgrp)
 {
-       BOOL ret;
-       if (newgrp->rid != 0xffffffff)
-       {
-               DEBUG(0,("add_group_entry - RID must be 0xffffffff, \
-database instance is responsible for allocating the RID, not you.\n"));
-               return False;
-       }
-       ret = gpdb_ops->add_group_entry(newgrp);
-       if (newgrp->rid == 0xffffffff)
-       {
-               DEBUG(0,("add_group_entry - RID has not been set by database\n"));
-               return False;
-       }
-       return ret;
+       return gpdb_ops->add_group_entry(newgrp);
 }
 
 /************************************************************************
- Routine to delete group database entry matching by rid.
-************************************************************************/
-BOOL del_group_entry(uint32 rid)
-{
-       return gpdb_ops->del_group_entry(rid);
-}
-
-/************************************************************************
- Routine to search group database file for entry matching by rid or groupname.
+ Routine to search the group database file for an entry matching the groupname.
  and then replace the entry.
 ************************************************************************/
 
@@ -383,29 +338,13 @@ BOOL mod_group_entry(DOMAIN_GRP* grp)
        return gpdb_ops->mod_group_entry(grp);
 }
 
-/************************************************************************
- Routine to add a member to an entry in the group database file.
-*************************************************************************/
-BOOL add_group_member(uint32 rid, uint32 member_rid)
-{
-       return gpdb_ops->add_group_member(rid, member_rid);
-}
-
-/************************************************************************
- Routine to delete a member from an entry in the group database file.
-*************************************************************************/
-BOOL del_group_member(uint32 rid, uint32 member_rid)
-{
-       return gpdb_ops->del_group_member(rid, member_rid);
-}
-
 /************************************************************************
  Routine to search group database by name.
 *************************************************************************/
 
-DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+DOMAIN_GRP *getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 {
-       return gpdb_ops->getgroupntnam(name, mem, num_mem);
+       return gpdb_ops->getgroupnam(name, mem, num_mem);
 }
 
 /************************************************************************
@@ -429,9 +368,9 @@ DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
 /*************************************************************************
  gets an array of groups that a user is in.
  *************************************************************************/
-BOOL getusergroupsntnam(const char *user_name, DOMAIN_GRP **grp, int *num_grps)
+BOOL getusergroupsnam(char *user_name, DOMAIN_GRP **grp, int *num_grps)
 {
-       return gpdb_ops->getusergroupsntnam(user_name, grp, num_grps);
+       return gpdb_ops->getusergroupsnam(user_name, grp, num_grps);
 }
 
 /*************************************************************
@@ -444,51 +383,3 @@ void gpdb_init_grp(DOMAIN_GRP *grp)
        ZERO_STRUCTP(grp);
 }
 
-/*************************************************************************
- turns a list of groups into a string.
-*************************************************************************/
-BOOL make_group_line(char *p, int max_len,
-                               DOMAIN_GRP *grp,
-                               DOMAIN_GRP_MEMBER **mem, int *num_mem)
-{
-       int i;
-       int len;
-       len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
-
-       if (len == -1)
-       {
-               DEBUG(0,("make_group_line: cannot create entry\n"));
-               return False;
-       }
-
-       p += len;
-       max_len -= len;
-
-       if (mem == NULL || num_mem == NULL)
-       {
-               return True;
-       }
-
-       for (i = 0; i < (*num_mem); i++)
-       {
-               len = strlen((*mem)[i].name);
-               p = safe_strcpy(p, (*mem)[i].name, max_len); 
-
-               if (p == NULL)
-               {
-                       DEBUG(0, ("make_group_line: out of space for groups!\n"));
-                       return False;
-               }
-
-               max_len -= len;
-
-               if (i != (*num_mem)-1)
-               {
-                       *p = ',';
-                       p++;
-                       max_len--;
-               }
-       }
-
-       return True;
-}
index dba190ce569f56e20d6d8f72afdc067bd152a066..88d362e7d4c7b8116114f4c7d9c99d84a8219924 100644 (file)
 
 #include "includes.h"
 
-#ifdef USE_SMBGROUP_DB
+#ifdef USE_SMBPASS_DB
 
 static int gp_file_lock_depth = 0;
 extern int DEBUGLEVEL;
 
 static char s_readbuf[1024];
 
-extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
-
 /***************************************************************
  Start to enumerate the grppasswd list. Returns a void pointer
  to ensure no modification outside this module.
@@ -36,7 +33,7 @@ extern fstring global_sam_name;
 
 static void *startgrpfilepwent(BOOL update)
 {
-       return startfileent(lp_smb_group_file(),
+       return startfilepwent(lp_smb_group_file(),
                              s_readbuf, sizeof(s_readbuf),
                              &gp_file_lock_depth, update);
 }
@@ -47,7 +44,7 @@ static void *startgrpfilepwent(BOOL update)
 
 static void endgrpfilepwent(void *vp)
 {
-       endfileent(vp, &gp_file_lock_depth);
+       endfilepwent(vp, &gp_file_lock_depth);
 }
 
 /*************************************************************************
@@ -68,6 +65,51 @@ static BOOL setgrpfilepwpos(void *vp, SMB_BIG_UINT tok)
        return setfilepwpos(vp, tok);
 }
 
+static BOOL make_group_line(char *p, int max_len,
+                               DOMAIN_GRP *grp,
+                               DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+       int i;
+       int len;
+       len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
+
+       if (len == -1)
+       {
+               DEBUG(0,("make_group_line: cannot create entry\n"));
+               return False;
+       }
+
+       p += len;
+       max_len -= len;
+
+       if (mem == NULL || num_mem == NULL)
+       {
+               return True;
+       }
+
+       for (i = 0; i < (*num_mem); i++)
+       {
+               len = strlen((*mem)[i].name);
+               p = safe_strcpy(p, (*mem)[i].name, max_len); 
+
+               if (p == NULL)
+               {
+                       DEBUG(0, ("make_group_line: out of space for groups!\n"));
+                       return False;
+               }
+
+               max_len -= len;
+
+               if (i != (*num_mem)-1)
+               {
+                       *p = ',';
+                       p++;
+                       max_len--;
+               }
+       }
+
+       return True;
+}
 
 /*************************************************************************
  Routine to return the next entry in the smbdomaingroup list.
@@ -86,36 +128,11 @@ static char *get_group_members(char *p, int *num_mem, DOMAIN_GRP_MEMBER **member
 
        while (next_token(&p, name, ",", sizeof(fstring)))
        {
-               DOM_SID sid;
-               uint8 type;
-               BOOL found = False;
-
-               if (isdigit(name))
-               {
-                       uint32 rid = get_number(name);
-                       sid_copy(&sid, &global_sam_sid);
-                       sid_append_rid(&sid, rid);
-                       
-                       found = lookup_sid(&sid, name, &type) == 0x0;
-               }
-               else
-               {
-                       found = lookup_name(name, &sid, &type) == 0x0;
-               }
-
-               if (!found)
-               {
-                       DEBUG(0,("group database: could not resolve name %s in domain %s\n",
-                                 name, global_sam_name));
-                       continue;
-               }
-
                (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
                if ((*members) == NULL)
                {
                        return NULL;
                }
-
                fstrcpy((*members)[(*num_mem)].name, name);
                (*members)[(*num_mem)].attr = 0x07;
                (*num_mem)++;
@@ -130,19 +147,19 @@ static DOMAIN_GRP *getgrpfilepwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
 {
        /* Static buffers we will return. */
        static DOMAIN_GRP gp_buf;
-       DOM_NAME_MAP gmep;
 
        int gidval;
 
        pstring linebuf;
        char  *p;
+       size_t            linebuf_len;
 
        gpdb_init_grp(&gp_buf);
 
        /*
         * Scan the file, a line at a time and check if the name matches.
         */
-       while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
+       while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
        {
                /* get group name */
 
@@ -197,22 +214,7 @@ static DOMAIN_GRP *getgrpfilepwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
 
                /* ok, set up the static data structure and return it */
 
-               if (!lookupsmbgrpgid((gid_t)gidval, &gmep))
-               {
-                       continue;
-               }
-               if (gmep.type != SID_NAME_DOM_GRP &&
-                   gmep.type != SID_NAME_WKN_GRP))
-               {
-                       continue;
-               }
-
-               sid_split_rid(&gmep.sid, &gp_buf.rid);
-               if (!sid_equal(&gmep.sid, &global_sam_sid))
-               {
-                       continue;
-               }
-
+               gp_buf.rid     = pwdb_gid_to_group_rid((gid_t)gidval);
                gp_buf.attr    = 0x07;
 
                make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
@@ -237,7 +239,11 @@ static BOOL add_grpfilegrp_entry(DOMAIN_GRP *newgrp)
 
 /************************************************************************
  Routine to search the grppasswd file for an entry matching the groupname.
- and then modify its group entry. 
+ and then modify its group entry. We can't use the startgrppwent()/
+ getgrppwent()/endgrppwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out group or NO PASS
 ************************************************************************/
 
 static BOOL mod_grpfilegrp_entry(DOMAIN_GRP* grp)
@@ -254,7 +260,7 @@ static struct groupdb_ops file_ops =
        getgrpfilepwpos,
        setgrpfilepwpos,
 
-       iterate_getgroupntnam,          /* In groupdb.c */
+       iterate_getgroupnam,          /* In groupdb.c */
        iterate_getgroupgid,          /* In groupdb.c */
        iterate_getgrouprid,          /* In groupdb.c */
        getgrpfilepwent,
@@ -262,7 +268,7 @@ static struct groupdb_ops file_ops =
        add_grpfilegrp_entry,
        mod_grpfilegrp_entry,
 
-       iterate_getusergroupntnam      /* in groupdb.c */
+       iterate_getusergroupsnam      /* in groupdb.c */
 };
 
 struct groupdb_ops *file_initialise_group_db(void)
index a3b1437dc2569affa17ee3dc659faf986969e77a..59ae4979fde38d7937277461f250858506ab1fda 100644 (file)
@@ -19,6 +19,9 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#ifndef _BYTEORDER_H
+#define _BYTEORDER_H
+
 /*
    This file implements macros for machine independent short and 
    int manipulation
@@ -80,9 +83,12 @@ SSVALS(buf,pos,val) - signed version of SSVAL()
 SIVALS(buf,pos,val) - signed version of SIVAL()
 
 RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
+RSVALS(buf,pos) - like SVALS() but for NMB byte ordering
 RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
+RIVALS(buf,pos) - like IVALS() but for NMB byte ordering
 RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
 RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
+RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering
 
 it also defines lots of intermediate macros, just ignore those :-)
 
@@ -91,28 +97,28 @@ it also defines lots of intermediate macros, just ignore those :-)
 /* some switch macros that do both store and read to and from SMB buffers */
 
 #define RW_PCVAL(read,inbuf,outbuf,len) \
-                if (read) { PCVAL (inbuf,0,outbuf,len) } \
-                else      { PSCVAL(inbuf,0,outbuf,len) }
+       { if (read) { PCVAL (inbuf,0,outbuf,len); } \
+       else      { PSCVAL(inbuf,0,outbuf,len); } }
 
-#define RW_PIVAL(read,inbuf,outbuf,len) \
-                if (read) { PIVAL (inbuf,0,outbuf,len) } \
-                else      { PSIVAL(inbuf,0,outbuf,len) }
+#define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
+       { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \
+       else      { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } }
 
-#define RW_PSVAL(read,inbuf,outbuf,len) \
-                if (read) { PSVAL (inbuf,0,outbuf,len) } \
-                else      { PSSVAL(inbuf,0,outbuf,len) }
+#define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
+       { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \
+       else      { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } }
 
 #define RW_CVAL(read, inbuf, outbuf, offset) \
-                if (read) (outbuf) = CVAL (inbuf,offset); \
-                else                 SCVAL(inbuf,offset,outbuf);
+       { if (read) { (outbuf) = CVAL (inbuf,offset); } \
+       else      { SCVAL(inbuf,offset,outbuf); } }
 
-#define RW_IVAL(read, inbuf, outbuf, offset) \
-                if (read) (outbuf)= IVAL (inbuf,offset); \
-                else                SIVAL(inbuf,offset,outbuf);
+#define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \
+       { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \
+       else      { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } }
 
-#define RW_SVAL(read, inbuf, outbuf, offset) \
-                if (read) (outbuf)= SVAL (inbuf,offset); \
-                else                SSVAL(inbuf,offset,outbuf);
+#define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \
+       { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \
+       else      { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } }
 
 #undef CAREFUL_ALIGNMENT
 
@@ -144,7 +150,7 @@ it also defines lots of intermediate macros, just ignore those :-)
 #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
 
-#else
+#else /* CAREFUL_ALIGNMENT */
 
 /* this handles things for architectures like the 386 that can handle
    alignment errors */
@@ -154,32 +160,26 @@ it also defines lots of intermediate macros, just ignore those :-)
 */
 
 /* get single value from an SMB buffer */
-#define SVAL(buf,pos) (*(const uint16 *)((const char *)(buf) + (pos)))
-#define IVAL(buf,pos) (*(const uint32 *)((const char *)(buf) + (pos)))
-#define SVALS(buf,pos) (*(const int16 *)((const char *)(buf) + (pos)))
-#define IVALS(buf,pos) (*(const int32 *)((const char *)(buf) + (pos)))
-
-#define SVALMOD(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
-#define IVALMOD(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
-#define SVALMODS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
-#define IVALMODS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
+#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
+#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
+#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
 
 /* store single value in an SMB buffer */
-#define SSVAL(buf,pos,val) SVALMOD(buf,pos)=((uint16)(val))
-#define SIVAL(buf,pos,val) IVALMOD(buf,pos)=((uint32)(val))
-#define SSVALS(buf,pos,val) SVALMODS(buf,pos)=((int16)(val))
-#define SIVALS(buf,pos,val) IVALMODS(buf,pos)=((int32)(val))
-
-#endif
+#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
+#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
+#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
+#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
 
+#endif /* CAREFUL_ALIGNMENT */
 
 /* macros for reading / writing arrays */
 
 #define SMBMACRO(macro,buf,pos,val,len,size) \
-{ uint32 l; for (l = 0; l < (uint32)(len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
+{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
 
 #define SSMBMACRO(macro,buf,pos,val,len,size) \
-{ uint32 l; for (l = 0; l < (uint32)(len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
+{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
 
 /* reads multiple data from an SMB buffer */
 #define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
@@ -203,46 +203,63 @@ it also defines lots of intermediate macros, just ignore those :-)
 #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
 
 #define RSVAL(buf,pos) SREV(SVAL(buf,pos))
+#define RSVALS(buf,pos) SREV(SVALS(buf,pos))
 #define RIVAL(buf,pos) IREV(IVAL(buf,pos))
+#define RIVALS(buf,pos) IREV(IVALS(buf,pos))
 #define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
+#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val))
 #define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
+#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val))
+
+/* reads multiple data from an SMB buffer (big-endian) */
+#define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2)
+#define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4)
+#define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2)
+#define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4)
+
+/* stores multiple data in an SMB buffer (big-endian) */
+#define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2)
+#define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4)
+#define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2)
+#define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4)
 
 #define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
-       RW_PCVAL(read,inbuf,outbuf,len) \
-       DEBUG(10,("%s%04x %s: ", \
+       RW_PCVAL(read,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
              tab_depth(depth), base,string)); \
-    if (charmode) print_asc(10, (unsigned char*)(outbuf), (len)); else \
-       { uint32 idx; for (idx = 0; idx < (uint32)(len); idx++) { DEBUGADD(10,("%02x ", (outbuf)[idx])); } } \
-       DEBUG(10,("\n"));
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n")); } 
 
-#define DBG_RW_PSVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
-       RW_PSVAL(read,inbuf,outbuf,len) \
-       DEBUG(10,("%s%04x %s: ", \
+#define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
+       { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
              tab_depth(depth), base,string)); \
-    if (charmode) print_asc(10, (unsigned char*)(outbuf), 2*(len)); else \
-       { uint32 idx; for (idx = 0; idx < (uint32)(len); idx++) { DEBUGADD(10,("%04x ", (outbuf)[idx])); } } \
-       DEBUG(10,("\n"));
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n")); }
 
-#define DBG_RW_PIVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
-       RW_PIVAL(read,inbuf,outbuf,len) \
-       DEBUG(10,("%s%04x %s: ", \
+#define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
+       { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
              tab_depth(depth), base,string)); \
-    if (charmode) print_asc(10, (unsigned char*)(outbuf), 4*(len)); else \
-       { uint32 idx; for (idx = 0; idx < (uint32)(len); idx++) { DEBUGADD(10,("%08x ", (outbuf)[idx])); } } \
-       DEBUG(10,("\n"));
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n")); }
 
 #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
-       RW_CVAL(read,inbuf,outbuf,0) \
-       DEBUG(10,("%s%04x %s: %02x\n", \
-             tab_depth(depth), base, string, outbuf));
+       RW_CVAL(read,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %02x\n", \
+             tab_depth(depth), base, string, outbuf)); }
 
-#define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \
-       RW_SVAL(read,inbuf,outbuf,0) \
-       DEBUG(10,("%s%04x %s: %04x\n", \
-             tab_depth(depth), base, string, outbuf));
+#define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
+       { RW_SVAL(read,big_endian,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %04x\n", \
+             tab_depth(depth), base, string, outbuf)); }
 
-#define DBG_RW_IVAL(string,depth,base,read,inbuf,outbuf) \
-       RW_IVAL(read,inbuf,outbuf,0) \
-       DEBUG(10,("%s%04x %s: %08x\n", \
-             tab_depth(depth), base, string, outbuf));
+#define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
+       { RW_IVAL(read,big_endian,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %08x\n", \
+             tab_depth(depth), base, string, outbuf)); }
 
+#endif /* _BYTEORDER_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 275f3b44da1d81a61d0737412f710abdec1b82b1..15ba66e3e12416412529f762536254fd7e3955dc 100644 (file)
@@ -27,7 +27,7 @@
 /* the client asks for a smaller buffer to save ram and also to get more
    overlap on the wire. This size gives us a nice read/write size, which
    will be a multiple of the page size on almost any system */
-#define CLI_BUFFER_SIZE (0x4400)
+#define CLI_BUFFER_SIZE (0xFFFF)
 
 /*
  * These definitions depend on smb.h
@@ -56,8 +56,22 @@ struct print_job_info
        time_t t;
 };
 
-struct cli_state
+struct pwd_info
 {
+    BOOL null_pwd;
+    BOOL cleartext;
+    BOOL crypted;
+
+    fstring password;
+
+    uchar smb_lm_pwd[16];
+    uchar smb_nt_pwd[16];
+
+    uchar smb_lm_owf[24];
+    uchar smb_nt_owf[24];
+};
+
+struct cli_state {
        int port;
        int fd;
        uint16 cnum;
@@ -69,11 +83,10 @@ struct cli_state
        int rap_error;
        int privileges;
 
-       struct ntuser_creds usr;
-       BOOL retry;
-
        fstring eff_name;
        fstring desthost;
+       fstring user_name;
+       fstring domain;
 
        /*
         * The following strings are the
@@ -88,23 +101,17 @@ struct cli_state
        fstring dev;
        struct nmb_name called;
        struct nmb_name calling;
+       fstring full_dest_host_name;
        struct in_addr dest_ip;
 
+       struct pwd_info pwd;
        unsigned char cryptkey[8];
-       unsigned char lm_cli_chal[8];
-       unsigned char nt_cli_chal[128];
-       size_t nt_cli_chal_len;
-
-       BOOL use_ntlmv2;
-       BOOL redirect;
-       BOOL reuse;
-
        uint32 sesskey;
        int serverzone;
        uint32 servertime;
        int readbraw_supported;
        int writebraw_supported;
-       int timeout;
+       int timeout; /* in milliseconds. */
        int max_xmit;
        int max_mux;
        char *outbuf;
@@ -119,16 +126,20 @@ struct cli_state
         */
 
        uint32 nt_error;                   /* NT RPC error code. */
+       uint16 nt_pipe_fnum;               /* Pipe handle. */
        unsigned char sess_key[16];        /* Current session key. */
        unsigned char ntlmssp_hash[258];   /* ntlmssp data. */
        uint32 ntlmssp_cli_flgs;           /* ntlmssp client flags */
        uint32 ntlmssp_srv_flgs;           /* ntlmssp server flags */
        uint32 ntlmssp_seq_num;            /* ntlmssp sequence number */
        DOM_CRED clnt_cred;                /* Client credential. */
+       fstring mach_acct;                 /* MYNAME$. */
+       fstring srv_name_slash;            /* \\remote server. */
+       fstring clnt_name_slash;           /* \\local client. */
        uint16 max_xmit_frag;
        uint16 max_recv_frag;
-};
 
-struct cli_connection;
+       BOOL use_oplocks; /* should we use oplocks? */
+};
 
 #endif /* _CLIENT_H */
index 5f0f4526d8a3ca4ca7d9aa2a5505e7947f1608e6..5858d303f5bd7cac66f3cf94e4d828c56f0647cd 100644 (file)
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef gid_t
 
+/* Define if your system has a working fnmatch function.  */
+#undef HAVE_FNMATCH
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
 /* Define if your struct stat has st_rdev.  */
 #undef HAVE_ST_RDEV
 
@@ -30,6 +36,9 @@
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef mode_t
 
+/* Define if your C compiler doesn't accept -c and -o together.  */
+#undef NO_MINUS_C_MINUS_O
+
 /* Define to `long' if <sys/types.h> doesn't define.  */
 #undef off_t
 
@@ -55,6 +64,7 @@
    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
 #undef WORDS_BIGENDIAN
 
+#undef HAVE_VOLATILE
 #undef HAVE_BROKEN_READDIR
 #undef HAVE_ERRNO_DECL
 #undef HAVE_LONGLONG
@@ -62,6 +72,7 @@
 #undef HAVE_REMSH
 #undef HAVE_UNSIGNED_CHAR
 #undef HAVE_UTIMBUF
+#undef HAVE_SIG_ATOMIC_T_TYPE
 #undef ssize_t
 #undef ino_t
 #undef ssize_t
 #undef AIX
 #undef BSD
 #undef IRIX
+#undef IRIX6
 #undef HPUX
 #undef QNX
 #undef SCO
 #undef OSF1
 #undef NEXT2
+#undef RELIANTUNIX
 #undef HAVE_SHARED_MMAP
+#undef HAVE_MMAP
 #undef HAVE_SYSV_IPC
 #undef HAVE_FCNTL_LOCK
 #undef HAVE_FTRUNCATE_EXTEND
+#undef FTRUNCATE_NEEDS_ROOT
 #undef HAVE_TRAPDOOR_UID
 #undef HAVE_ROOT
 #undef HAVE_UNION_SEMUN
-#undef HAVE_NETMASK_IFCONF
 #undef HAVE_GETTIMEOFDAY_TZ
 #undef HAVE_SOCK_SIN_LEN
 #undef STAT_READ_FILSYS
 #undef STAT_STATFS4
 #undef STAT_STATVFS
 #undef STAT_STATVFS64
-#undef HAVE_NETMASK_IFREQ
-#undef HAVE_NETMASK_AIX
+#undef HAVE_IFACE_AIX
+#undef HAVE_IFACE_IFCONF
+#undef HAVE_IFACE_IFREQ
 #undef HAVE_CRYPT
 #undef HAVE_PUTPRPWNAM
 #undef HAVE_SET_AUTH_PARAMETERS
-#undef WITH_MMAP
 #undef WITH_SYSLOG
 #undef WITH_PROFILE
 #undef WITH_SSL
 #undef WITH_LDAP
 #undef WITH_NISPLUS
+#undef WITH_PAM
 #undef WITH_NISPLUS_HOME
 #undef WITH_AUTOMOUNT
 #undef WITH_SMBMOUNT
-#undef HAVE_PAM_AUTHENTICATE
 #undef HAVE_BROKEN_GETGROUPS
 #undef REPLACE_GETPASS
 #undef REPLACE_INET_NTOA
 #undef HAVE_FILE_MACRO
 #undef HAVE_FUNCTION_MACRO
 #undef HAVE_SETRESUID_DECL
-#undef HAVE_CRYPT_DECL
 #undef HAVE_SETRESUID
 #undef WITH_NETATALK
 #undef HAVE_INO64_T
 #undef SIZEOF_OFF_T
 #undef STAT_STATVFS64
 #undef HAVE_LIBREADLINE
-#undef HAVE_READLINE_FCF_PROTO
 #undef HAVE_KERNEL_OPLOCKS
 #undef HAVE_IRIX_SPECIFIC_CAPABILITIES
 #undef HAVE_INT16_FROM_RPC_RPC_H
 #undef HAVE_INT32_FROM_RPC_RPC_H
 #undef HAVE_UINT32_FROM_RPC_RPC_H
 #undef KRB4_AUTH
+#undef KRB5_AUTH
 #undef SEEKDIR_RETURNS_VOID
 #undef HAVE_DIRENT_D_OFF
 #undef HAVE_GETSPNAM
 #undef HAVE_BIGCRYPT
 #undef HAVE_GETPRPWNAM
+#undef HAVE_FSTAT64
+#undef HAVE_LSTAT64
+#undef HAVE_STAT64
+#undef HAVE_SETRESGID
+#undef HAVE_SETRESGID_DECL
+#undef HAVE_SHADOW_H
+#undef HAVE_MEMSET
+#undef HAVE_STRCASECMP
+#undef HAVE_STRUCT_DIRENT64
+#undef HAVE_TRUNCATED_SALT
+#undef BROKEN_NISPLUS_INCLUDE_FILES
+#undef HAVE_RPC_AUTH_ERROR_CONFLICT
+#undef HAVE_EXPLICIT_LARGEFILE_SUPPORT
+#undef USE_BOTH_CRYPT_CALLS
+#undef HAVE_BROKEN_FCNTL64_LOCKS
+#undef HAVE_FNMATCH
+#undef USE_SETEUID
+#undef USE_SETRESUID
+#undef USE_SETREUID
+#undef USE_SETUIDX
 
 /* The number of bytes in a int.  */
 #undef SIZEOF_INT
 /* Define if you have the execl function.  */
 #undef HAVE_EXECL
 
+/* Define if you have the fcvt function.  */
+#undef HAVE_FCVT
+
+/* Define if you have the fcvtl function.  */
+#undef HAVE_FCVTL
+
 /* Define if you have the fopen64 function.  */
 #undef HAVE_FOPEN64
 
 /* Define if you have the fseek64 function.  */
 #undef HAVE_FSEEK64
 
+/* Define if you have the fseeko64 function.  */
+#undef HAVE_FSEEKO64
+
 /* Define if you have the fstat function.  */
 #undef HAVE_FSTAT
 
 /* Define if you have the ftell64 function.  */
 #undef HAVE_FTELL64
 
+/* Define if you have the ftello64 function.  */
+#undef HAVE_FTELLO64
+
 /* Define if you have the ftruncate function.  */
 #undef HAVE_FTRUNCATE
 
 /* Define if you have the getdents function.  */
 #undef HAVE_GETDENTS
 
+/* Define if you have the getgrent function.  */
+#undef HAVE_GETGRENT
+
 /* Define if you have the getgrnam function.  */
 #undef HAVE_GETGRNAM
 
 /* Define if you have the open64 function.  */
 #undef HAVE_OPEN64
 
-/* Define if you have the pam_authenticate function.  */
-#undef HAVE_PAM_AUTHENTICATE
-
 /* Define if you have the pathconf function.  */
 #undef HAVE_PATHCONF
 
 /* Define if you have the setenv function.  */
 #undef HAVE_SETENV
 
+/* Define if you have the setgidx function.  */
+#undef HAVE_SETGIDX
+
 /* Define if you have the setgroups function.  */
 #undef HAVE_SETGROUPS
 
 /* Define if you have the setnetgrent function.  */
 #undef HAVE_SETNETGRENT
 
+/* Define if you have the setpriv function.  */
+#undef HAVE_SETPRIV
+
 /* Define if you have the setsid function.  */
 #undef HAVE_SETSID
 
 /* Define if you have the stat64 function.  */
 #undef HAVE_STAT64
 
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
 /* Define if you have the strchr function.  */
 #undef HAVE_STRCHR
 
 /* Define if you have the syscall function.  */
 #undef HAVE_SYSCALL
 
-/* Define if you have the tputs function.  */
-#undef HAVE_TPUTS
+/* Define if you have the usleep function.  */
+#undef HAVE_USLEEP
 
 /* Define if you have the utime function.  */
 #undef HAVE_UTIME
 /* Define if you have the yp_get_default_domain function.  */
 #undef HAVE_YP_GET_DEFAULT_DOMAIN
 
+/* Define if you have the <arpa/inet.h> header file.  */
+#undef HAVE_ARPA_INET_H
+
 /* Define if you have the <compat.h> header file.  */
 #undef HAVE_COMPAT_H
 
 /* Define if you have the <memory.h> header file.  */
 #undef HAVE_MEMORY_H
 
-/* Define if you have the <mysql.h> header file.  */
-#undef HAVE_MYSQL_H
-
 /* Define if you have the <ndir.h> header file.  */
 #undef HAVE_NDIR_H
 
 /* Define if you have the <net/if.h> header file.  */
 #undef HAVE_NET_IF_H
 
-/* Define if you have the <net/route.h> header file.  */
-#undef HAVE_NET_ROUTE_H
+/* Define if you have the <netinet/in_ip.h> header file.  */
+#undef HAVE_NETINET_IN_IP_H
+
+/* Define if you have the <netinet/in_systm.h> header file.  */
+#undef HAVE_NETINET_IN_SYSTM_H
+
+/* Define if you have the <netinet/ip.h> header file.  */
+#undef HAVE_NETINET_IP_H
 
 /* Define if you have the <netinet/tcp.h> header file.  */
 #undef HAVE_NETINET_TCP_H
 /* Define if you have the <rpc/rpc.h> header file.  */
 #undef HAVE_RPC_RPC_H
 
+/* Define if you have the <rpcsvc/nis.h> header file.  */
+#undef HAVE_RPCSVC_NIS_H
+
 /* Define if you have the <rpcsvc/yp_prot.h> header file.  */
 #undef HAVE_RPCSVC_YP_PROT_H
 
 /* Define if you have the <sys/param.h> header file.  */
 #undef HAVE_SYS_PARAM_H
 
+/* Define if you have the <sys/priv.h> header file.  */
+#undef HAVE_SYS_PRIV_H
+
 /* Define if you have the <sys/resource.h> header file.  */
 #undef HAVE_SYS_RESOURCE_H
 
 /* Define if you have the <sys/select.h> header file.  */
 #undef HAVE_SYS_SELECT_H
 
-/* Define if you have the <sys/un.h> header file.  */
-#undef HAVE_SYS_UN_H
-
 /* Define if you have the <sys/socket.h> header file.  */
 #undef HAVE_SYS_SOCKET_H
 
 /* Define if you have the <sys/syscall.h> header file.  */
 #undef HAVE_SYS_SYSCALL_H
 
+/* Define if you have the <sys/termio.h> header file.  */
+#undef HAVE_SYS_TERMIO_H
+
 /* Define if you have the <sys/time.h> header file.  */
 #undef HAVE_SYS_TIME_H
 
 /* Define if you have the <syscall.h> header file.  */
 #undef HAVE_SYSCALL_H
 
+/* Define if you have the <termio.h> header file.  */
+#undef HAVE_TERMIO_H
+
 /* Define if you have the <termios.h> header file.  */
 #undef HAVE_TERMIOS_H
 
 /* Define if you have the <utime.h> header file.  */
 #undef HAVE_UTIME_H
 
+/* Define if you have the cups library (-lcups).  */
+#undef HAVE_LIBCUPS
+
 /* Define if you have the dl library (-ldl).  */
 #undef HAVE_LIBDL
 
+/* Define if you have the gen library (-lgen).  */
+#undef HAVE_LIBGEN
+
 /* Define if you have the inet library (-linet).  */
 #undef HAVE_LIBINET
 
index ee3989d02835a612cf03e3c0e038f8890d6d968f..2a10badd73ddb326d9cf8c0805d43df5d7bef474 100644 (file)
 #undef HAVE_TERMIOS_H
 #endif
 
+#ifdef LINUX
+#define DEFAULT_PRINTING PRINT_BSD
+#define PRINTCAP_NAME "/etc/printcap"
+#endif
+
+#ifdef RELIANTUNIX
+/*
+ * <unistd.h> has to be included before any other to get
+ * large file support on Reliant UNIX
+ */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#endif /* RELIANTUNIX */
+
+#ifdef HAVE_SYSV_IPC
+#define USE_SYSV_IPC
+#endif
 
-/* if we have both SYSV IPC and shared mmap then we need to
-   choose. For most systems it is much faster to use SYSV IPC. We used
-   to make an exception for Linux, but now Linux 2.2 has made it
-   better to use sysv if possible */
-#if (defined(HAVE_SYSV_IPC) && defined(HAVE_SHARED_MMAP))
-#  undef HAVE_SHARED_MMAP
+#ifdef HAVE_SHARED_MMAP
+#define USE_SHARED_MMAP
 #endif
 
 
+/* if we have both SYSV IPC and shared mmap then we need to choose */
+#if (defined(USE_SYSV_IPC) && defined(USE_SHARED_MMAP))
+#  undef USE_SHARED_MMAP
+#endif
+
 #include <sys/types.h>
 
 #ifdef TIME_WITH_SYS_TIME
 #include <stdio.h>
 #include <stddef.h>
 
-#include <netinet/in.h>
-#if defined(HAVE_RPC_RPC_H)
-#include <rpc/rpc.h>
-#endif
-
 #ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
 #include <sys/socket.h>
 #endif
 
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
-
 #ifdef HAVE_SYS_SYSCALL_H
 #include <sys/syscall.h>
 #elif HAVE_SYSCALL_H
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif
+#ifdef HAVE_SYS_PRIV_H
+#include <sys/priv.h>
+#endif
 #ifdef HAVE_SYS_ID_H
 #include <sys/id.h>
 #endif
 #include <varargs.h>
 #endif
 
+#include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <syslog.h>
 #include <netinet/tcp.h>
 #endif
 
-#ifdef HAVE_TERMIOS_H
+/*
+ * The next three defines are needed to access the IPTOS_* options
+ * on some systems.
+ */
+
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_IP_H
+#include <netinet/in_ip.h>
+#endif
+
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+
+#if defined(HAVE_TERMIOS_H)
+/* POSIX terminal handling. */
 #include <termios.h>
+#elif defined(HAVE_TERMIO_H)
+/* Older SYSV terminal handling - don't use if we can avoid it. */
+#include <termio.h>
+#elif defined(HAVE_SYS_TERMIO_H)
+/* Older SYSV terminal handling - don't use if we can avoid it. */
+#include <sys/termio.h>
 #endif
 
 #if HAVE_DIRENT_H
 #include <sys/sem.h>
 #endif
 
-#if 0
-/*
- *  I have removed this as it prevents compilation under SCO Server
- *  3.2. If you need to add it back in then please add a comment as to
- *  why it's needed and what OS it's needed for so we can work out how
- *  to test for it properly (tridge) */
-#ifdef HAVE_NET_ROUTE_H
-#include <net/route.h>
-#endif
-#endif
-
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
 #endif
 
 #if defined(HAVE_RPC_RPC_H)
+/*
+ * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h.
+ */
+#if defined(HAVE_SYS_SECURITY_H) && defined(HAVE_RPC_AUTH_ERROR_CONFLICT)
+#undef AUTH_ERROR
+#endif
 #include <rpc/rpc.h>
 #endif
 
 #endif
 #endif /* HAVE_NETGROUP */
 
-#if defined(HAVE_MYSQL_H)
-#include <mysql.h>
+/*
+ * Define VOLATILE if needed.
+ */
+
+#if defined(HAVE_VOLATILE)
+#define VOLATILE volatile
 #else
-/* needed to get make proto to work with no <mysql.h> */
-#define MYSQL     void
-#define MYSQL_ROW void
+#define VOLATILE
+#endif
+
+/*
+ * Define SIG_ATOMIC_T if needed.
+ */
+
+#if defined(HAVE_SIG_ATOMIC_T_TYPE)
+#define SIG_ATOMIC_T sig_atomic_t
+#else
+#define SIG_ATOMIC_T int
 #endif
 
 #ifndef uchar
  */
 
 #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
  */
 
 #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
@@ -555,11 +614,20 @@ extern int errno;
 #include "ubi_sLinkList.h"
 #include "ubi_dLinkList.h"
 #include "dlinklist.h"
+#include "interfaces.h"
+
+#ifdef HAVE_FNMATCH
+#include <fnmatch.h>
+#else
+#include "fnmatch.h"
+#endif
 
 #ifndef UBI_BINTREE_H
 #include "ubi_Cache.h"
 #endif /* UBI_BINTREE_H */
 
+#include "debugparse.h"
+
 #include "version.h"
 #include "smb.h"
 #include "smbw.h"
@@ -583,9 +651,25 @@ extern int errno;
 /***** automatically generated prototypes *****/
 #include "proto.h"
 
-/* String routines */
+#ifdef strcpy
+#undef strcpy
+#endif /* strcpy */
+#define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___;
+
+#ifdef strcat
+#undef strcat
+#endif /* strcat */
+#define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___;
+
+#ifdef sprintf
+#undef sprintf
+#endif /* sprintf */
+#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
 
-#include "safe_string.h"
+#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1)
+#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1)
+#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
+#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
 
 #ifdef __COMPAR_FN_T
 #define QSORT_CAST (__compar_fn_t)
@@ -596,12 +680,15 @@ extern int errno;
 #endif
 
 /* this guess needs to be improved (tridge) */
-#if defined(STAT_STATVFS) && !defined(SYSV)
+#if (defined(STAT_STATVFS) || defined(STAT_STATVFS64)) && !defined(SYSV)
 #define SYSV 1
 #endif
 
 #ifndef DEFAULT_PRINTING
-#ifdef SYSV
+#ifdef HAVE_LIBCUPS
+#define DEFAULT_PRINTING PRINT_CUPS
+#define PRINTCAP_NAME "cups"
+#elif defined(SYSV)
 #define DEFAULT_PRINTING PRINT_SYSV
 #define PRINTCAP_NAME "lpstat"
 #else
@@ -638,17 +725,12 @@ union semun {
 
 #if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP))
 #define USE_SMBPASS_DB 1
-#define USE_SMBUNIX_DB 1
 #endif
 
 #if defined(HAVE_PUTPRPWNAM) && defined(AUTH_CLEARTEXT_SEG_CHARS)
 #define OSF1_ENH_SEC 1
 #endif
 
-#if defined(HAVE_PAM_AUTHENTICATE) && defined(HAVE_SECURITY_PAM_APPL_H)
-#define HAVE_PAM 1
-#endif
-
 #ifndef ALLOW_CHANGE_PASSWORD
 #if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID))
 #define ALLOW_CHANGE_PASSWORD 1
@@ -673,10 +755,6 @@ union semun {
 #define MAXPATHLEN 256
 #endif
 
-#ifndef MAX_SERVER_POLICY_HANDLES
-#define MAX_SERVER_POLICY_HANDLES 64
-#endif
-
 #ifndef SEEK_SET
 #define SEEK_SET 0
 #endif
@@ -697,14 +775,6 @@ union semun {
 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
 #endif
 
-#ifndef SHM_R
-#define SHM_R (0400)
-#endif
-
-#ifndef SHM_W
-#define SHM_W (0200)
-#endif
-
 #if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID)
 #define ULTRIX_AUTH 1
 #endif
@@ -725,14 +795,6 @@ union semun {
 #      undef HAVE_LIBREADLINE
 #    endif
 #  endif
-
-/* Some old versions of readline don't define a prototype for
-   filename_completion_function() */
-
-#  ifndef HAVE_READLINE_FCF_PROTO
-char *filename_completion_function(void);
-#  endif
-
 #endif
 
 #ifndef HAVE_STRDUP
@@ -759,15 +821,16 @@ time_t mktime(struct tm *t);
 int ftruncate(int f,long l);
 #endif
 
-#if (defined(HAVE_SETRESUID) && !defined(HAVE_SETRESUID_DECL))
-/* stupid glibc */
-int setresuid(uid_t ruid, uid_t euid, uid_t suid);
-int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+#ifndef HAVE_STRTOUL
+unsigned long strtoul(const char *nptr, char **endptr, int base);
 #endif
 
-#if (defined(HAVE_CRYPT) && !defined(HAVE_CRYPT_DECL) && !defined(KRB4_AUTH))
+#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL))
 /* stupid glibc */
-int crypt(const char *key, const char *salt);
+int setresuid(uid_t ruid, uid_t euid, uid_t suid);
+#endif
+#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL))
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
 #endif
 
 #if !defined(HAVE_BZERO) && defined(HAVE_MEMSET)
@@ -778,7 +841,32 @@ int crypt(const char *key, const char *salt);
 #define getpass(prompt) getsmbpass((prompt))
 #endif
 
+/*
+ * 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
+
 #endif /* _INCLUDES_H */
index e6e2fd4badb3b97769c7eab97e6a05cec69cea38..961670f3a68965c1fe4fe60fae27953b0baf2d29 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
 #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)
 #define NMBD_INETD_TIMEOUT (120)
 #define NMBD_MAX_TTL (24*60*60)
 #define LPQ_LOCK_TIMEOUT (5)
+#define NMBD_INTERFACES_RELOAD (120)
 
 /* the following are in milliseconds */
 #define LOCK_RETRY_TIMEOUT (100)
 /* 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 0de00f363689a825f0c10a88b9cdf666fdb2389a..3473c74a56a700c145ff4c2c6f8558bdf279cd91 100644 (file)
@@ -142,7 +142,7 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH,
 enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME, 
                   DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME};
 enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
-enum packet_type {NMB_PACKET, DGRAM_PACKET, NMB_SOCK_PACKET, DGRAM_SOCK_PACKET };
+enum packet_type {NMB_PACKET, DGRAM_PACKET};
 
 enum master_state
 {
@@ -501,7 +501,6 @@ struct packet_struct
 #define QUERYFORPDC_R  12 /* Response to Query for PDC. */
 #define SAMLOGON       18
 #define SAMLOGON_R     19
-#define SAMLOGON_UNK_R 21
 
 
 /* Ids for netbios packet types. */
@@ -547,11 +546,6 @@ struct packet_struct
    affects non-permanent self names (in seconds) */
 #define MAX_REFRESH_TIME (60*20)
 
-/* Types of machine we can announce as. */
-#define ANNOUNCE_AS_NT 1
-#define ANNOUNCE_AS_WIN95 2
-#define ANNOUNCE_AS_WFW 3
-
 /* Macro's to enumerate subnets either with or without
    the UNICAST subnet. */
 
index 096e7cd66cab28bef1fd2986aea35d6472f19874..d066ef3e36f3e20947d78cd63bfd1c13a2b303c1 100644 (file)
 #include "rpc_reg.h"
 #include "rpc_samr.h"
 #include "rpc_srvsvc.h"
-#include "rpc_svcctl.h"
 #include "rpc_wkssvc.h"
-#include "rpc_brs.h"
-#include "rpc_atsvc.h"
-#include "rpc_spoolss.h"
-#include "rpc_eventlog.h"
 
 /* 
  * A bunch of stuff that was put into smb.h
  * in the NTDOM branch - it didn't belong there.
  */
  
-typedef struct
+typedef struct _prs_struct 
 {
-       struct mem_buf *data; /* memory buffer */
-       uint32 offset; /* offset currently being accessed in memory buffer */
-       uint8 align; /* data alignment */
        BOOL io; /* parsing in or out of data stream */
-       BOOL error; /* error occurred */
-
+       /* 
+        * If the (incoming) data is big-endian. On output we are
+        * always little-endian.
+        */ 
+       BOOL bigendian_data;
+       uint8 align; /* data alignment */
+       BOOL is_dynamic; /* Do we own this memory or not ? */
+       uint32 data_offset; /* Current working offset into data. */
+       uint32 buffer_size; /* Current size of the buffer. */
+       char *data_p; /* The buffer itself. */
 } prs_struct;
 
-typedef struct rpcsrv_struct
-{
-       prs_struct rhdr; /* output header */
-       prs_struct rfault; /* fault */
-       prs_struct rdata; /* output data */
-       prs_struct rdata_i; /* output data (intermediate, for fragments) */
-       prs_struct rauth; /* output authentication verifier */
-       prs_struct rverf; /* output verifier */
-       prs_struct rntlm; /* output ntlmssp */
-
-       RPC_HDR       hdr;
-       RPC_HDR_BA    hdr_ba;
-       RPC_HDR_RB    hdr_rb;
-       RPC_HDR_REQ   hdr_req;
-       RPC_HDR_RESP  hdr_resp;
-       RPC_HDR_FAULT hdr_fault;
-       RPC_HDR_AUTH  auth_info;
-       RPC_HDR_AUTHA autha_info;
-
-       RPC_AUTH_NTLMSSP_VERIFIER auth_verifier;
-       RPC_AUTH_NTLMSSP_NEG      ntlmssp_neg;
-       RPC_AUTH_NTLMSSP_CHAL     ntlmssp_chal;
-       RPC_AUTH_NTLMSSP_RESP     ntlmssp_resp;
-       RPC_AUTH_NTLMSSP_CHK      ntlmssp_chk;
-
-       BOOL ntlmssp_auth;
-       BOOL ntlmssp_validated;
-       unsigned char ntlmssp_hash[258];
-       uint32 ntlmssp_seq_num;
-       fstring user_name;
-       fstring domain;
-       fstring wks;
-
-       uchar user_sess_key[16];
+/*
+ * Defines for io member of prs_struct.
+ */
 
-       /* per-user authentication info.  hmm, this not appropriate, but
-          it will do for now.  dcinfo contains NETLOGON-specific info,
-          so have to think of a better method.
-        */
-       struct dcinfo dc;
+#define MARSHALL 0
+#define UNMARSHALL 1
 
-} rpcsrv_struct;
+#define MARSHALLING(ps) (!(ps)->io)
+#define UNMARSHALLING(ps) ((ps)->io)
 
 typedef struct pipes_struct
 {
@@ -117,120 +84,73 @@ typedef struct pipes_struct
        fstring name;
        fstring pipe_srv_name;
 
-       /* remote, server-side rpc redirection */
-       struct msrpc_state *m;
+       RPC_HDR hdr; /* Incoming RPC header. */
+       RPC_HDR_REQ hdr_req; /* Incoming request header. */
+
+       uint32 ntlmssp_chal_flags; /* Client challenge flags. */
+       BOOL ntlmssp_auth_requested; /* If the client wanted authenticated rpc. */
+       BOOL ntlmssp_auth_validated; /* If the client *got* authenticated rpc. */
+       unsigned char challenge[8];
+       unsigned char ntlmssp_hash[258];
+       uint32 ntlmssp_seq_num;
+
+       /*
+        * Windows user info.
+        */
+       fstring user_name;
+       fstring domain;
+       fstring wks;
+
+       /*
+        * Unix user name and credentials.
+        */
+       fstring unix_user_name;
+       uid_t uid;
+       gid_t gid;
+
+       /* 
+        * Raw RPC output data. This does not include RPC headers or footers.
+        */
+       prs_struct rdata;
+
+       /* The amount of data sent from the current rdata struct. */
+       uint32 data_sent_length;
 
-       /* local, server-side rpc state processing */
-       rpcsrv_struct *l;
+       /* 
+        * The current PDU being returned. This inclues
+        * headers, data and authentication footer.
+        */
+       unsigned char current_pdu[MAX_PDU_FRAG_LEN];
 
-       /* to store pdus being constructed / communicated from smb to msrpc */
-       prs_struct smb_pdu;
-       prs_struct rsmb_pdu;
+       /* The amount of data in the current_pdu buffer. */
+       uint32 current_pdu_len;
 
-       /* state-based info used in processing smbs to/from msrpc pdus */ 
-       uint32 file_offset;
-       uint32 prev_pdu_file_offset;
-       uint32 hdr_offsets;
+       /* The amount of data sent from the current PDU. */
+       uint32 current_pdu_sent;
 
+       /* When replying to an SMBtrans, this is the maximum amount of
+           data that can be sent in the initial reply. */
+       int max_trans_reply;
 } pipes_struct;
 
 struct api_struct
 {  
   char *name;
   uint8 opnum;
-  void (*fn) (rpcsrv_struct*, prs_struct*, prs_struct*);
+  BOOL (*fn) (uint16 vuid, prs_struct*, prs_struct*);
 };
 
-struct mem_desc
-{  
-       /* array memory offsets */
-       uint32 start; 
-       uint32 end;
-};
-   
-struct mem_buf
+typedef struct
 {  
-       BOOL dynamic; /* True iff data has been dynamically allocated
-                                        (and therefore can be freed) */
-       char *data;
-       uint32 data_size;
-       uint32 data_used;
-
-       uint32 margin; /* safety margin when reallocing. */
-                                  /* this can be abused quite nicely */
-       uint8 align;   /* alignment of data structures (smb, dce/rpc, udp etc) */
+       uint32 rid;
+       char *name;
 
-       struct mem_desc offset;
-
-       struct mem_buf *next;
-};
+} rid_name;
 
 struct acct_info
 {
     fstring acct_name; /* account name */
-    fstring acct_desc; /* account description */
-    uint32  rid; /* domain-relative RID */
+    uint32 smb_userid; /* domain-relative RID */
 };
 
-/*
- * higher order functions for use with msrpc client code
- */
-
-#define ALIAS_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, const char*)
-#define ALIAS_INFO_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, ALIAS_INFO_CTR *const)
-#define ALIAS_MEM_FN(fn)\
-       void(*fn)(const char*, const DOM_SID*, uint32, const char*,\
-                 uint32, DOM_SID *const *const, char *const *const,\
-                 uint8*const)
-
-#define GROUP_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, const char*)
-#define GROUP_INFO_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, GROUP_INFO_CTR *const)
-#define GROUP_MEM_FN(fn)\
-       void(*fn)(const char*, const DOM_SID*, uint32, const char*,\
-                 uint32, const uint32*, char *const *const,\
-                 uint32*const)
-
-#define DOMAIN_FN(fn)\
-       void (*fn)(const char*)
-#define DOMAIN_INFO_FN(fn)\
-       void (*fn)(const char*, const DOM_SID *, uint32, SAM_UNK_CTR *)
-
-#define USER_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, const char*)
-#define USER_INFO_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32,\
-                  SAM_USER_INFO_21 *const)
-#define USER_MEM_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint32, const char*,\
-                  uint32, const uint32*, char *const *const, uint32* const)
-
-#define DISP_FN(fn)\
-       void (*fn)(const char*, const DOM_SID*, uint16, uint32, \
-                  SAM_DISPINFO_CTR *)
-
-#define REG_FN(fn)\
-       void (*fn)(int, const char *, int)
-#define REG_KEY_FN(fn)\
-       void (*fn)(const char*, const char*, time_t)
-#define REG_VAL_FN(fn)\
-       void (*fn)(const char *, const char*, uint32, const BUFFER2 *)
-
-#define SVC_QUERY_FN(fn)\
-       void (*fn)(const QUERY_SERVICE_CONFIG *)
-#define SVC_INFO_FN(fn)\
-       void (*fn)(const ENUM_SRVC_STATUS *)
-
-#define TPRT_INFO_FN(fn)\
-       void (*fn)(const SRV_TPRT_INFO_CTR *)
-
-#define PRINT_INFO_FN(fn)\
-       void (*fn)(const char*, uint32, uint32, void  *const *const)
-#define JOB_INFO_FN(fn)\
-       void (*fn)(const char*, const char*, uint32, uint32, void *const *const)
-
 #endif /* _NT_DOMAIN_H */
-
index 86c049495c959936e21e221bc4cc7da1c985b443..a94464a013e9fc298eb0e1e8d29d0c70a0b6c5cb 100644 (file)
@@ -1,12 +1,3 @@
-/* Win32 Status codes. */
-
-#define STATUS_BUFFER_OVERFLOW (5)
-#define STATUS_MORE_ENTRIES (0x105)
-#define ERROR_INVALID_HANDLE             (6)
-#define ERROR_INVALID_PARAMETER                 (87)
-#define ERROR_INSUFFICIENT_BUFFER      (122)
-
-
 /* these are the NT error codes less than 1000. They are here for when
    we start supporting NT error codes in Samba. They were extracted
    using a loop in smbclient then printing a netmon sniff to a file */
@@ -16,6 +7,7 @@
 #define NT_STATUS_INVALID_INFO_CLASS (3)
 #define NT_STATUS_INFO_LENGTH_MISMATCH (4)
 #define NT_STATUS_ACCESS_VIOLATION (5)
+#define STATUS_BUFFER_OVERFLOW (5)
 #define NT_STATUS_IN_PAGE_ERROR (6)
 #define NT_STATUS_PAGEFILE_QUOTA (7)
 #define NT_STATUS_INVALID_HANDLE (8)
 #define NT_STATUS_QUOTA_LIST_INCONSISTENT (614)
 #define NT_STATUS_FILE_IS_OFFLINE (615)
 #define NT_STATUS_NOTIFY_ENUM_DIR (0x10C)
-#define NT_STATUS_NO_SUCH_JOB (0xEDE) /* scheduler */
index 353f6a6b4296642352540b51ae44f1c626b54970..0924dc293729e70d8ebd84482f69bb6d97665c1b 100644 (file)
 /* this file defines the profile structure in the profile shared
    memory area */
 
+#define PROF_SHMEM_KEY ((key_t)0x07021999)
+#define PROF_SHM_MAGIC 0x6349985
+#define PROF_SHM_VERSION 1
+
 struct profile_struct {
+       int prof_shm_magic;
+       int prof_shm_version;
        unsigned smb_count; /* how many SMB packets we have processed */
        unsigned uid_changes; /* how many times we change our effective uid */
 };
index 3c37085160305fa140ac3813caf6baef0485b128..25d95323bc69ed0f58738f65adda5654a93cd483 100644 (file)
@@ -3,15 +3,10 @@
 /* This file is automatically generated with "make proto". DO NOT EDIT */
 
 
-/*The following definitions come from  browserd/browserd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
 /*The following definitions come from  client/client.c  */
 
 void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs);
-struct cli_state *do_connect(char *server, char *share, int smb_port);
+struct cli_state *do_connect(char *server, char *share);
 
 /*The following definitions come from  client/clitar.c  */
 
@@ -22,121 +17,6 @@ void cmd_tar(void);
 int process_tar(void);
 int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
 
-/*The following definitions come from  groupdb/aliasdb.c  */
-
-BOOL initialise_alias_db(void);
-LOCAL_GRP *iterate_getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *iterate_getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als);
-BOOL iterate_getuseraliasntnam(const char *user_name, LOCAL_GRP **alss, int *num_alss);
-BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss);
-void *startaliasent(BOOL update);
-void endaliasent(void *vp);
-LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL add_alias_entry(LOCAL_GRP *newgrp);
-BOOL mod_alias_entry(LOCAL_GRP* als);
-BOOL del_alias_entry(uint32 rid);
-BOOL add_alias_member(uint32 rid, DOM_SID *member_sid);
-BOOL del_alias_member(uint32 rid, DOM_SID *member_sid);
-LOCAL_GRP *getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *getaliasrid(uint32 alias_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL getuseraliasntnam(const char *user_name, LOCAL_GRP **als, int *num_alss);
-void aldb_init_als(LOCAL_GRP *als);
-BOOL make_alias_line(char *p, int max_len,
-                               LOCAL_GRP *als,
-                               LOCAL_GRP_MEMBER **mem, int *num_mem);
-
-/*The following definitions come from  groupdb/aliasfile.c  */
-
-struct aliasdb_ops *file_initialise_alias_db(void);
-
-/*The following definitions come from  groupdb/aliasldap.c  */
-
-struct aliasdb_ops *ldap_initialise_alias_db(void);
-
-/*The following definitions come from  groupdb/aliasunix.c  */
-
-BOOL get_unixalias_members(struct group *grp,
-                               int *num_mem, LOCAL_GRP_MEMBER **members);
-struct aliasdb_ops *unix_initialise_alias_db(void);
-
-/*The following definitions come from  groupdb/builtindb.c  */
-
-BOOL initialise_builtin_db(void);
-LOCAL_GRP *iterate_getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *iterate_getbuiltinrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *iterate_getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL add_domain_builtin(LOCAL_GRP **blts, int *num_blts, LOCAL_GRP *blt);
-BOOL iterate_getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blts, int *num_blts);
-BOOL enumdombuiltins(LOCAL_GRP **blts, int *num_blts);
-void *startbuiltinent(BOOL update);
-void endbuiltinent(void *vp);
-LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL add_builtin_entry(LOCAL_GRP *newblt);
-BOOL mod_builtin_entry(LOCAL_GRP* blt);
-BOOL add_builtin_member(uint32 rid, DOM_SID *member_sid);
-BOOL del_builtin_member(uint32 rid, DOM_SID *member_sid);
-LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
-BOOL getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blt, int *num_blts);
-void bidb_init_blt(LOCAL_GRP *blt);
-BOOL make_builtin_line(char *p, int max_len,
-                               LOCAL_GRP *blt,
-                               LOCAL_GRP_MEMBER **mem, int *num_mem);
-
-/*The following definitions come from  groupdb/builtinldap.c  */
-
-struct aliasdb_ops *ldap_initialise_builtin_db(void);
-
-/*The following definitions come from  groupdb/builtinunix.c  */
-
-BOOL get_unixbuiltin_members(struct group *grp,
-                               int *num_mem, LOCAL_GRP_MEMBER **members);
-struct aliasdb_ops *unix_initialise_builtin_db(void);
-
-/*The following definitions come from  groupdb/groupdb.c  */
-
-BOOL initialise_group_db(void);
-DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-DOMAIN_GRP *iterate_getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp);
-BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num_grps);
-BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps);
-void *startgroupent(BOOL update);
-void endgroupent(void *vp);
-DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-BOOL add_group_entry(DOMAIN_GRP *newgrp);
-BOOL del_group_entry(uint32 rid);
-BOOL mod_group_entry(DOMAIN_GRP* grp);
-BOOL add_group_member(uint32 rid, uint32 member_rid);
-BOOL del_group_member(uint32 rid, uint32 member_rid);
-DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
-BOOL getusergroupsntnam(const char *user_name, DOMAIN_GRP **grp, int *num_grps);
-void gpdb_init_grp(DOMAIN_GRP *grp);
-BOOL make_group_line(char *p, int max_len,
-                               DOMAIN_GRP *grp,
-                               DOMAIN_GRP_MEMBER **mem, int *num_mem);
-
-/*The following definitions come from  groupdb/groupfile.c  */
-
-struct groupdb_ops *file_initialise_group_db(void);
-
-/*The following definitions come from  groupdb/groupldap.c  */
-
-struct groupdb_ops *ldap_initialise_group_db(void);
-
-/*The following definitions come from  groupdb/groupunix.c  */
-
-BOOL get_unixgroup_members(struct group *grp,
-                               int *num_mem, DOMAIN_GRP_MEMBER **members);
-struct groupdb_ops *unix_initialise_group_db(void);
-
 /*The following definitions come from  lib/access.c  */
 
 BOOL allow_access(char *deny_list,char *allow_list,
@@ -155,7 +35,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  */
 
@@ -165,11 +45,10 @@ void add_char_string(char *s);
 
 /*The following definitions come from  lib/crc32.c  */
 
-uint32 crc32_calc_buffer( uint32 count, char *buffer);
+uint32 crc32_calc_buffer( char *buffer, uint32 count);
 
 /*The following definitions come from  lib/debug.c  */
 
-BOOL dbg_interactive(void);
 void sig_usr2( int sig );
 void sig_usr1( int sig );
 void setup_logging( char *pname, BOOL interactive );
@@ -177,24 +56,6 @@ void reopen_logs( void );
 void force_check_log_size( void );
 void dbgflush( void );
 BOOL dbghdr( int level, char *file, char *func, int line );
-dbg_Token dbg_char2token( dbg_Token *state, int c );
-
-/*The following definitions come from  lib/domain_namemap.c  */
-
-BOOL pwdb_rid_is_user(uint32 rid);
-BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info);
-BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info);
-BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info);
-BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info);
-BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info);
-BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info);
-BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp);
-BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep);
-BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep);
-BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep);
-BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp);
-BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep);
-BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep);
 
 /*The following definitions come from  lib/doscalls.c  */
 
@@ -202,13 +63,13 @@ 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);
 int dos_rmdir(char *dname);
 int dos_chdir(char *dname);
 int dos_utime(char *fname,struct utimbuf *times);
-int copy_reg(char *source, const char *dest);
 int dos_rename(char *from, char *to);
 int dos_chmod(char *fname,mode_t mode);
 char *dos_getwd(char *unix_path);
@@ -223,6 +84,10 @@ char *dos_GetWd(char *path);
 
 void fault_setup(void (*fn)(void *));
 
+/*The following definitions come from  lib/fnmatch.c  */
+
+int fnmatch (const char *pattern, const char *string, int flags);
+
 /*The following definitions come from  lib/genrand.c  */
 
 void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
@@ -231,28 +96,25 @@ void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
 
 char *getsmbpass(char *prompt)    ;
 
-/*The following definitions come from  lib/hmacmd5.c  */
-
-void hmac_md5_init_rfc2104(uchar*  key, int key_len, HMACMD5Context *ctx);
-void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
-                       HMACMD5Context *ctx);
-void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx);
-void hmac_md5_final(uchar *digest, HMACMD5Context *ctx);
-
 /*The following definitions come from  lib/interface.c  */
 
 void load_interfaces(void);
-void iface_set_default(char *ip,char *bcast,char *nmask);
+BOOL interfaces_changed(void);
 BOOL ismyip(struct in_addr ip);
 BOOL is_local_net(struct in_addr from);
 int iface_count(void);
 BOOL we_are_multihomed(void);
 struct interface *get_interface(int n);
 struct in_addr *iface_n_ip(int n);
+struct in_addr *iface_n_bcast(int n);
 unsigned iface_hash(void);
 struct in_addr *iface_bcast(struct in_addr ip);
 struct in_addr *iface_ip(struct in_addr ip);
 
+/*The following definitions come from  lib/interfaces.c  */
+
+int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
+
 /*The following definitions come from  lib/kanji.c  */
 
 void interpret_coding_system(char *str);
@@ -261,80 +123,7 @@ void initialize_multibyte_vectors( int client_codepage);
 
 /*The following definitions come from  lib/md4.c  */
 
-void mdfour(unsigned char *out, const unsigned char *in, int n);
-
-/*The following definitions come from  lib/md5.c  */
-
-void MD5Init(struct MD5Context *ctx);
-void MD5Update(struct MD5Context *ctx, uchar const *buf, unsigned len);
-void MD5Final(uchar digest[16], struct MD5Context *ctx);
-void MD5Transform(uint32 buf[4], const uchar inext[64]);
-
-/*The following definitions come from  lib/membuffer.c  */
-
-void mem_init(struct mem_buf *buf, int margin);
-void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic);
-BOOL mem_alloc_data(struct mem_buf *buf, int size);
-BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
-                               uint32 offset, uint32 len);
-BOOL mem_buf_init(struct mem_buf **buf, uint32 margin);
-void mem_buf_free(struct mem_buf **buf);
-void mem_free_data(struct mem_buf *buf);
-BOOL mem_realloc_data(struct mem_buf *buf, size_t new_size);
-BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size, BOOL force_grow);
-uint32 mem_buf_len(struct mem_buf *buf);
-char *mem_data(struct mem_buf **buf, uint32 offset);
-
-/*The following definitions come from  lib/msrpc-agent.c  */
-
-void start_msrpc_agent(char *pipe_name);
-
-/*The following definitions come from  lib/msrpc-client.c  */
-
-BOOL msrpc_receive(struct msrpc_state *msrpc);
-BOOL msrpc_send_prs(struct msrpc_state *msrpc, prs_struct *ps);
-BOOL msrpc_receive_prs(struct msrpc_state *msrpc, prs_struct *ps);
-BOOL msrpc_send(struct msrpc_state *msrpc, BOOL show);
-BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
-void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr);
-void msrpc_close_socket(struct msrpc_state *msrpc);
-void msrpc_sockopt(struct msrpc_state *msrpc, char *options);
-BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
-                               const char* pipename,
-                               const struct user_creds *usr);
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc);
-void msrpc_shutdown(struct msrpc_state *msrpc);
-BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
-               const char *pipe_name);
-
-/*The following definitions come from  lib/msrpc_use.c  */
-
-void init_msrpc_use(void);
-void free_msrpc_use(void);
-struct msrpc_state *msrpc_use_add(const char* pipe_name,
-                               const struct user_creds *usr_creds,
-                               BOOL redir);
-BOOL msrpc_use_del(const char* pipe_name,
-                               const struct user_creds *usr_creds,
-                               BOOL force_close,
-                               BOOL *connection_closed);
-void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use);
-
-/*The following definitions come from  lib/netmask.c  */
-
-int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
-
-/*The following definitions come from  lib/passcheck.c  */
-
-BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar challenge[8],
-                               const char *user, const char *domain,
-                               uchar *lm_pass, size_t lm_pwd_len,
-                               uchar *nt_pass, size_t nt_pwd_len,
-                               uchar user_sess_key[16]);
-BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal,
-               uchar *lm_pwd, size_t lm_pwd_len,
-               uchar *nt_pwd, size_t nt_pwd_len,
-               struct passwd *pwd, uchar user_sess_key[16]);
+void mdfour(unsigned char *out, unsigned char *in, int n);
 
 /*The following definitions come from  lib/pidfile.c  */
 
@@ -345,27 +134,12 @@ void pidfile_create(char *name);
 
 char *rep_inet_ntoa(struct in_addr ip);
 
-/*The following definitions come from  lib/sids.c  */
-
-struct sid_map* add_sidmap_to_array(uint32 *len, struct sid_map ***array,
-                               const struct sid_map *name);
-void get_sam_domain_name(void);
-BOOL get_member_domain_sid(void);
-void generate_wellknown_sids(void);
-BOOL create_sidmap_table(void);
-BOOL generate_sam_sid(char *domain_name, DOM_SID *sid);
-BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain);
-BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
-BOOL map_domain_sid_to_any_dc(DOM_SID *sid, char *dc_name);
-BOOL split_domain_name(const char *fullname, char *domain, char *name);
-BOOL enumtrustdoms(char ***doms, uint32 *num_entries);
-BOOL enumdomains(char ***doms, uint32 *num_entries);
-
 /*The following definitions come from  lib/signal.c  */
 
 void BlockSignals(BOOL block,int signum);
 void CatchSignal(int signum,void (*handler)(int ));
 void CatchChild(void);
+void CatchChildLeaveStatus(void);
 
 /*The following definitions come from  lib/slprintf.c  */
 
@@ -380,8 +154,9 @@ int smbrun(char *cmd,char *outfile,BOOL shared);
 
 /*The following definitions come from  lib/system.c  */
 
-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_select(int maxfd, fd_set *fds,struct timeval *tval);
+int sys_select(int maxfd, fd_set *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);
@@ -393,6 +168,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);
@@ -403,7 +179,7 @@ BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable );
 long sys_random(void);
 void sys_srandom(unsigned int seed);
 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);
 
@@ -413,10 +189,9 @@ void GetTimeOfDay(struct timeval *tval);
 void TimeInit(void);
 int TimeDiff(time_t t);
 struct tm *LocalTime(time_t *t);
-time_t nt_time_to_unix(const NTTIME *nt);
+time_t nt_time_to_unix(NTTIME *nt);
 time_t interpret_long_date(char *p);
 void unix_to_nt_time(NTTIME *nt, time_t t);
-void init_nt_time(NTTIME *nt);
 void put_long_date(char *p,time_t t);
 BOOL null_mtime(time_t mtime);
 void put_dos_date(char *buf,int offset,time_t unixdate);
@@ -426,7 +201,7 @@ time_t make_unix_date(void *date_ptr);
 time_t make_unix_date2(void *date_ptr);
 time_t make_unix_date3(void *date_ptr);
 char *http_timestring(time_t t);
-char *timestring(void );
+char *timestring(BOOL hires);
 time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
 
 /*The following definitions come from  lib/ufc.c  */
@@ -435,31 +210,24 @@ char *ufc_crypt(char *key,char *salt);
 
 /*The following definitions come from  lib/username.c  */
 
-struct passwd *hashed_getpwnam(const char *name);
-char *uidtoname(uid_t uid);
-char *get_unixhome_dir(char *user);
+char *get_user_home_dir(char *user);
 BOOL map_username(char *user);
-const struct passwd *Get_Pwnam(char *user,BOOL allow_change);
-BOOL user_ok(char *user,int snum);
+struct passwd *Get_Pwnam(char *user,BOOL allow_change);
 BOOL user_in_list(char *user,char *list);
 
 /*The following definitions come from  lib/util.c  */
 
-BOOL init_myworkgroup(void);
 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);
 char *dns_to_netbios_name(char *dns_name);
 int name_mangle( char *In, char *Out, char name_type );
 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);
+SMB_OFF_T get_file_size(char *file_name);
 char *attrib_string(uint16 mode);
 void unix_format(char *fname);
 void dos_format(char *fname);
@@ -483,15 +251,17 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,
 int name_extract(char *buf,int ofs,char *name);
 int name_len(char *s1);
 void msleep(int t);
-BOOL do_match(char *str, 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 exact_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);
 void *Realloc(void *p,size_t size);
-BOOL get_myname(char *my_name,struct in_addr *ip);
+BOOL get_myname(char *my_name);
 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
 int interpret_protocol(char *str,int def);
+BOOL is_ipaddress(const char *str);
 uint32 interpret_addr(char *str);
 struct in_addr *interpret_addr2(char *str);
 BOOL zero_ip(struct in_addr ip);
@@ -500,173 +270,100 @@ void standard_sub_basic(char *str);
 void standard_sub(connection_struct *conn,char *str);
 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
 struct hostent *Get_Hostbyname(const char *name);
-BOOL process_exists(int pid);
-int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
-BOOL get_unix_grps(int *p_ngroups, struct group **p_groups);
-void free_unix_grps(int ngroups, struct group *p_groups);
+BOOL process_exists(pid_t pid);
+char *uidtoname(uid_t uid);
 char *gidtoname(gid_t gid);
-BOOL nametogid(const char *name, gid_t *gid);
-BOOL nametouid(const char *name, uid_t *uid);
+uid_t nametouid(const char *name);
+gid_t nametogid(const char *name);
 void smb_panic(char *why);
 char *readdirname(DIR *p);
 BOOL is_in_path(char *name, name_compare_entry *namelist);
 void set_namearray(name_compare_entry **ppname_array, char *namelist);
 void free_namearray(name_compare_entry *name_array);
+uint32 map_lock_offset(uint32 high, uint32 low);
 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
 BOOL is_myname(char *s);
 void set_remote_arch(enum remote_arch_types type);
 enum remote_arch_types get_remote_arch(void);
-char *align4(char *q, char *base);
 char *align2(char *q, char *base);
-void out_ascii(FILE *f, const unsigned char *buf,int len);
-void out_struct(FILE *f, const char *buf1,int len, int per_line);
-void out_data(FILE *f, const char *buf1,int len, int per_line);
-void print_asc(int level, unsigned char const *buf,int len);
-void dump_data(int level, const char *buf1, int len);
+void out_ascii(FILE *f, unsigned char *buf,int len);
+void out_data(FILE *f,char *buf1,int len, int per_line);
+void print_asc(int level, unsigned char *buf,int len);
+void dump_data(int level,char *buf1,int len);
 char *tab_depth(int depth);
 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 become_user_permanently(uid_t uid, gid_t gid);
-char *get_trusted_serverlist(const char* domain);
-char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
-uint16 pwdb_decode_acct_ctrl(const char *p);
-time_t pwdb_get_last_set_time(const char *p);
-void pwdb_set_logon_time(char *p, int max_len, time_t t);
-void pwdb_set_logoff_time(char *p, int max_len, time_t t);
-void pwdb_set_kickoff_time(char *p, int max_len, time_t t);
-void pwdb_set_can_change_time(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 char *pwd, uint16 acct_ctrl);
-BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl);
-
-/*The following definitions come from  lib/util_array.c  */
-
-void free_void_array(uint32 num_entries, void **entries,
-               void(free_item)(void*));
-void* add_copy_to_array(uint32 *len, void ***array, const void *item,
-       void*(item_dup)(const void*), BOOL alloc_anyway);
-void* add_item_to_array(uint32 *len, void ***array, void *item);
-void free_use_info_array(uint32 num_entries, struct use_info **entries);
-struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
-                               const struct use_info *name);
-void free_char_array(uint32 num_entries, char **entries);
-char* add_chars_to_array(uint32 *len, char ***array, const char *name);
-void free_uint32_array(uint32 num_entries, uint32 **entries);
-uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name);
-void free_unistr_array(uint32 num_entries, UNISTR2 **entries);
-UNISTR2* add_unistr_to_array(uint32 *len, UNISTR2 ***array, UNISTR2 *name);
-void free_sid_array(uint32 num_entries, DOM_SID **entries);
-DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
-void free_devmode(DEVICEMODE *devmode);
-void free_printer_info_2(PRINTER_INFO_2 *printer);
-void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries);
-PRINTER_INFO_2 *add_print2_to_array(uint32 *len, PRINTER_INFO_2 ***array,
-                               const PRINTER_INFO_2 *prt);
-void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries);
-PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array,
-                               const PRINTER_INFO_1 *prt);
-void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries);
-JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array,
-                               const JOB_INFO_1 *job);
-void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries);
-JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array,
-                               const JOB_INFO_2 *job);
+BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name);
+char *smbd_mktemp(char *template);
+void *memdup(void *p, size_t size);
+char *myhostname(void);
 
 /*The following definitions come from  lib/util_file.c  */
 
 BOOL do_file_lock(int fd, int waitsecs, int type);
 BOOL file_lock(int fd, int type, int secs, int *plock_depth);
 BOOL file_unlock(int fd, int *plock_depth);
-void *startfileent(char *pfile, char *s_readbuf, int bufsize,
+void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
                                int *file_lock_depth, BOOL update);
-void endfileent(void *vp, int *file_lock_depth);
+void endfilepwent(void *vp, int *file_lock_depth);
 SMB_BIG_UINT getfilepwpos(void *vp);
 BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok);
 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);
-
-/*The following definitions come from  lib/util_hnd.c  */
-
-BOOL init_policy_hnd(int num_pol_hnds);
-BOOL register_policy_hnd(POLICY_HND *hnd);
-BOOL open_policy_hnd(POLICY_HND *hnd);
-int find_policy_by_hnd(const POLICY_HND *hnd);
-BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid);
-BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status);
-BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
-BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
-uint32 get_policy_samr_rid(POLICY_HND *hnd);
-BOOL set_policy_reg_name(POLICY_HND *hnd, fstring name);
-BOOL get_policy_reg_name(POLICY_HND *hnd, fstring name);
-BOOL set_policy_con(POLICY_HND *hnd, struct cli_connection *con,
-                               void (*free_fn)(struct cli_connection *));
-BOOL get_policy_con(const POLICY_HND *hnd, struct cli_connection **con);
-BOOL close_policy_hnd(POLICY_HND *hnd);
-
-/*The following definitions come from  lib/util_pwdb.c  */
-
-uint32 lookup_wk_group_name(const char *group_name, const char *domain,
-                               DOM_SID *sid, uint8 *type);
-uint32 lookup_wk_user_name(const char *user_name, const char *domain,
-                               DOM_SID *sid, uint8 *type);
-uint32 lookup_builtin_alias_name(const char *alias_name, const char *domain,
-                               DOM_SID *sid, uint8 *type);
-BOOL pwdb_initialise(BOOL is_server);
-char *lookup_wk_alias_rid(uint32 rid);
-char *lookup_wk_user_rid(uint32 rid);
-char *lookup_wk_group_rid(uint32 rid);
+
+/*The following definitions come from  lib/util_sec.c  */
+
+void gain_root_privilege(void);
+void gain_root_group_privilege(void);
+void set_effective_uid(uid_t uid);
+void set_effective_gid(gid_t gid);
+void save_re_uid(void);
+void restore_re_uid(void);
+int set_re_uid(void);
+void become_user_permanently(uid_t uid, gid_t gid);
 
 /*The following definitions come from  lib/util_sid.c  */
 
-char *sid_to_string(pstring sidstr_out, const DOM_SID *sid);
-BOOL string_to_sid(DOM_SID *sidout, const char *sidstr);
+void generate_wellknown_sids(void);
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
+BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use);
+BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain);
+void split_domain_name(const char *fullname, char *domain, char *name);
+char *sid_to_string(fstring sidstr_out, DOM_SID *sid);
+BOOL string_to_sid(DOM_SID *sidout, char *sidstr);
 BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
 BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
-void sid_copy(DOM_SID *sid1, const DOM_SID *sid2);
-BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2);
-BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
-int sid_size(const DOM_SID *sid);
-DOM_SID *sid_dup(const DOM_SID *src);
-BOOL read_sid(char *domain_name, DOM_SID *sid);
-BOOL write_sid(char *domain_name, DOM_SID *sid);
-BOOL create_new_sid(DOM_SID *sid);
+void sid_copy(DOM_SID *dst, DOM_SID *src);
+DOM_SID *sid_dup(DOM_SID *src);
+BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid);
+BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2);
+size_t sid_size(DOM_SID *sid);
 
 /*The following definitions come from  lib/util_sock.c  */
 
 BOOL is_a_socket(int fd);
 void set_socket_options(int fd, char *options);
 void close_sockets(void );
-ssize_t write_socket(int fd,char *buf,size_t len);
 ssize_t read_udp_socket(int fd,char *buf,size_t len);
 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out);
 BOOL send_keepalive(int client);
 ssize_t read_data(int fd,char *buffer,size_t N);
 ssize_t write_data(int fd,char *buffer,size_t N);
+ssize_t write_socket_data(int fd,char *buffer,size_t N);
+ssize_t write_socket(int fd,char *buf,size_t len);
 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout);
 BOOL receive_smb(int fd,char *buffer, unsigned int timeout);
 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout);
+BOOL send_null_session_msg(int fd);
 BOOL send_smb(int fd,char *buffer);
 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr);
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind);
 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
 void reset_globals_after_fork(void);
 char *client_name(int fd);
 char *client_addr(int fd);
-int open_pipe_sock(char *path);
-int create_pipe_socket(char *dir, int dir_perms,
-                               char *path, int path_perms);
-
-/*The following definitions come from  lib/util_status.c  */
-
-BOOL get_connection_status(struct connect_record **crec,
-                               uint32 *connection_count);
-BOOL get_session_count(struct connect_record **srec,uint32 *session_count);
 
 /*The following definitions come from  lib/util_str.c  */
 
@@ -689,69 +386,47 @@ 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 all_string_sub(char *s,const char *pattern,const char *insert);
-void split_at_first_component(char *path, char *front, char sep, char *back);
+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_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  */
 
-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);
-void unistr_to_ascii(char *dest, const uint16 *src, int len);
-void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
-char *skip_unibuf(char *srcbuf, int len);
-char *uni_strncpy(char *destbuf, const char *srcbuf, int len);
-uint32 buffer2_to_uint32(const BUFFER2 *str);
-void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen);
-void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen);
-BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
-UNISTR2 *unistr2_dup(const UNISTR2 *name);
-void unistr2_free(UNISTR2 *name);
-
-/*The following definitions come from  lib/vagent.c  */
-
-void init_sock_redir(struct vagent_ops*va);
-void free_sock_redir(struct vagent_ops*va);
-void start_agent(struct vagent_ops *va);
-
-/*The following definitions come from  lib/vuser.c  */
-
-user_struct *get_valid_user_struct(uint16 vuid);
-void invalidate_vuid(uint16 vuid);
-char *validated_username(uint16 vuid);
-uint16 create_vuid(uid_t uid, gid_t gid, int n_groups, gid_t *groups,
-                               char *unix_name, char *requested_name,
-                               char *real_name,
-                               BOOL guest, uchar user_sess_key[16]);
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, uchar user_sess_key[16]);
+int dos_PutUniCode(char *dst,const char *src, ssize_t len);
+char *skip_unicode_string(char *buf,int n);
+char *dos_unistrn2(uint16 *src, int len);
+char *dos_unistr2(uint16 *src);
+char *dos_unistr2_to_str(UNISTR2 *str);
+uint32 buffer2_to_uint32(BUFFER2 *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);
+int unistrcpy(char *dst, char *src);
+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);
 
 /*The following definitions come from  libsmb/clientgen.c  */
 
 int cli_set_port(struct cli_state *cli, int port);
 char *cli_errstr(struct cli_state *cli);
-void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len);
-BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen);
-void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen);
-BOOL cli_send_trans(struct cli_state *cli, int trans, 
-                           char *name, int pipe_name_len, 
-                           int fid, int flags,
-                           uint16 *setup, int lsetup, int msetup,
-                           char *param, int lparam, int mparam,
-                           char *data, int ldata, int mdata);
 BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
                   uint16 *setup, uint32 setup_count, uint32 max_setup_count,
                   char *params, uint32 param_count, uint32 max_param_count,
@@ -767,16 +442,11 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
 BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
 BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
                       void (*fn)(const char *, uint32, const char *));
-BOOL cli_session_setup_x(struct cli_state *cli, 
-                               char *user, 
-                               char *pass, int passlen,
-                               char *ntpass, int ntpasslen,
-                               char *user_domain);
 BOOL cli_session_setup(struct cli_state *cli, 
-                               char *myhostname, char *user,
-                               char *pass, int passlen,
-                               char *ntpass, int ntpasslen,
-                               char *user_domain);
+                      char *user, 
+                      char *pass, int passlen,
+                      char *ntpass, int ntpasslen,
+                      char *workgroup);
 BOOL cli_ulogoff(struct cli_state *cli);
 BOOL cli_send_tconX(struct cli_state *cli, 
                    char *share, char *dev, char *pass, int passlen);
@@ -785,9 +455,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst);
 BOOL cli_unlink(struct cli_state *cli, char *fname);
 BOOL cli_mkdir(struct cli_state *cli, char *dname);
 BOOL cli_rmdir(struct cli_state *cli, char *dname);
-int cli_nt_create(struct cli_state *cli, const char *fname);
-int cli_open(struct cli_state *cli, const char *fname,
-                               int flags, int share_mode);
+int cli_nt_create(struct cli_state *cli, char *fname);
+int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode);
 BOOL cli_close(struct cli_state *cli, int fnum);
 BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
@@ -795,6 +464,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
 ssize_t cli_write(struct cli_state *cli,
                  int fnum, uint16 write_mode,
                  char *buf, off_t offset, size_t size);
+ssize_t cli_smbwrite(struct cli_state *cli,
+                    int fnum, char *buf, off_t offset, size_t size1);
 BOOL cli_getattrE(struct cli_state *cli, int fd, 
                  uint16 *attr, size_t *size, 
                  time_t *c_time, time_t *a_time, time_t *m_time);
@@ -820,27 +491,17 @@ BOOL cli_negprot(struct cli_state *cli);
 BOOL cli_session_request(struct cli_state *cli,
                         struct nmb_name *calling, struct nmb_name *called);
 BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
-void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
 struct cli_state *cli_initialise(struct cli_state *cli);
-void cli_close_socket(struct cli_state *cli);
 void cli_shutdown(struct cli_state *cli);
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error);
 void cli_sockopt(struct cli_state *cli, char *options);
 uint16 cli_setpid(struct cli_state *cli, uint16 pid);
 BOOL cli_reestablish_connection(struct cli_state *cli);
 BOOL cli_establish_connection(struct cli_state *cli, 
-                               const char *dest_host, struct in_addr *dest_ip,
+                               char *dest_host, struct in_addr *dest_ip,
                                struct nmb_name *calling, struct nmb_name *called,
                                char *service, char *service_type,
                                BOOL do_shutdown, BOOL do_tcon);
-BOOL cli_connect_auth(struct cli_state *cli,
-                               const char* desthost,
-                               struct in_addr *dest_ip,
-                               const struct ntuser_creds *usr);
-BOOL cli_connect_servers_auth(struct cli_state *cli,
-                               char *p,
-                               const struct ntuser_creds *usr);
-BOOL cli_connect_serverlist(struct cli_state *cli, char *p);
 int cli_printjob_del(struct cli_state *cli, int job);
 int cli_print_queue(struct cli_state *cli, 
                    void (*fn)(struct print_job_info *));
@@ -850,12 +511,8 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
 BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
 BOOL cli_message_end(struct cli_state *cli, int grp);
 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
-BOOL get_any_dc_name(const char *domain, char *srv_name);
-
-/*The following definitions come from  libsmb/clienttrust.c  */
-
-BOOL change_trust_account_password(char *domain, char *remote_machine_list,
-                                       uint16 sec_chan);
+BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
+                                            struct in_addr *pdest_ip);
 
 /*The following definitions come from  libsmb/credentials.c  */
 
@@ -882,17 +539,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
 FILE *startlmhosts(char *fname);
 BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
 void endlmhosts(FILE *fp);
-BOOL is_ip_address(const char *name);
 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
-BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
-                               struct in_addr *ip);
 BOOL find_master_ip(char *group, struct in_addr *master_ip);
+BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name);
+BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count);
 
 /*The following definitions come from  libsmb/nmblib.c  */
 
 void debug_nmb_packet(struct packet_struct *p);
 char *nmb_namestr(struct nmb_name *n);
-void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len);
 struct packet_struct *copy_packet(struct packet_struct *packet);
 void free_packet(struct packet_struct *packet);
 struct packet_struct *read_packet(int fd,enum packet_type packet_type);
@@ -901,12 +556,9 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
 BOOL send_packet(struct packet_struct *p);
 struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
 void sort_query_replies(char *data, int n, struct in_addr ip);
-BOOL read_nmb_sock(int c, struct nmb_state *con);
-int get_nmb_sock(void);
 
 /*The following definitions come from  libsmb/nterr.c  */
 
-void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len);
 char *get_nt_error_msg(uint32 nt_code);
 
 /*The following definitions come from  libsmb/passchange.c  */
@@ -918,26 +570,19 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
 /*The following definitions come from  libsmb/pwd_cache.c  */
 
 void pwd_init(struct pwd_info *pwd);
-BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
 void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key);
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2);
 void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
 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, 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]);
+void pwd_get_lm_nt_16(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);
 void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]);
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
-                               uchar *nt_owf, size_t *nt_owf_len,
-                               uchar *sess_key);
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]);
 
 /*The following definitions come from  libsmb/smbdes.c  */
 
-void smbhash(unsigned char *out, const uchar *in, const uchar *key, int forw);
 void E_P16(unsigned char *p14,unsigned char *p16);
 void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
 void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
@@ -946,54 +591,19 @@ void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
 void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
 void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
 void SamOEMhash( unsigned char *data, unsigned char *key, int val);
-void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw);
 
 /*The following definitions come from  libsmb/smbencrypt.c  */
 
-void SMBencrypt(uchar *pwrd, uchar *c8, uchar *p24);
-void SMBNTencrypt(uchar *pwrd, uchar *c8, uchar *p24);
-void E_md4hash(uchar *pwrd, uchar *p16);
-void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]);
-void lm_owf_gen(const char *pwd, uchar p16[16]);
-void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
-void nt_owf_gen(const char *pwd, uchar nt_p16[16]);
-void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]);
-void SMBOWFencrypt(uchar pwrd[16], uchar *c8, uchar p24[24]);
-void SMBOWFencrypt_ntv2(const uchar kr[16], 
-                               const uchar *srv_chal, int srv_chal_len,
-                               const uchar *cli_chal, int cli_chal_len,
-                               char resp_buf[16]);
-void SMBsesskeygen_ntv2(const uchar kr[16], 
-                               const uchar *nt_resp, 
-                               char sess_key[16]);
-void SMBsesskeygen_ntv1(const uchar kr[16], 
-                               const uchar *nt_resp, 
-                               char sess_key[16]);
-void SMBgenclientchals(char *lm_cli_chal,
-                               char *nt_cli_chal, int *nt_cli_chal_len,
-                               const char *srv, const char *dom);
-void ntv2_owf_gen(const uchar owf[16], 
-                               const char *user_n,
-                               const char *domain_n,
-                               uchar kr_buf[16]);
-void NTLMSSPOWFencrypt(uchar pwrd[8], uchar *ntlmchalresp, uchar p24[24]);
-BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16], BOOL unicode);
-BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, const uchar *key);
-void create_ntlmssp_resp(struct pwd_info *pwd,
-                               char *domain, char *user_name, char *my_name,
-                               uint32 ntlmssp_cli_flgs,
-                                prs_struct *auth_resp);
-BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
-                       int new_pwrd_size, uint32 *new_pw_len);
-BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
-                       int new_pw_len, BOOL nt_pass_set);
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
+void E_md4hash(uchar *passwd, uchar *p16);
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
 
 /*The following definitions come from  libsmb/smberr.c  */
 
-char *smb_err_msg(uint8 class, uint32 num);
-BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len);
-BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len);
 char *smb_errstr(char *inbuf);
 
 /*The following definitions come from  locking/locking.c  */
@@ -1017,7 +627,8 @@ int get_share_modes(connection_struct *conn,
 void del_share_mode(int token, files_struct *fsp);
 BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type);
 BOOL remove_share_oplock(int token, files_struct *fsp);
-BOOL modify_share_mode(int token, files_struct *fsp, int new_mode);
+BOOL downgrade_share_oplock(int token, files_struct *fsp);
+BOOL modify_share_mode(int token, files_struct *fsp, int new_mode, uint16 new_oplock);
 int share_mode_forall(void (*fn)(share_mode_entry *, char *));
 void share_status(FILE *f);
 
@@ -1037,44 +648,6 @@ struct shmem_ops *smb_shm_open(int ronly);
 
 struct shmem_ops *sysv_shm_open(int ronly);
 
-/*The following definitions come from  lsarpcd/lsarpcd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
-/*The following definitions come from  mem_man/mem_man.c  */
-
-void *smb_mem_malloc(size_t size,char *file,int line);
-char *smb_mem_strdup(char *s, char *file, int line);
-int smb_mem_free(void *ptr,char *file,int line);
-void smb_mem_write_info(void *ptr,FILE *outfile);
-size_t smb_mem_query_size(void *ptr);
-size_t smb_mem_query_real_size(void *ptr);
-char *smb_mem_query_file(void *ptr);
-int smb_mem_query_line(void *ptr);
-int smb_mem_test(void *ptr);
-void smb_mem_write_status(FILE *outfile);
-void smb_mem_write_verbose(FILE *outfile);
-void smb_mem_write_errors(FILE *outfile);
-void smb_mem_set_multiplier(int multiplier);
-void *smb_mem_resize(void *ptr,size_t newsize);
-
-/*The following definitions come from  msrpc/msrpcd.c  */
-
-void exit_server(char *reason);
-int msrpc_main(int argc,char *argv[]);
-
-/*The following definitions come from  msrpc/msrpcd_process.c  */
-
-BOOL get_user_creds(int c, struct user_creds *usr);
-BOOL msrpcd_init(int c, pipes_struct *p);
-void msrpcd_process(int c, pipes_struct *p);
-
-/*The following definitions come from  netlogond/netlogond.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
 /*The following definitions come from  nmbd/asyncdns.c  */
 
 int asyncdns_fd(void);
@@ -1166,6 +739,7 @@ void add_logon_names(void);
 
 /*The following definitions come from  nmbd/nmbd_mynames.c  */
 
+void register_my_workgroup_one_subnet(struct subnet_record *subrec);
 BOOL register_my_workgroup_and_names(void);
 void release_my_names(void);
 void refresh_my_names(time_t t);
@@ -1365,6 +939,8 @@ void write_browse_list(time_t t, BOOL force_write);
 
 /*The following definitions come from  nmbd/nmbd_subnetdb.c  */
 
+void close_subnet(struct subnet_record *subrec);
+struct subnet_record *make_normal_subnet(struct interface *iface);
 BOOL create_subnets(void);
 BOOL we_are_a_wins_client(void);
 struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec);
@@ -1415,14 +991,10 @@ void expire_workgroups_and_servers(time_t t);
 
 /*The following definitions come from  param/loadparm.c  */
 
-struct vfs_options *lp_vfsoptions(int i) ;
 char *lp_logfile(void);
 char *lp_smbrun(void);
 char *lp_configfile(void);
 char *lp_smb_passwd_file(void);
-char *lp_smb_passgrp_file(void);
-char *lp_smb_group_file(void);
-char *lp_smb_alias_file(void);
 char *lp_serverstring(void);
 char *lp_printcapname(void);
 char *lp_lockdir(void);
@@ -1436,14 +1008,8 @@ char *lp_passwd_chat(void);
 char *lp_passwordserver(void);
 char *lp_name_resolve_order(void);
 char *lp_workgroup(void);
-char *lp_trusted_domains(void);
-char *lp_trusting_domains(void);
 char *lp_username_map(void);
-char *lp_aliasname_map(void);
 char *lp_groupname_map(void);
-char *lp_builtinname_map(void);
-char *lp_builtinrid_file(void);
-char *lp_ntusrname_map(void);
 char *lp_logon_script(void);
 char *lp_logon_path(void);
 char *lp_logon_drive(void);
@@ -1457,13 +1023,19 @@ char *lp_nis_home_map_name(void);
 char *lp_netbios_aliases(void);
 char *lp_driverfile(void);
 char *lp_panic_action(void);
-char *lp_nt_forms(void);
-char *lp_nt_drivers_file(void);
-char *lp_dfs_map(void);
+char *lp_adduser_script(void);
+char *lp_deluser_script(void);
+char *lp_wins_hook(void);
+char *lp_domain_groups(void);
+char *lp_domain_admin_group(void);
+char *lp_domain_guest_group(void);
+char *lp_domain_admin_users(void);
+char *lp_domain_guest_users(void);
 char *lp_ldap_server(void);
 char *lp_ldap_suffix(void);
-char *lp_ldap_bind_as(void);
-char *lp_ldap_passwd_file(void);
+char *lp_ldap_filter(void);
+char *lp_ldap_root(void);
+char *lp_ldap_rootpasswd(void);
 int lp_ssl_version(void);
 char *lp_ssl_hosts(void);
 char *lp_ssl_hosts_resign(void);
@@ -1483,7 +1055,9 @@ BOOL lp_wins_support(void);
 BOOL lp_we_are_a_wins_server(void);
 BOOL lp_wins_proxy(void);
 BOOL lp_local_master(void);
+BOOL lp_domain_master(void);
 BOOL lp_domain_logons(void);
+BOOL lp_preferred_master(void);
 BOOL lp_load_printers(void);
 BOOL lp_use_rhosts(void);
 BOOL lp_readprediction(void);
@@ -1494,10 +1068,11 @@ BOOL lp_null_passwords(void);
 BOOL lp_strip_dot(void);
 BOOL lp_encrypted_passwords(void);
 BOOL lp_update_encrypted(void);
-BOOL lp_client_ntlmv2(void);
-BOOL lp_server_ntlmv2(void);
 BOOL lp_syslog_only(void);
 BOOL lp_timestamp_logs(void);
+BOOL lp_debug_hires_timestamp(void);
+BOOL lp_debug_pid(void);
+BOOL lp_debug_uid(void);
 BOOL lp_browse_list(void);
 BOOL lp_unix_realname(void);
 BOOL lp_nis_home_map(void);
@@ -1507,7 +1082,10 @@ 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_allow_trusted_domains(void);
+BOOL lp_restrict_anonymous(void);
 int lp_os_level(void);
 int lp_max_ttl(void);
 int lp_max_wins_ttl(void);
@@ -1533,6 +1111,8 @@ int lp_machine_password_timeout(void);
 int lp_change_notify_timeout(void);
 int lp_stat_cache_size(void);
 int lp_map_to_guest(void);
+int lp_min_passwd_length(void);
+int lp_oplock_break_wait_time(void);
 int lp_ldap_port(void);
 char *lp_preexec(int );
 char *lp_postexec(int );
@@ -1565,12 +1145,13 @@ char *lp_force_group(int );
 char *lp_readlist(int );
 char *lp_writelist(int );
 char *lp_fstype(int );
-char *lp_vfsobj(int );
 char *lp_mangled_map(int );
 char *lp_veto_files(int );
 char *lp_hide_files(int );
 char *lp_veto_oplocks(int );
 char *lp_driverlocation(int );
+BOOL lp_preexec_close(int );
+BOOL lp_rootpreexec_close(int );
 BOOL lp_revalidate(int );
 BOOL lp_casesensitive(int );
 BOOL lp_preservecase(int );
@@ -1591,6 +1172,7 @@ BOOL lp_locking(int );
 BOOL lp_strict_locking(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 );
@@ -1605,20 +1187,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 );
+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);
-char *lp_mysql_passfile(void);
-char *lp_mysql_db(void);
-char *lp_mysql_table(void);
 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);
@@ -1632,8 +1215,10 @@ 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);
 void lp_remove_service(int snum);
@@ -1644,9 +1229,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  */
 
@@ -1656,54 +1242,11 @@ BOOL pm_process( char *FileName,
 
 /*The following definitions come from  passdb/ldap.c  */
 
-BOOL ldap_connect(void);
-void ldap_disconnect(void);
-BOOL ldap_search_for(char *filter);
-BOOL ldap_search_by_name(const char *user);
-BOOL ldap_search_by_uid(int uid);
-BOOL ldap_get_attribute(char *attribute, char *value);
-struct smb_passwd *ldap_getpw(void);
-BOOL ldap_allocaterid(uint32 *rid);
-struct smb_passdb_ops *ldap_initialise_password_db(void);
-
-/*The following definitions come from  passdb/mysqlpass.c  */
-
-int mysql_db_lock_connect( MYSQL *handle );
-void *mysql_startpwent( BOOL update );
-void mysql_endpwent( void *ptr );
-SMB_BIG_UINT mysql_getpwpos(void *vp);
-BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos);
-void *mysql_fill_smb_passwd( MYSQL_ROW *row );
-struct smb_passwd *mysql_getsmbpwent(void *vp);
-void *mysql_fetch_passwd( void *(*filler)(MYSQL_ROW*), char *where );
-void *mysql_getpwuid(void *(*filler)(MYSQL_ROW *), uid_t uid);
-struct smb_passwd *mysql_getsmbpwuid(uid_t uid);
-void *mysql_getpwnam(void *(*filler)(MYSQL_ROW *), char *field, const char *name);
-struct smb_passwd *mysql_getsmbpwnam(const char *unix_name);
-BOOL mysql_del_smb( MYSQL *handle, char *unix_name );
-BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb );
-BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override );
-BOOL mysql_add_smbpwd_entry(struct smb_passwd *smb);
-BOOL mysql_mod_smbpwd_entry(struct smb_passwd *smb, BOOL override);
-struct smb_passdb_ops *mysql_initialise_password_db(void);
-
-/*The following definitions come from  passdb/mysqlsampass.c  */
-
-void *mysql_fill_sam_passwd( MYSQL_ROW *row );
-struct sam_passwd *mysql_getsampwent(void *vp);
-struct sam_passwd *mysql_getsampwrid(uint32 rid);
-struct sam_passwd *mysql_getsampwuid(uid_t uid);
-struct sam_passwd *mysql_getsampwntnam(const char *nt_name);
-struct sam_disp_info *mysql_getsamdispntnam(const char *nt_name);
-struct sam_disp_info *mysql_getsamdisprid(uint32 rid);
-struct sam_disp_info *mysql_getsamdispent(void *vp);
-BOOL mysql_add_sampwd_entry(struct sam_passwd *sam);
-BOOL mysql_mod_sampwd_entry(struct sam_passwd *sam, BOOL override);
-struct sam_passdb_ops *mysql_initialise_sam_password_db(void);
+struct passdb_ops *ldap_initialize_password_db(void);
 
 /*The following definitions come from  passdb/nispass.c  */
 
-struct passdb_ops *nisplus_initialise_password_db(void);
+struct passdb_ops *nisplus_initialize_password_db(void);
 
 /*The following definitions come from  passdb/pass_check.c  */
 
@@ -1713,144 +1256,84 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
 
 /*The following definitions come from  passdb/passdb.c  */
 
-BOOL initialise_password_db(void);
-struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid);
-struct smb_passwd *iterate_getsmbpwnam(const char *name);
+BOOL initialize_password_db(void);
+struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid);
+struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid);
+struct smb_passwd *iterate_getsmbpwnam(char *name);
 void *startsmbpwent(BOOL update);
 void endsmbpwent(void *vp);
-SMB_BIG_UINT getsmbpwpos(void *vp);
-BOOL setsmbpwpos(void *vp, SMB_BIG_UINT tok);
 struct smb_passwd *getsmbpwent(void *vp);
 BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override);
-struct smb_passwd *getsmbpwnam(const char *name);
-struct smb_passwd *getsmbpwuid(uid_t unix_uid);
-void pwdb_init_smb(struct smb_passwd *user);
-struct smb_passwd *pwdb_smb_map_names(struct smb_passwd *smb);
-
-/*The following definitions come from  passdb/passgrp.c  */
-
-BOOL initialise_passgrp_db(void);
-struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-struct smb_passwd *iterate_getsmbgrpntnam(const char *nt_name,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-void *startsmbgrpent(BOOL update);
-void endsmbgrpent(void *vp);
-struct smb_passwd *getsmbgrpent(void *vp,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-struct smb_passwd *getsmbgrpntnam(char *name,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-struct smb_passwd *getsmbgrprid(uint32 user_rid,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-struct smb_passwd *getsmbgrpuid(uid_t unix_uid,
-               uint32 **grps, int *num_grps,
-               uint32 **alss, int *num_alss);
-
-/*The following definitions come from  passdb/passgrpldap.c  */
-
-struct passgrp_ops *ldap_initialise_password_grp(void);
-
-/*The following definitions come from  passdb/sampass.c  */
-
-struct sam_passdb_ops *file_initialise_sam_password_db(void);
-
-/*The following definitions come from  passdb/sampassdb.c  */
-
-BOOL initialise_sam_password_db(void);
-void *startsam21pwent(BOOL update);
-void endsam21pwent(void *vp);
-struct sam_passwd *getsam21pwent(void *vp);
-BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override);
-struct sam_passwd *iterate_getsam21pwntnam(const char *ntname);
+struct smb_passwd *getsmbpwnam(char *name);
+struct smb_passwd *getsmbpwrid(uint32 user_rid);
+struct smb_passwd *getsmbpwuid(uid_t smb_userid);
+struct sam_passwd *iterate_getsam21pwnam(char *name);
 struct sam_passwd *iterate_getsam21pwrid(uint32 rid);
 struct sam_passwd *iterate_getsam21pwuid(uid_t uid);
 struct sam_disp_info *getsamdisprid(uint32 rid);
-struct sam_passwd *getsam21pwntnam(const char *name);
+struct sam_passwd *getsam21pwent(void *vp);
+struct sam_passwd *getsam21pwnam(char *name);
 struct sam_passwd *getsam21pwrid(uint32 rid);
-void pwdb_init_sam(struct sam_passwd *user);
-struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user);
-void copy_id23_to_sam_passwd(struct sam_passwd *to, const SAM_USER_INFO_23 *from);
-void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from);
-struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user);
-struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user);
-struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam);
-
-/*The following definitions come from  passdb/sampassldap.c  */
-
-BOOL ldap_search_by_rid(uint32 rid);
-BOOL ldap_search_by_ntname(const char *ntname);
-struct sam_passdb_ops *ldap_initialise_sam_password_db(void);
+void pdb_init_smb(struct smb_passwd *user);
+void pdb_init_sam(struct sam_passwd *user);
+struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user);
+struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user);
+struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user);
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
+uint16 pdb_decode_acct_ctrl(const char *p);
+time_t pdb_get_last_set_time(const char *p);
+void pdb_set_logon_time(char *p, int max_len, time_t t);
+void pdb_set_logoff_time(char *p, int max_len, time_t t);
+void pdb_set_kickoff_time(char *p, int max_len, time_t t);
+void pdb_set_can_change_time(char *p, int max_len, time_t t);
+void pdb_set_must_change_time(char *p, int max_len, time_t t);
+void pdb_set_last_set_time(char *p, int max_len, time_t t);
+void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl);
+BOOL pdb_gethexpwd(char *p, unsigned char *pwd);
+BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
+BOOL pdb_generate_sam_sid(void);
+uid_t pdb_user_rid_to_uid(uint32 user_rid);
+gid_t pdb_user_rid_to_gid(uint32 user_rid);
+uint32 pdb_uid_to_user_rid(uid_t uid);
+uint32 pdb_gid_to_group_rid(gid_t gid);
+BOOL pdb_rid_is_user(uint32 rid);
+BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
+BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
 
 /*The following definitions come from  passdb/smbpass.c  */
 
-struct smb_passwd *getsmbfilepwent(void *vp);
-struct smb_passdb_ops *file_initialise_password_db(void);
+struct passdb_ops *file_initialize_password_db(void);
 
 /*The following definitions come from  passdb/smbpasschange.c  */
 
-BOOL local_password_change(char *user_name,
-                               BOOL add_user,
-                               uint16 acb_info, uint16 acb_mask,
-                               char *new_passwd, 
-                               char *err_str, size_t err_str_len,
-                               char *msg_str, size_t msg_str_len);
+BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+                          char *new_passwd, 
+                          char *err_str, size_t err_str_len,
+                          char *msg_str, size_t msg_str_len);
 
 /*The following definitions come from  passdb/smbpassfile.c  */
 
+BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth);
+BOOL pw_file_unlock(int fd, int *plock_depth);
 BOOL trust_password_lock( char *domain, char *name, BOOL update);
 BOOL trust_password_unlock(void);
 BOOL trust_password_delete( char *domain, char *name );
 BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time);
 BOOL set_trust_account_password( unsigned char *md4_new_pwd);
 BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname);
-BOOL create_trust_account_file(char *domain, char *name, uchar pass[16]);
-
-/*The following definitions come from  passdb/smbpassgroup.c  */
-
-struct passgrp_ops *file_initialise_password_grp(void);
-
-/*The following definitions come from  passdb/smbpassgroupunix.c  */
-
-struct passgrp_ops *unix_initialise_password_grp(void);
-
-/*The following definitions come from  printing/nt_printing.c  */
-
-int get_ntforms(nt_forms_struct **list);
-int write_ntforms(nt_forms_struct **list, int number);
-void add_a_form(nt_forms_struct **list, FORM form, int *count);
-void update_a_form(nt_forms_struct **list, FORM form, int count);
-int get_ntdrivers(fstring **list, char *architecture);
-void get_short_archi(char *short_archi, char *long_archi);
-void dump_a_param(NT_PRINTER_PARAM *param);
-BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param);
-BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param);
-uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
-uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename);
-uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
-uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
-uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
-                            fstring printername, fstring architecture);
-uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
-BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
-                                 fstring value, uint8 **data, uint32 *type, uint32 *len);
-BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
-                        fstring value, uint8 **data, uint32 *type, uint32 *len);
-void init_devicemode(NT_DEVICEMODE *nt_devmode);
 
 /*The following definitions come from  printing/pcap.c  */
 
 BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
 void pcap_printer_fn(void (*fn)(char *, char *));
 
+/*The following definitions come from  printing/print_cups.c  */
+
+void cups_printer_fn(void (*fn)(char *, char *));
+int cups_printername_ok(char *name);
+
 /*The following definitions come from  printing/print_svid.c  */
 
 void sysv_printer_fn(void (*fn)(char *, char *));
@@ -1859,8 +1342,9 @@ int sysv_printername_ok(char *name);
 /*The following definitions come from  printing/printing.c  */
 
 void lpq_reset(int snum);
-void print_file(connection_struct *conn, int snum, files_struct *file);
-int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue,
+void print_file(connection_struct *conn, files_struct *file);
+int get_printqueue(int snum, 
+                  connection_struct *conn,print_queue_struct **queue,
                   print_status_struct *status);
 void del_printqueue(connection_struct *conn,int snum,int jobid);
 void status_printjob(connection_struct *conn,int snum,int jobid,int status);
@@ -1873,867 +1357,315 @@ void load_printers(void);
 
 BOOL profile_setup(BOOL rdonly);
 
-/*The following definitions come from  rpc_client/cli_atsvc.c  */
-
-BOOL at_add_job(
-               char *srv_name, AT_JOB_INFO *info, char *command,
-               uint32 *jobid);
-BOOL at_del_job( char *srv_name, uint32 min_jobid, uint32 max_jobid);
-BOOL at_enum_jobs( char *srv_name, uint32 *num_jobs,
-                 AT_ENUM_INFO *jobs, char ***commands);
-BOOL at_query_job(char *srv_name,
-                 uint32 jobid, AT_JOB_INFO *job, fstring command);
-
-/*The following definitions come from  rpc_client/cli_brs.c  */
-
-BOOL brs_query_info( const char *srv_name, uint32 switch_value,
-                       void *id);
-
-/*The following definitions come from  rpc_client/cli_connect.c  */
-
-void init_connections(void);
-void free_connections(void);
-void cli_connection_free(struct cli_connection *con);
-void cli_connection_unlink(struct cli_connection *con);
-BOOL cli_connection_init(const char* srv_name, const char* pipe_name,
-                               struct cli_connection **con);
-BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name,
-                               struct cli_connection **con);
-BOOL cli_connection_get(const POLICY_HND *pol, struct cli_connection **con);
-BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from);
-BOOL cli_get_con_usr_sesskey(struct cli_connection *con, uchar usr_sess_key[16]);
-BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]);
-BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name);
-BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar usr_sess_key[16]);
-BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16]);
-BOOL cli_get_sesskey_srv(const char* srv_name, uchar sess_key[16]);
-void cli_con_gen_next_creds(struct cli_connection *con,
-                               DOM_CRED *new_clnt_cred);
-void cli_con_get_cli_cred(struct cli_connection *con,
-                               DOM_CRED *clnt_cred);
-BOOL cli_con_deal_with_creds(struct cli_connection *con,
-                               DOM_CRED *rcv_srv_cred);
-BOOL cli_con_set_creds(const char* srv_name, const uchar sess_key[16],
-                               DOM_CRED *cred);
-BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num,
-                      prs_struct *data, prs_struct *rdata);
-BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
-                      prs_struct *data, prs_struct *rdata);
-
-/*The following definitions come from  rpc_client/cli_eventlog.c  */
-
-BOOL event_open(const char* srv_name, const char *log, POLICY_HND *hnd);
-BOOL event_close( POLICY_HND *hnd);
-BOOL event_numofeventlogrec( POLICY_HND *hnd, uint32 *number);
-BOOL event_readeventlog(POLICY_HND *hnd, 
-                           uint32 number, uint32 flags, uint32 offset, 
-                          uint32 *number_of_bytes, EVENTLOGRECORD *ev);
-
 /*The following definitions come from  rpc_client/cli_login.c  */
 
-uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               unsigned char trust_pwd[16],
-                               uint16 sec_chan);
-BOOL cli_nt_srv_pwset(const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               unsigned char *new_hashof_trust_pwd,
-                               uint16 sec_chan);
-BOOL cli_nt_login_interactive(const char* srv_name, const char* myhostname,
-                               const char *domain, const char *username, 
-                               uint32 luid_low, char *password,
-                               NET_ID_INFO_CTR *ctr,
-                               NET_USER_INFO_3 *user_info3);
-BOOL cli_nt_login_network(const char* srv_name, const char* myhostname,
-                               const char *domain, const char *username, 
-                               uint32 luid_low, char lm_chal[8],
-                               char lm_chal_resp[24],
-                               char nt_chal_resp[24],
-                               NET_ID_INFO_CTR *ctr,
-                               NET_USER_INFO_3 *user_info3);
-BOOL cli_nt_logoff(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr);
-BOOL net_sam_sync(const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               uchar trust_passwd[16],
-                               SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
-                               SAM_DELTA_CTR deltas    [MAX_SAM_DELTAS],
-                               uint32 *num_deltas);
+BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
+BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username, 
+                              uint32 smb_userid_low, char *password,
+                              NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, 
+                          uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
+                          char nt_chal_resp[24],
+                          NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
 
 /*The following definitions come from  rpc_client/cli_lsarpc.c  */
 
-BOOL get_domain_sids(const char *domain, DOM_SID *sid3, DOM_SID *sid5);
-BOOL get_trust_sid_and_domain(const char* myname, char *server,
-                               DOM_SID *sid,
-                               char *domain, size_t len);
-BOOL lsa_open_policy(const char *server_name, POLICY_HND *hnd,
+BOOL do_lsa_open_policy(struct cli_state *cli,
+                       char *server_name, POLICY_HND *hnd,
                        BOOL sec_qos);
-BOOL lsa_open_policy2( const char *server_name, POLICY_HND *hnd,
-                       BOOL sec_qos);
-BOOL lsa_open_secret( const POLICY_HND *hnd,
-                               const char *secret_name,
-                               uint32 des_access,
-                               POLICY_HND *hnd_secret);
-BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 *secret,
-                     NTTIME *last_update);
-BOOL lsa_lookup_names( POLICY_HND *hnd,
-                       int num_names,
-                       char **names,
-                       DOM_SID **sids,
-                       uint8 **types,
-                       int *num_sids);
-BOOL lsa_lookup_sids(POLICY_HND *hnd,
+BOOL do_lsa_lookup_sids(struct cli_state *cli,
+                       POLICY_HND *hnd,
                        int num_sids,
                        DOM_SID **sids,
                        char ***names,
-                       uint8 **types,
                        int *num_names);
-BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+BOOL do_lsa_query_info_pol(struct cli_state *cli,
+                       POLICY_HND *hnd, uint16 info_class,
                        fstring domain_name, DOM_SID *domain_sid);
-BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx,
-                       uint32 *num_doms, char ***names,
-                       DOM_SID ***sids);
-BOOL lsa_close(POLICY_HND *hnd);
+BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_client/cli_netlogon.c  */
 
-void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred);
-BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level);
-uint32 cli_net_auth2(const char *srv_name,
-                               const char *trust_acct, 
-                               const char *acct_name, 
-                               uint16 sec_chan, 
-                               uint32 neg_flags, DOM_CHAL *srv_chal);
-uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
-                               DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
-BOOL cli_net_srv_pwset(const char* srv_name,
-                               const char* myhostname,
-                               const char* trust_acct,
-                               uint8 hashed_trust_pwd[16],
-                               uint16 sec_chan_type);
-BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr, 
-                               NET_USER_INFO_3 *user_info3);
-BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr);
-BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
-                               uint32 database_id,
-                               uint32 *num_deltas,
-                               SAM_DELTA_HDR *hdr_deltas,
-                               SAM_DELTA_CTR *deltas);
-
-/*The following definitions come from  rpc_client/cli_netlogon_sync.c  */
-
-BOOL synchronise_passdb(void);
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
+BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, 
+                   uint32 neg_flags, DOM_CHAL *srv_chal);
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
+BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, 
+                       NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+BOOL change_trust_account_password( char *domain, char *remote_machine_list);
 
 /*The following definitions come from  rpc_client/cli_pipe.c  */
 
-BOOL create_rpc_bind_resp(struct pwd_info *pwd,
-                               char *domain, char *user_name, char *my_name,
-                               uint32 ntlmssp_cli_flgs,
-                               uint32 rpc_call_id,
-                               prs_struct *rhdr,
-                                prs_struct *rhdr_autha,
-                                prs_struct *auth_resp);
-BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num,
+BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                       prs_struct *data, prs_struct *rdata);
 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
-BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
-               uint16* fnum);
-void cli_nt_session_close(struct cli_state *cli, uint16 fnum);
+BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
+void cli_nt_session_close(struct cli_state *cli);
 
 /*The following definitions come from  rpc_client/cli_reg.c  */
 
-BOOL reg_connect( const char* srv_name,
-                               const char *full_keyname,
-                               char *key_name,
+BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
                                POLICY_HND *reg_hnd);
-BOOL reg_open_hkcr( struct cli_connection *con,
-                               uint16 unknown_0, uint32 level,
-                               POLICY_HND *hnd);
-BOOL reg_open_hklm( struct cli_connection *con,
-                               uint16 unknown_0, uint32 level,
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
                                POLICY_HND *hnd);
-BOOL reg_open_hku( struct cli_connection *con, 
-                               uint16 unknown_0, uint32 level,
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
                                POLICY_HND *hnd);
-BOOL reg_flush_key( POLICY_HND *hnd);
-BOOL reg_query_key( POLICY_HND *hnd,
-                               char *key_class, uint32 *class_len,
+BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd);
+BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
+                               char *class, uint32 *class_len,
                                uint32 *num_subkeys, uint32 *max_subkeylen,
                                uint32 *max_subkeysize, uint32 *num_values,
                                uint32 *max_valnamelen, uint32 *max_valbufsize,
                                uint32 *sec_desc, NTTIME *mod_time);
-BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk);
-BOOL reg_query_info( POLICY_HND *hnd,
-                               const char* val_name,
-                               uint32 *type, BUFFER2 *buffer);
-BOOL reg_set_key_sec( POLICY_HND *hnd,
-                               uint32 sec_info,
-                               uint32 sec_buf_size, SEC_DESC *sec_buf);
-BOOL reg_get_key_sec( POLICY_HND *hnd,
-                               uint32 sec_info,
-                               uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf);
-BOOL reg_delete_val( POLICY_HND *hnd, char *val_name);
-BOOL reg_delete_key( POLICY_HND *hnd, char *key_name);
-BOOL reg_create_key( POLICY_HND *hnd,
+BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk);
+BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
+                               char *type, uint32 *unk_0, uint32 *unk_1);
+BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf);
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf);
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name);
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name);
+BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
                                char *key_name, char *key_class,
                                SEC_ACCESS *sam_access,
                                POLICY_HND *key);
-BOOL reg_enum_key( POLICY_HND *hnd,
+BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
                                int key_index, char *key_name,
                                uint32 *unk_1, uint32 *unk_2,
                                time_t *mod_time);
-BOOL reg_create_val( POLICY_HND *hnd,
+BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
                                char *val_name, uint32 type, BUFFER3 *data);
-BOOL reg_enum_val( POLICY_HND *hnd,
+BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
                                int val_index, int max_valnamelen, int max_valbufsize,
                                fstring val_name,
                                uint32 *val_type, BUFFER2 *value);
-BOOL reg_open_entry( POLICY_HND *hnd,
+BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
                                char *key_name, uint32 unk_0,
                                POLICY_HND *key_hnd);
-BOOL reg_close( POLICY_HND *hnd);
-BOOL reg_shutdown(const char *srv_name,
-                       const char *msg, uint32 timeout, uint16 flags);
+BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_client/cli_samr.c  */
 
-BOOL samr_chgpasswd_user( struct cli_connection *con, 
+BOOL get_samr_query_usergroups(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain, uint32 user_rid,
+                               uint32 *num_groups, DOM_GID *gid);
+BOOL get_samr_query_userinfo(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 info_level,
+                               uint32 user_rid, SAM_USER_INFO_21 *usr);
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
                char *srv_name, char *user_name,
                char nt_newpass[516], uchar nt_oldhash[16],
                char lm_newpass[516], uchar lm_oldhash[16]);
-BOOL samr_unknown_38(struct cli_connection *con, char *srv_name);
-BOOL samr_query_dom_info(  POLICY_HND *domain_pol, uint16 switch_value,
-                               SAM_UNK_CTR *ctr);
-uint32 samr_enum_domains(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_domains);
-uint32 samr_enum_dom_groups(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_groups);
-uint32 samr_enum_dom_aliases(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_aliases);
-uint32 samr_enum_dom_users(  POLICY_HND *pol, uint32 *start_idx, 
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name);
+BOOL do_samr_query_dom_info(struct cli_state *cli, 
+                               POLICY_HND *domain_pol, uint16 switch_value);
+BOOL do_samr_enum_dom_users(struct cli_state *cli, 
+                               POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
                                uint16 acb_mask, uint16 unk_1, uint32 size,
                                struct acct_info **sam,
-                               uint32 *num_sam_users);
-BOOL samr_connect(  const char *srv_name, uint32 unknown_0,
+                               int *num_sam_users);
+BOOL do_samr_connect(struct cli_state *cli, 
+                               char *srv_name, uint32 unknown_0,
                                POLICY_HND *connect_pol);
-BOOL samr_open_user(  const POLICY_HND *pol,
-                               uint32 unk_0, uint32 rid, 
+BOOL do_samr_open_user(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 unk_0, uint32 rid, 
                                POLICY_HND *user_pol);
-BOOL samr_open_alias(  const POLICY_HND *domain_pol,
-                               uint32 flags, uint32 rid,
-                               POLICY_HND *alias_pol);
-BOOL samr_del_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid);
-BOOL samr_add_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid);
-BOOL samr_delete_dom_alias(  POLICY_HND *alias_pol);
-uint32 samr_create_dom_user(  POLICY_HND *domain_pol, const char *acct_name,
-                               uint32 unk_0, uint32 unk_1,
-                               POLICY_HND *user_pol, uint32 *rid);
-BOOL samr_create_dom_alias(  POLICY_HND *domain_pol, const char *acct_name,
-                               POLICY_HND *alias_pol, uint32 *rid);
-BOOL samr_query_aliasinfo(  POLICY_HND *alias_pol, uint16 switch_value,
-                               ALIAS_INFO_CTR *ctr);
-BOOL samr_set_aliasinfo(  POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr);
-BOOL samr_open_group(  const POLICY_HND *domain_pol,
-                               uint32 flags, uint32 rid,
-                               POLICY_HND *group_pol);
-BOOL samr_del_groupmem(  POLICY_HND *group_pol, uint32 rid);
-BOOL samr_add_groupmem(  POLICY_HND *group_pol, uint32 rid);
-BOOL samr_delete_dom_group(  POLICY_HND *group_pol);
-BOOL samr_create_dom_group(  POLICY_HND *domain_pol, const char *acct_name,
-                               POLICY_HND *group_pol, uint32 *rid);
-BOOL samr_set_groupinfo(  POLICY_HND *group_pol, GROUP_INFO_CTR *ctr);
-BOOL samr_open_domain(  const POLICY_HND *connect_pol,
-                               uint32 ace_perms,
-                               const DOM_SID *sid,
+BOOL do_samr_open_domain(struct cli_state *cli, 
+                               POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
                                POLICY_HND *domain_pol);
-BOOL samr_query_lookup_domain(  POLICY_HND *pol, const char *dom_name,
-                             DOM_SID *dom_sid);
-BOOL samr_query_lookup_names(  POLICY_HND *pol, uint32 flags,
-                               uint32 num_names, char **names,
-                               uint32 *num_rids,
-                               uint32 rid[MAX_LOOKUP_SIDS],
-                               uint32 type[MAX_LOOKUP_SIDS]);
-BOOL samr_query_lookup_rids(  const POLICY_HND *pol, uint32 flags,
-                               uint32 num_rids, uint32 *rids,
-                               uint32 *num_names,
-                               char   ***names,
-                               uint32 **type);
-BOOL samr_query_aliasmem(  const POLICY_HND *alias_pol, 
-                               uint32 *num_mem, DOM_SID2 *sid);
-BOOL samr_query_useraliases(  const POLICY_HND *pol,
-                               uint32 *ptr_sid, DOM_SID2 *sid,
-                               uint32 *num_aliases, uint32 **rid);
-BOOL samr_query_groupmem(  POLICY_HND *group_pol, 
-                               uint32 *num_mem, uint32 **rid, uint32 **attr);
-BOOL samr_query_usergroups(  POLICY_HND *pol, uint32 *num_groups,
-                               DOM_GID **gid);
-BOOL samr_query_groupinfo(  POLICY_HND *pol,
-                               uint16 switch_value, GROUP_INFO_CTR* ctr);
-BOOL samr_set_userinfo2(  POLICY_HND *pol, uint16 switch_value,
-                               void* usr);
-BOOL samr_set_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr);
-BOOL samr_query_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr);
-BOOL samr_close(  POLICY_HND *hnd);
-BOOL samr_query_dispinfo(  POLICY_HND *pol_domain, uint16 level,
-                               uint32 *num_entries,
-                               SAM_DISPINFO_CTR *ctr);
-
-/*The following definitions come from  rpc_client/cli_spoolss.c  */
-
-BOOL spoolss_enum_printers(uint32 flags, const char *srv_name,
-                       uint32 level,
-                       uint32 *count,
-                       void ***printers);
-uint32 spoolss_enum_jobs( const POLICY_HND *hnd,
-                       uint32 firstjob,
-                       uint32 numofjobs,
-                       uint32 level,
-                       uint32 *buf_size,
-                       uint32 *count,
-                       void ***jobs);
-BOOL spoolss_open_printer_ex( const char *printername,
-                       uint32 cbbuf, uint32 devmod, uint32 des_access,
-                       const char *station, const char *username,
-                       POLICY_HND *hnd);
-BOOL spoolss_closeprinter(POLICY_HND *hnd);
+BOOL do_samr_query_unknown_12(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
+                               uint32 *num_aliases,
+                               fstring als_names    [MAX_LOOKUP_SIDS],
+                               uint32  num_als_users[MAX_LOOKUP_SIDS]);
+BOOL do_samr_query_usergroups(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid);
+BOOL do_samr_query_userinfo(struct cli_state *cli, 
+                               POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_client/cli_srvsvc.c  */
 
-BOOL srv_net_srv_tprt_enum(
-                       const char *srv_name, 
-                       uint32 switch_value, SRV_TPRT_INFO_CTR *ctr,
-                       uint32 preferred_len,
-                       ENUM_HND *hnd);
-BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd);
-BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd);
-BOOL srv_net_srv_share_enum( char *srv_name, 
-                       uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
-                       uint32 preferred_len,
-                       ENUM_HND *hnd);
-BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
+BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
+                       char *server_name, 
+                       uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
+                       uint32 preferred_len, ENUM_HND *hnd);
+BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd);
-BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value,
-                               SRV_INFO_CTR *ctr);
-BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod);
-
-/*The following definitions come from  rpc_client/cli_svcctl.c  */
-
-BOOL svc_open_sc_man( const char *srv_name, char *db_name,
-                               uint32 des_access,
-                               POLICY_HND *hnd);
-BOOL svc_open_service( POLICY_HND *scm_hnd,
-                               const char *srv_name,
-                               uint32 des_access,
-                               POLICY_HND *hnd);
-BOOL svc_enum_svcs( POLICY_HND *hnd,
-                               uint32 services_type, uint32 services_state,
-                               uint32 *buf_size, uint32 *resume_hnd,
-                               uint32 *dos_error,
-                               ENUM_SRVC_STATUS **svcs, uint32 *num_svcs);
-BOOL svc_stop_service( POLICY_HND *hnd,
-                               uint32 unknown);
-BOOL svc_start_service( POLICY_HND *hnd,
-                               uint32 argc,
-                               char **argv);
-BOOL svc_query_svc_cfg( POLICY_HND *hnd,
-                               QUERY_SERVICE_CONFIG *cfg,
-                               uint32 *buf_size);
-BOOL svc_close(POLICY_HND *hnd);
-BOOL svc_change_svc_cfg( 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);
-
-/*The following definitions come from  rpc_client/cli_use.c  */
-
-void init_cli_use(void);
-void free_cli_use(void);
-struct cli_state *cli_net_use_add(const char* srv_name,
-                               const struct ntuser_creds *usr_creds,
-                               BOOL redir,
-                               BOOL reuse);
-BOOL cli_net_use_del(const char* srv_name,
-                               const struct ntuser_creds *usr_creds,
-                               BOOL force_close,
-                               BOOL *connection_closed);
-void cli_net_use_enum(uint32 *num_cons, struct use_info ***use);
-void cli_use_wait_keyboard(void);
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+                       char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr);
 
 /*The following definitions come from  rpc_client/cli_wkssvc.c  */
 
-BOOL wks_query_info( char *srv_name, uint32 switch_value,
+BOOL do_wks_query_info(struct cli_state *cli, 
+                       char *server_name, uint32 switch_value,
                        WKS_INFO_100 *wks100);
 
-/*The following definitions come from  rpc_client/msrpc_lsarpc.c  */
-
-BOOL msrpc_lsa_query_secret(const char* srv_name,
-                               const char* secret_name,
-                               STRING2 *secret,
-                               NTTIME *last_update);
-
-/*The following definitions come from  rpc_client/msrpc_netlogon.c  */
-
-BOOL check_domain_security(char *orig_user, char *domain, 
-                               uchar *challenge,
-                               char *smb_apasswd, int smb_apasslen,
-                               char *smb_ntpasswd, int smb_ntpasslen,
-                               uchar user_sess_key[16]);
-
-/*The following definitions come from  rpc_client/msrpc_samr.c  */
-
-BOOL req_user_info( const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 user_rid,
-                               USER_INFO_FN(usr_inf));
-uint32 sam_query_usergroups(
-                               const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 user_rid,
-                               const char *user_name,
-                               uint32 *num_groups,
-                               DOM_GID **gid,
-                               char    ***name,
-                               uint32  **type,
-                               USER_MEM_FN(usr_mem));
-void msrpc_sam_user( const POLICY_HND *pol_dom, const POLICY_HND *pol_blt,
-                       const char* domain,
-                       const DOM_SID *sid1,
-                       const DOM_SID *blt_sid1,
-                       uint32 user_rid,
-                       char  *user_name,
-                       USER_FN(usr_fn),
-                       USER_INFO_FN(usr_inf_fn),
-                       USER_MEM_FN(usr_grp_fn),
-                       USER_MEM_FN(usr_als_fn));
-BOOL msrpc_sam_query_user( const char* srv_name,
-                       const char* domain,
-                       const DOM_SID *sid,
-                       char  *user_name,
-                       USER_FN(usr_fn),
-                       USER_INFO_FN(usr_inf_fn),
-                       USER_MEM_FN(usr_grp_fn),
-                       USER_MEM_FN(usr_als_fn));
-int msrpc_sam_enum_users( const char* srv_name,
-                       const char* domain,
-                       const DOM_SID *sid1,
-                       struct acct_info **sam,
-                       uint32 *num_sam_entries,
-                       USER_FN(usr_fn),
-                       USER_INFO_FN(usr_inf_fn),
-                       USER_MEM_FN(usr_grp_fn),
-                       USER_MEM_FN(usr_als_fn));
-BOOL sam_query_dominfo(const char* srv_name,
-                               const DOM_SID *sid1,
-                               uint32 switch_value, SAM_UNK_CTR *ctr);
-BOOL query_aliasinfo(
-                               const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 alias_rid,
-                               ALIAS_INFO_FN(grp_inf));
-BOOL sam_query_aliasmem(const char *srv_name,
-                               const POLICY_HND *pol_dom,
-                               uint32 alias_rid,
-                               uint32 *num_names,
-                               DOM_SID ***sids,
-                               char ***name,
-                               uint8 **type);
-BOOL req_aliasmem_info(const char* srv_name,
-                               const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 alias_rid,
-                               const char *alias_name,
-                               ALIAS_MEM_FN(als_mem));
-BOOL sam_query_groupmem(
-                               const POLICY_HND *pol_dom,
-                               uint32 group_rid,
-                               uint32 *num_names,
-                               uint32 **rid_mem,
-                               char ***name,
-                               uint32 **type);
-BOOL query_groupinfo( const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 group_rid,
-                               GROUP_INFO_FN(grp_inf));
-BOOL req_groupmem_info( const POLICY_HND *pol_dom,
-                               const char *domain,
-                               const DOM_SID *sid,
-                               uint32 group_rid,
-                               const char *group_name,
-                               GROUP_MEM_FN(grp_mem));
-uint32 msrpc_sam_enum_domains( const char* srv_name,
-                               struct acct_info **sam,
-                               uint32 *num_sam_entries,
-                               DOMAIN_FN(dom_fn),
-                               DOMAIN_INFO_FN(dom_inf_fn));
-uint32 msrpc_sam_enum_groups( const char* srv_name,
-                               const char* domain,
-                               const DOM_SID *sid1,
-                               struct acct_info **sam,
-                               uint32 *num_sam_entries,
-                               GROUP_FN(grp_fn),
-                               GROUP_INFO_FN(grp_inf_fn),
-                               GROUP_MEM_FN(grp_mem_fn));
-uint32 msrpc_sam_enum_aliases( const char* srv_name,
-                               const char* domain,
-                               const DOM_SID *sid1,
-                               struct acct_info **sam,
-                               uint32 *num_sam_entries,
-                               ALIAS_FN(als_fn),
-                               ALIAS_INFO_FN(als_inf_fn),
-                               ALIAS_MEM_FN(als_mem_fn));
-BOOL create_samr_domain_user( POLICY_HND *pol_dom,
-                               char *acct_name, uint16 acb_info,
-                               const char* password, int plen,
-                               uint32 *rid);
-BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
-                               const char *acct_name, const char *acct_desc,
-                               uint32 *rid);
-BOOL create_samr_domain_group(
-                               POLICY_HND *pol_open_domain,
-                               const char *acct_name, const char *acct_desc,
-                               uint32 *rid);
-BOOL get_samr_query_usergroups( const POLICY_HND *pol_open_domain,
-                               uint32 user_rid,
-                               uint32 *num_groups, DOM_GID **gid);
-BOOL delete_samr_dom_group(
-                               POLICY_HND *pol_open_domain,
-                               uint32 group_rid);
-BOOL get_samr_query_groupmem( 
-                               const POLICY_HND *pol_open_domain,
-                               uint32 group_rid, uint32 *num_mem,
-                               uint32 **rid, uint32 **attr);
-BOOL delete_samr_dom_alias( 
-                               POLICY_HND *pol_open_domain,
-                               uint32 alias_rid);
-BOOL get_samr_query_aliasmem( 
-                               const POLICY_HND *pol_open_domain,
-                               uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
-BOOL set_samr_set_userinfo2( 
-                               POLICY_HND *pol_open_domain,
-                               uint32 info_level,
-                               uint32 user_rid, void *usr);
-BOOL set_samr_set_userinfo( 
-                               POLICY_HND *pol_open_domain,
-                               uint32 info_level,
-                               uint32 user_rid, void *usr);
-BOOL get_samr_query_userinfo( 
-                               const POLICY_HND *pol_open_domain,
-                               uint32 info_level,
-                               uint32 user_rid, void *usr);
-BOOL get_samr_query_groupinfo( 
-                               const POLICY_HND *pol_open_domain,
-                               uint32 info_level,
-                               uint32 group_rid, GROUP_INFO_CTR *ctr);
-BOOL get_samr_query_aliasinfo( 
-                               const POLICY_HND *pol_open_domain,
-                               uint32 info_level,
-                               uint32 alias_rid, ALIAS_INFO_CTR *ctr);
-BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
-                               char *acct_name, uint16 acb_info,
-                               const char *password, int plen,
-                               uint32 *rid);
-BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
-                               DOM_SID *sid1,
-                               uint16 switch_value,
-                               uint32 *num_entries, SAM_DISPINFO_CTR *ctr,
-                               DISP_FN(disp_fn));
-
-/*The following definitions come from  rpc_parse/parse_at.c  */
-
-BOOL make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server,
-                       AT_JOB_INFO *info, char *command);
-BOOL at_io_job_info(char *desc, AT_JOB_INFO *info, prs_struct *ps, int depth);
-BOOL at_io_q_add_job(char *desc, AT_Q_ADD_JOB *q_a, prs_struct *ps, int depth);
-BOOL at_io_r_add_job(char *desc, AT_R_ADD_JOB *r_a, prs_struct *ps, int depth);
-BOOL make_at_q_del_job(AT_Q_DEL_JOB *q_a, char *server, uint32 min_jobid,
-                      uint32 max_jobid);
-BOOL at_io_q_del_job(char *desc, AT_Q_DEL_JOB *q_d, prs_struct *ps, int depth);
-BOOL at_io_r_del_job(char *desc, AT_R_DEL_JOB *r_d, prs_struct *ps, int depth);
-BOOL make_at_q_enum_jobs(AT_Q_ENUM_JOBS *q_e, char *server);
-BOOL at_io_q_enum_jobs(char *desc, AT_Q_ENUM_JOBS *q_e, prs_struct *ps, int depth);
-BOOL at_io_r_enum_jobs(char *desc, AT_R_ENUM_JOBS *r_e, prs_struct *ps, int depth);
-BOOL make_at_q_query_job(AT_Q_QUERY_JOB *q_q, char *server, uint32 jobid);
-BOOL at_io_q_query_job(char *desc, AT_Q_QUERY_JOB *q_q, prs_struct *ps, int depth);
-BOOL at_io_r_query_job(char *desc, AT_R_QUERY_JOB *r_q, prs_struct *ps, int depth);
-
-/*The following definitions come from  rpc_parse/parse_brs.c  */
-
-BOOL make_brs_q_query_info(BRS_Q_QUERY_INFO *q_u,
-                               const char *server, uint16 switch_value)  ;
-BOOL brs_io_q_query_info(char *desc, BRS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
-BOOL make_brs_info_100(BRS_INFO_100 *inf);
-BOOL make_brs_r_query_info(BRS_R_QUERY_INFO *r_u,
-                               uint32 switch_value, void *inf,
-                               int status)  ;
-BOOL brs_io_r_query_info(char *desc,  BRS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
-
-/*The following definitions come from  rpc_parse/parse_creds.c  */
-
-BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
-                               const char* requested_name,
-                               const char* real_name,
-                               BOOL guest);
-BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth);
-void creds_free_unix(CREDS_UNIX *r_u);
-BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
-               uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
-BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
-void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
-BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
-               DOM_SID *sid, uint32 num_grps, uint32 *grps);
-BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth);
-void creds_free_nt_sec(CREDS_NT_SEC *r_u);
-BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
-BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
-void creds_free_nt(CREDS_NT *r_u);
-BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
-void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
-void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from);
-void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
-void copy_nt_creds(struct ntuser_creds *to,
-                               const struct ntuser_creds *from);
-void copy_user_creds(struct user_creds *to,
-                               const struct user_creds *from);
-void free_user_creds(struct user_creds *creds);
-BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
-BOOL create_ntuser_creds( prs_struct *ps,
-                               const char* name, 
-                               uint16 version, uint16 command,
-                               const struct ntuser_creds *ntu,
-                               BOOL reuse);
-BOOL create_user_creds( prs_struct *ps,
-                               const char* name, 
-                               uint16 version, uint16 command,
-                               const struct user_creds *usr);
-
-/*The following definitions come from  rpc_parse/parse_eventlog.c  */
-
-BOOL make_eventlog_q_open(EVENTLOG_Q_OPEN *q_u, const char *journal, char *unk);
-BOOL eventlog_io_q_open(char *desc, EVENTLOG_Q_OPEN *q_u, prs_struct *ps, int depth);
-BOOL eventlog_io_r_open(char *desc, EVENTLOG_R_OPEN *r_u, prs_struct *ps, int depth);
-BOOL make_eventlog_q_close(EVENTLOG_Q_CLOSE *q_u, POLICY_HND *pol);
-BOOL eventlog_io_q_close(char *desc, EVENTLOG_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL eventlog_io_r_close(char *desc, EVENTLOG_R_CLOSE *r_u, prs_struct *ps, int depth);
-BOOL make_eventlog_q_numofeventlogrec(EVENTLOG_Q_NUMOFEVENTLOGREC *q_u, POLICY_HND *pol);
-BOOL eventlog_io_q_numofeventlogrec(char *desc,EVENTLOG_Q_NUMOFEVENTLOGREC  *q_u, prs_struct *ps, int depth);
-BOOL eventlog_io_r_numofeventlogrec(char *desc, EVENTLOG_R_NUMOFEVENTLOGREC *r_u, prs_struct *ps, int depth);
-BOOL make_eventlog_q_readeventlog(EVENTLOG_Q_READEVENTLOG *q_u, POLICY_HND *pol,
-                                  uint32 flags, uint32 offset, uint32 number_of_bytes);
-BOOL eventlog_io_q_readeventlog(char *desc, EVENTLOG_Q_READEVENTLOG *q_u, prs_struct *ps, int depth);
-BOOL eventlog_io_r_readeventlog(char *desc, EVENTLOG_R_READEVENTLOG *r_u, prs_struct *ps, int depth);
-
 /*The following definitions come from  rpc_parse/parse_lsa.c  */
 
-BOOL make_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
+void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
                        uint32 sid_name_use, char *name, uint32 idx);
-BOOL make_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
+void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
                                uint32 unknown);
-BOOL make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos);
-BOOL make_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
+void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos);
+void init_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
                        uint32 attributes,
                        uint32 desired_access,
                        LSA_SEC_QOS *qos);
-BOOL lsa_io_q_open_pol(char *desc,  LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth);
-BOOL lsa_io_r_open_pol(char *desc,  LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth);
-BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name,
+BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth);
+BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth);
+void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name,
                        uint32 attributes,
                        uint32 desired_access,
                        LSA_SEC_QOS *qos);
-BOOL lsa_io_q_open_pol2(char *desc,  LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth);
-BOOL lsa_io_r_open_pol2(char *desc,  LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth);
-BOOL make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
-BOOL lsa_io_q_query(char *desc,  LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth);
-BOOL make_q_open_secret(LSA_Q_OPEN_SECRET *q_o, const POLICY_HND *pol_hnd,
-                       const char *secret_name, uint32 desired_access);
-BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_o, prs_struct *ps, int depth);
-BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_o, prs_struct *ps, int depth);
-BOOL lsa_io_secret_value(char *desc, LSA_SECRET_VALUE *value, prs_struct *ps, int depth);
-BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO *info, prs_struct *ps, int depth);
-BOOL make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol);
-BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET *q_q, prs_struct *ps, int depth);
-BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, int depth);
-BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
-                               POLICY_HND *pol,
-                               uint32 enum_context, uint32 preferred_len);
-BOOL lsa_io_q_enum_trust_dom(char *desc,  LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth);
-BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
-                               int32 enum_context,
-                               char *domain_name, DOM_SID *domain_sid,
-                               uint32 status);
-BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth);
-BOOL lsa_io_r_query(char *desc,  LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth);
-BOOL make_lsa_sid_enum(LSA_SID_ENUM *sen, uint32 num_entries, DOM_SID **sids);
-BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
+BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth);
+BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth);
+void init_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
+BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth);
+BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth);
+void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
+                           uint32 enum_context, char *domain_name, DOM_SID *domain_sid,
+                           uint32 status);
+BOOL lsa_io_r_enum_trust_dom(char *desc,  LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth);
+BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth);
+void init_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids);
+void init_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
                                int num_sids, DOM_SID **sids,
                                uint16 level);
 BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth);
-BOOL lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth);
-BOOL make_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
-                               uint32 num_names, char **names);
-BOOL lsa_io_q_lookup_names(char *desc,  LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth);
-BOOL lsa_io_r_lookup_names(char *desc,  LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth);
-BOOL make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL lsa_io_q_close(char *desc,  LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth);
+void init_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
+                int num_names, char **names);
+BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth);
+BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth);
+void init_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
+BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
 BOOL lsa_io_r_close(char *desc,  LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_misc.c  */
 
-BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth);
-BOOL smb_io_time(char *desc,  NTTIME *nttime, prs_struct *ps, int depth);
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
 BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
 uint32 get_enum_hnd(ENUM_HND *enh);
-BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd);
-BOOL smb_io_enum_hnd(char *desc,  ENUM_HND *hnd, prs_struct *ps, int depth);
-BOOL smb_io_dom_sid(char *desc,  DOM_SID *sid, prs_struct *ps, int depth);
-BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
-BOOL smb_io_dom_sid2(char *desc,  DOM_SID2 *sid, prs_struct *ps, int depth);
-BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
+void init_enum_hnd(ENUM_HND *enh, uint32 hnd);
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+void init_dom_sid(DOM_SID *sid, char *str_sid);
+void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid);
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
+void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
 BOOL smb_io_strhdr(char *desc,  STRHDR *hdr, prs_struct *ps, int depth);
-BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer);
-BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth);
-BOOL make_uni_hdr(UNIHDR *hdr, int len);
-BOOL smb_io_unihdr(char *desc,  UNIHDR *hdr, prs_struct *ps, int depth);
-BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len);
-BOOL smb_io_hdrbuf_pre(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
-BOOL smb_io_hdrbuf_post(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, 
+void init_uni_hdr(UNIHDR *hdr, int len);
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
+void init_buf_hdr(BUFHDR *hdr, int max_len, int len);
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, 
                                uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
-BOOL smb_io_hdrbuf(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth);
-BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
-BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
-BOOL make_uni_hdr2(UNIHDR2 *hdr, int len);
-BOOL smb_io_unihdr2(char *desc,  UNIHDR2 *hdr2, prs_struct *ps, int depth);
-BOOL make_unistr(UNISTR *str, char *buf);
-BOOL smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps, int depth);
-BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val);
-BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len);
-BOOL make_buffer3_hex(BUFFER3 *str, char *buf);
-BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
-BOOL smb_io_buffer3(char *desc,  BUFFER3 *buf3, prs_struct *ps, int depth);
-BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len);
-BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
-BOOL init_buffer5(BUFFER5 **str);
-BOOL clear_buffer5(BUFFER5 **str);
-BOOL make_buffer5(BUFFER5 *str, char *buf, int len);
-BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
-BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num);
-BOOL make_buffer2(BUFFER2 *str, const char *buf, int len);
-BOOL smb_io_buffer2(char *desc,  BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
-BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
-BOOL make_string2(STRING2 *str, const char *buf, int len);
-BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf);
-BOOL smb_io_string2(char *desc,  STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
-BOOL make_unistr2(UNISTR2 *str, const char *buf, int len);
-BOOL smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
-BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
-BOOL smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps, int depth);
-BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
-BOOL smb_io_dom_rid3(char *desc,  DOM_RID3 *rid3, 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 smb_io_chal(char *desc,  DOM_CHAL *chal, prs_struct *ps, int depth);
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
+void init_uni_hdr2(UNIHDR2 *hdr, int len);
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+void init_unistr(UNISTR *str, char *buf);
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
+void init_buffer3_uint32(BUFFER3 *str, uint32 val);
+void init_buffer3_str(BUFFER3 *str, char *buf, int len);
+void init_buffer3_hex(BUFFER3 *str, char *buf);
+void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+void init_buffer2(BUFFER2 *str, uint8 *buf, int len);
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
+void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf);
+void copy_unistr2(UNISTR2 *str, UNISTR2 *from);
+void init_string2(STRING2 *str, char *buf, int len);
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+void init_unistr2(UNISTR2 *str, char *buf, int len);
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
+void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
+void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
+void init_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
+               uint16 sec_chan, char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
 BOOL smb_io_cred(char *desc,  DOM_CRED *cred, prs_struct *ps, int depth);
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
-                               const char *logon_srv, const char *comp_name,
+void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
+                               char *logon_srv, 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,
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+void init_clnt_info(DOM_CLNT_INFO *clnt,
+               char *logon_srv, char *acct_name,
+               uint16 sec_chan, 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, uint8 data[16]);
+void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
+BOOL smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth);
+void init_owf_info(OWF_INFO *hash, uint8 data[16]);
 BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
 BOOL smb_io_gid(char *desc,  DOM_GID *gid, prs_struct *ps, int depth);
-BOOL smb_io_pol_hnd(char *desc,  POLICY_HND *pol, prs_struct *ps, int depth);
-BOOL smb_io_dom_query_3(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
-BOOL smb_io_dom_query_5(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
-BOOL smb_io_unistr3(char *desc,  UNISTR3 *name, prs_struct *ps, int depth);
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+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_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);
-BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
                                uint32 flags, uint32 pdc_status, uint32 logon_attempts,
                                uint32 tc_status, char *trusted_domain_name);
-BOOL net_io_r_logon_ctrl2(char *desc,  NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
-BOOL make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
-                       uint32 num_doms, char **dom_name);
-BOOL net_io_r_trust_dom(char *desc,  NET_R_TRUST_DOM_LIST *r_t, 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);
-BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
-                               const char *logon_srv, const char *logon_clnt,
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
+                       uint32 num_doms, char *dom_name);
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, 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);
+void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
+                               char *logon_srv, char *logon_clnt,
                                DOM_CHAL *clnt_chal);
 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, 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 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,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+void init_q_auth_2(NET_Q_AUTH_2 *q_a,
+               char *logon_srv, char *acct_name, uint16 sec_chan, 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, int depth);
-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, int depth);
-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,
+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, int depth);
+void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
+                uint16 sec_chan, 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, int depth);
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
                                uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
-                               const char *user_name, const char *wksta_name,
+                               char *user_name, char *wksta_name,
                                char sess_key[16],
                                unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
-BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
-                               uint32 param_ctrl,
-                               uint32 log_id_low, uint32 log_id_high,
-                               const char *user_name, const char *wksta_name,
+void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
+                               uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+                               char *user_name, char *wksta_name,
                                unsigned char lm_challenge[8],
                                unsigned char lm_chal_resp[24],
                                unsigned char nt_chal_resp[24]);
-BOOL make_sam_info(DOM_SAM_INFO *sam,
-                               const char *logon_srv, const char *comp_name,
-                               DOM_CRED *clnt_cred,
+void init_sam_info(DOM_SAM_INFO *sam,
+                               char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
                                DOM_CRED *rtn_cred, uint16 logon_level,
                                NET_ID_INFO_CTR *ctr);
-BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
+void init_net_user_info3(NET_USER_INFO_3 *usr,
 
        NTTIME *logon_time,
        NTTIME *logoff_time,
@@ -2765,518 +1697,284 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
 
        DOM_SID *dom_sid,
        char *other_sids);
-BOOL net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
-BOOL net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+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, int depth);
-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, int depth);
-BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid);
-BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info, char *user_name,
-                          char *full_name, uint32 user_rid, uint32 group_rid,
-                          char *home_dir, char *dir_drive, char *logon_script,
-                          char *acct_desc, uint32 acb_info, char *profile);
-BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
-                               NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth);
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_prs.c  */
 
 void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name);
-void prs_debug_out(prs_struct *ps, char *msg, int level);
-void prs_init(prs_struct *ps, uint32 size,
-                               uint8 align, uint32 margin,
-                               BOOL io);
-BOOL prs_copy(prs_struct *ps, const prs_struct *from);
+BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
 void prs_mem_free(prs_struct *ps);
-void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next);
-void prs_align(prs_struct *ps);
-BOOL prs_grow(prs_struct *ps, uint32 new_size);
-BOOL prs_append_data(prs_struct *ps, const char *data, int len);
-BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
-BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
-BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
-BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
-BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
-BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
-BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
-BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
-BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
-BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
-BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
-BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
-BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size);
-BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
-BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic);
+char *prs_take_memory(prs_struct *ps, uint32 *psize);
+BOOL prs_grow(prs_struct *ps, uint32 extra_space);
+BOOL prs_force_grow(prs_struct *ps, uint32 extra_space);
+char *prs_data_p(prs_struct *ps);
+uint32 prs_data_size(prs_struct *ps);
+uint32 prs_offset(prs_struct *ps);
+BOOL prs_set_offset(prs_struct *ps, uint32 offset);
+BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src);
+BOOL prs_append_data(prs_struct *dst, char *src, uint32 len);
+void prs_set_bigendian_data(prs_struct *ps);
+BOOL prs_align(prs_struct *ps);
+char *prs_mem_get(prs_struct *ps, uint32 extra_size);
+BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
+BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
+BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size);
+BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
+BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
                                uint32 ptr_uint16, uint32 start_offset);
-BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
-BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
+BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
                                uint32 ptr_uint32, uint32 data_size);
 
 /*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,
+void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
                                uint16 unknown_0, uint32 level);
 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);
+void init_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);
+void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+                               char *name, char *class, SEC_ACCESS *sam_access,
+                               SEC_DESC_BUF *sec_buf);
 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,
+void init_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,
+void init_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,
+void init_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);
+void init_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,
+void init_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);
+void init_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);
+void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf);
 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);
+void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, 
+                               uint32 sec_buf_size, SEC_DESC_BUF *psdb);
 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);
+void init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type,
+                               time_t unix_time, 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,
+void init_reg_r_info(REG_R_INFO *r_r,
+                               uint32 level, char *os_type,
+                               uint32 unknown_0, uint32 unknown_1,
                                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,
+void init_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,
+void init_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);
+void init_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,
+void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
                                char *key_name, uint32 unk);
 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,
+void init_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  */
 
-BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
                                uint32 call_id, int data_len, int auth_len);
 BOOL smb_io_rpc_hdr(char *desc,  RPC_HDR *rpc, prs_struct *ps, int depth);
-BOOL smb_io_rpc_hdr_fault(char *desc,  RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc, 
+void init_rpc_hdr_rb(RPC_HDR_RB *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
                                uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
                                RPC_IFACE *abstract, RPC_IFACE *transfer);
-BOOL smb_io_rpc_hdr_rb(char *desc,  RPC_HDR_RB *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc, 
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
+void init_rpc_hdr_ba(RPC_HDR_BA *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
-                               const char *pipe_addr,
+                               char *pipe_addr,
                                uint8 num_results, uint16 result, uint16 reason,
                                RPC_IFACE *transfer);
-BOOL smb_io_rpc_hdr_ba(char *desc,  RPC_HDR_BA *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
-BOOL smb_io_rpc_hdr_req(char *desc,  RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
-BOOL smb_io_rpc_hdr_resp(char *desc,  RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
-BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
+void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
                                uint16 max_tsize, uint16 max_rsize,
                                uint8 auth_type, uint8 auth_level,
                                uint8 stub_type_len);
 BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
 BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai);
-BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
                                uint8 auth_type, uint8 auth_level,
                                uint8 stub_type_len,
                                uint32 ptr);
 BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
-BOOL rpc_auth_ntlmssp_verifier_chk(RPC_AUTH_NTLMSSP_VERIFIER *rav,
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
                                char *signature, uint32 msg_type);
-BOOL make_rpc_auth_ntlmssp_verifier(RPC_AUTH_NTLMSSP_VERIFIER *rav,
+void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
                                char *signature, uint32 msg_type);
-BOOL smb_io_rpc_auth_ntlmssp_verifier(char *desc, RPC_AUTH_NTLMSSP_VERIFIER *rav, prs_struct *ps, int depth);
-BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth);
+void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
                                uint32 neg_flgs,
                                fstring myname, fstring domain);
 BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
-BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
                                uint32 neg_flags,
                                uint8 challenge[8]);
 BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
-BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
-                               uchar lm_resp[24],
-                               uchar *nt_resp, size_t nt_len,
+void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+                               uchar lm_resp[24], uchar nt_resp[24],
                                char *domain, char *user, char *wks,
                                uint32 neg_flags);
 BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
 BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num);
-BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+void init_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
                                uint32 ver, uint32 crc32, uint32 seq_num);
 BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
 
 /*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);
+void init_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);
 BOOL samr_io_r_close_hnd(char *desc,  SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
-               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);
-BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, 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);
-BOOL samr_io_q_open_domain(char *desc,  SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_open_domain(char *desc,  SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol);
+void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+                               POLICY_HND *connect_pol, uint32 rid,
+                               DOM_SID *sid);
+BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
+void init_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol);
 BOOL samr_io_q_unknown_2c(char *desc,  SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status);
+void init_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status);
 BOOL samr_io_r_unknown_2c(char *desc,  SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+void init_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
                                POLICY_HND *user_pol, uint16 switch_value);
 BOOL samr_io_q_unknown_3(char *desc,  SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth);
-BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
                                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);
-BOOL make_unk_info3(SAM_UNK_INFO_3 *u_3);
-BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 *u_3, prs_struct *ps, int depth);
-BOOL make_unk_info6(SAM_UNK_INFO_6 *u_6);
-BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 *u_6, prs_struct *ps, int depth);
-BOOL make_unk_info7(SAM_UNK_INFO_7 *u_7);
-BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth);
-BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
+void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
 BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth);
-BOOL make_unk_info1(SAM_UNK_INFO_1 *u_1);
-BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth);
-BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u, 
+void init_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);
-BOOL make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid);
-BOOL make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
+void init_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid);
+void init_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
                                uint16 unknown_2, uint16 unknown_3,
                                uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
                                int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
                                uint32 status);
 BOOL samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
-                               uint32 start_idx, 
+void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+                               uint16 req_num_entries, uint16 unk_0,
                                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);
-BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
-               uint32 next_idx,
+void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+               uint16 total_num_entries, uint16 unk_0,
                uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status);
-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,
-                               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);
-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]);
-BOOL make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-BOOL make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        DOMAIN_GRP *grp);
-BOOL make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-BOOL make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        DOMAIN_GRP *grp);
-BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
-                               uint32 num_entries, uint32 data_size,
-                               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);
-BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c,
-                               const POLICY_HND *hnd, uint32 unk, uint32 rid);
-BOOL samr_io_q_open_group(char *desc,  SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_open_group(char *desc,  SAMR_R_OPEN_GROUP *r_u, 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);
-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);
-BOOL samr_group_info_ctr(char *desc,  GROUP_INFO_CTR *ctr, 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);
-BOOL samr_io_q_create_dom_group(char *desc,  SAMR_Q_CREATE_DOM_GROUP *q_e, prs_struct *ps, int depth);
-BOOL make_samr_r_create_dom_group(SAMR_R_CREATE_DOM_GROUP *r_u, POLICY_HND *pol,
-               uint32 rid, uint32 status);
-BOOL samr_io_r_create_dom_group(char *desc,  SAMR_R_CREATE_DOM_GROUP *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_c, POLICY_HND *hnd);
-BOOL samr_io_q_delete_dom_group(char *desc,  SAMR_Q_DELETE_DOM_GROUP *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_delete_dom_group(SAMR_R_DELETE_DOM_GROUP *r_u,
-               uint32 status);
-BOOL samr_io_r_delete_dom_group(char *desc,  SAMR_R_DELETE_DOM_GROUP *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_e,
-                               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,
-               uint32 status);
-BOOL samr_io_r_del_groupmem(char *desc,  SAMR_R_DEL_GROUPMEM *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_e,
-                               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,
-               uint32 status);
-BOOL samr_io_r_add_groupmem(char *desc,  SAMR_R_ADD_GROUPMEM *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO *q_e,
-                               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);
-BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO *r_u, 
+BOOL samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
+void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size);
+BOOL samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth);
+void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+               uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
                uint32 status);
-BOOL samr_io_r_set_groupinfo(char *desc,  SAMR_R_SET_GROUPINFO *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_e,
-                               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);
-BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO *r_u, GROUP_INFO_CTR *ctr,
+BOOL samr_io_r_enum_dom_aliases(char *desc,  SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth);
+void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+                               uint16 switch_level, uint32 start_idx, uint32 size);
+BOOL samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth);
+void init_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+void init_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+               uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status);
+BOOL samr_io_r_query_dispinfo(char *desc,  SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth);
+void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+                               uint16 switch_level, 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);
+void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
                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);
-BOOL samr_io_q_query_groupmem(char *desc,  SAMR_Q_QUERY_GROUPMEM *q_u, 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);
-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);
-BOOL samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, 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_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS *q_e, 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);
-BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS *r_u,
-               uint32 next_idx,
-               uint32 num_sam_entries, char **doms, uint32 status);
-BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, 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);
-BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
-               uint32 next_idx,
-               uint32 num_sam_entries, DOMAIN_GRP *grps, uint32 status);
-BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, 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, uint32 size);
-BOOL samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, 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, LOCAL_GRP *alss, uint32 status);
-BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, 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);
-BOOL samr_alias_info_ctr(char *desc,  ALIAS_INFO_CTR *ctr, prs_struct *ps, int depth);
-BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+BOOL samr_io_r_enum_dom_groups(char *desc,  SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth);
+void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
                                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);
-BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, ALIAS_INFO_CTR *ctr,
+void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
+               uint16 switch_value, char *acct_desc,
                uint32 status);
 BOOL samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO *q_u, 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);
-BOOL samr_io_r_set_aliasinfo(char *desc,  SAMR_R_SET_ALIASINFO *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
-                               const POLICY_HND *hnd,
-                               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);
-void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u);
-BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u,
+BOOL samr_io_q_lookup_ids(char *desc,  SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth);
+void init_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
                uint32 num_rids, uint32 *rid, uint32 status);
-BOOL samr_io_r_query_useraliases(char *desc,  SAMR_R_QUERY_USERALIASES *r_u, prs_struct *ps, int depth);
-void samr_free_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u);
-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);
-BOOL samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
-               const POLICY_HND *pol, uint32 flags,
-               uint32 num_rids, uint32 *rid);
-BOOL samr_io_q_lookup_rids(char *desc,  SAMR_Q_LOOKUP_RIDS *q_u, 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, fstring *name, uint8 *type,
-               uint32 status);
-BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, 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 samr_io_q_delete_alias(char *desc,  SAMR_Q_DELETE_DOM_ALIAS *q_u, 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);
-BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, 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);
-BOOL make_samr_r_create_dom_alias(SAMR_R_CREATE_DOM_ALIAS *r_u, POLICY_HND *pol,
-               uint32 rid, uint32 status);
-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);
-BOOL samr_io_q_add_aliasmem(char *desc,  SAMR_Q_ADD_ALIASMEM *q_u, 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);
-BOOL samr_io_q_del_aliasmem(char *desc,  SAMR_Q_DEL_ALIASMEM *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_del_aliasmem(char *desc,  SAMR_R_DEL_ALIASMEM *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_c, POLICY_HND *hnd);
-BOOL samr_io_q_delete_dom_alias(char *desc,  SAMR_Q_DELETE_DOM_ALIAS *q_u, 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);
-BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c,
-                               const POLICY_HND *hnd);
-BOOL samr_io_q_query_aliasmem(char *desc,  SAMR_Q_QUERY_ALIASMEM *q_u, 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);
-BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
-               POLICY_HND *pol, uint32 flags,
-               uint32 num_names, char **name);
+BOOL samr_io_r_lookup_ids(char *desc,  SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth);
 BOOL samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
-               uint32 num_rids, uint32 *rid, uint8 *type, uint32 status);
+void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+                       uint32 num_rids, uint32 *rid, uint8 *type, uint32 status);
 BOOL samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
-                               const POLICY_HND *pol,
+BOOL samr_io_q_unknown_12(char *desc,  SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth);
+void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+               uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
+               uint32 status);
+BOOL samr_io_r_unknown_12(char *desc,  SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth);
+void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+                               POLICY_HND *pol,
                                uint32 unk_0, uint32 rid);
 BOOL samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth);
 BOOL samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
-                               POLICY_HND *pol,
-                               const char *name,
-                               uint16 acb_info, uint32 unk_1);
-BOOL samr_io_q_create_user(char *desc,  SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_create_user(SAMR_R_CREATE_USER *r_u,
-                               POLICY_HND *user_pol,
-                               uint32 unk_0, uint32 user_rid,
-                               uint32 status);
-BOOL samr_io_r_create_user(char *desc,  SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+                               POLICY_HND *hnd);
+BOOL samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth);
+void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+               uint32 num_gids, DOM_GID *gid, uint32 status);
+BOOL samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
+void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
                                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);
-BOOL make_sam_user_info10(SAM_USER_INFO_10 *usr,
+void init_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);
-BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
+void init_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);
-BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
-       char newpass[516], uint16 passlen);
-BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
-
-       NTTIME *logon_time, /* all zeros */
-       NTTIME *logoff_time, /* all zeros */
-       NTTIME *kickoff_time, /* all zeros */
-       NTTIME *pass_last_set_time, /* all zeros */
-       NTTIME *pass_can_change_time, /* all zeros */
-       NTTIME *pass_must_change_time, /* all zeros */
-
-       UNISTR2 *user_name, /* NULL */
-       UNISTR2 *full_name,
-       UNISTR2 *home_dir,
-       UNISTR2 *dir_drive,
-       UNISTR2 *log_scr,
-       UNISTR2 *prof_path,
-       UNISTR2 *desc,
-       UNISTR2 *wkstas,
-       UNISTR2 *unk_str,
-       UNISTR2 *mung_dial,
-
-       uint32 user_rid, /* 0x0000 0000 */
-       uint32 group_rid,
-       uint16 acb_info, 
-
-       uint32 unknown_3,
-       uint16 logon_divs,
-       LOGON_HRS *hrs,
-       uint32 unknown_5,
-       char newpass[516],
-       uint32 unknown_6);
-BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
-
-       NTTIME *logon_time, /* all zeros */
-       NTTIME *logoff_time, /* all zeros */
-       NTTIME *kickoff_time, /* all zeros */
-       NTTIME *pass_last_set_time, /* all zeros */
-       NTTIME *pass_can_change_time, /* all zeros */
-       NTTIME *pass_must_change_time, /* all zeros */
-
-       char *user_name, /* NULL */
-       char *full_name,
-       char *home_dir,
-       char *dir_drive,
-       char *log_scr,
-       char *prof_path,
-       char *desc,
-       char *wkstas,
-       char *unk_str,
-       char *mung_dial,
-
-       uint32 user_rid, /* 0x0000 0000 */
-       uint32 group_rid,
-       uint16 acb_info, 
-
-       uint32 unknown_3,
-       uint16 logon_divs,
-       LOGON_HRS *hrs,
-       uint32 unknown_5,
-       char newpass[516],
-       uint32 unknown_6);
-BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
-
+void init_sam_user_info21(SAM_USER_INFO_21 *usr,
        NTTIME *logon_time,
        NTTIME *logoff_time,
        NTTIME *kickoff_time,
@@ -3288,12 +1986,12 @@ BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
        char *full_name,
        char *home_dir,
        char *dir_drive,
-       char *log_scr,
-       char *prof_path,
-       char *desc,
-       char *wkstas,
-       char *unk_str,
-       char *mung_dial,
+       char *logon_script,
+       char *profile_path,
+       char *description,
+       char *workstations,
+       char *unknown_str,
+       char *munged_dial,
 
        uint32 user_rid,
        uint32 group_rid,
@@ -3304,435 +2002,201 @@ BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
        LOGON_HRS *hrs,
        uint32 unknown_5,
        uint32 unknown_6);
-BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
                                uint16 switch_value, void *info, uint32 status);
 BOOL samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
-                               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);
-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);
-BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
-                               POLICY_HND *hnd,
-                               uint16 switch_value, void *info);
-BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, 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);
-BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
-                               const char *srv_name, uint32 unknown_0);
+BOOL samr_io_q_unknown_32(char *desc,  SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_unknown_32(char *desc,  SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth);
+void init_samr_q_connect(SAMR_Q_CONNECT *q_u,
+                               char *srv_name, uint32 unknown_0);
 BOOL samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
 BOOL samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u);
+void init_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);
 BOOL samr_io_r_connect_anon(char *desc,  SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
-BOOL make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
+void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
+                               uint32 unknown_0, uint32 rid);
+BOOL samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
+void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+               POLICY_HND *pol, uint32 rid,
+               uint32 num_gids, uint32 *gid);
+void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void init_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void init_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
 BOOL samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u);
+void init_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u);
 BOOL samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
-BOOL make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]);
+void init_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]);
 BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
-BOOL make_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16]);
+void init_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16]);
 BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
-BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
                                char *dest_host, char *user_name,
                                char nt_newpass[516], uchar nt_oldhash[16],
                                char lm_newpass[516], uchar lm_oldhash[16]);
 BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
-BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status);
+void init_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);
 
 /*The following definitions come from  rpc_parse/parse_sec.c  */
 
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
+void init_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,
+void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth);
+SEC_ACL *make_sec_acl(uint16 revision, int num_aces, SEC_ACE *ace_list);
+SEC_ACL *dup_sec_acl( SEC_ACL *src);
+void free_sec_acl(SEC_ACL **ppsa);
+BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth);
+SEC_DESC *make_sec_desc(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 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  */
-
-BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
-BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
-                                     prs_struct *ps, int depth);
-BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, 
-               const char *printername,
-               uint32 cbbuf, uint32 devmod, uint32 des_access,
-               const char *station,
-               const char *username);
-BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
-                               POLICY_HND *handle,
-                               char *valuename,
-                               uint32 size);
-BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd);
-BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u,
-                           prs_struct *ps, int depth);
-BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, 
-                           prs_struct *ps, int depth);
-BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
-                           prs_struct *ps, int depth);
-BOOL spoolss_io_r_rfnpcnex(char *desc, 
-                           SPOOL_R_RFNPCNEX *r_u, 
-                           prs_struct *ps, int depth);
-BOOL spoolss_io_free_buffer(BUFFER *buffer);
-BOOL spoolss_io_q_getprinterdriver2(char *desc, 
-                                   SPOOL_Q_GETPRINTERDRIVER2 *q_u,
-                                    prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
-                               prs_struct *ps, int depth);
-BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u,
-                               uint32 flags,
-                               const char* servername,
-                               uint32 level,
-                               uint32 size);
-BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
-                               prs_struct *ps, int depth);
-void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u);
-BOOL spoolss_io_r_enumprinters(char *desc,
-                               SPOOL_R_ENUMPRINTERS *r_u, 
-                               prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinter(char *desc,
-                               SPOOL_R_GETPRINTER *r_u, 
-                               prs_struct *ps, int depth);
-BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u,
-                               POLICY_HND *hnd,
-                               uint32 level,
-                               uint32 buf_size);
-BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
-                               prs_struct *ps, int depth);
-BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth);
-void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u);
-BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
-                               uint32 firstjob,
-                               uint32 numofjobs,
-                               uint32 level,
-                               uint32 buf_size);
-BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
-BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth);
-BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
-BOOL spool_io_user_level_1(char *desc, SPOOL_USER_LEVEL_1 **q_u, prs_struct *ps, int depth);
-BOOL spool_io_user_level(char *desc, SPOOL_USER_LEVEL *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth);
-BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
-                                          prs_struct *ps, int depth);
-BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar);
-BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
-BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
-                                NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc);
-BOOL uni_2_asc_printer_info_2(SPOOL_PRINTER_INFO_LEVEL_2 *uni,
-                              NT_PRINTER_INFO_LEVEL_2  **asc);
-BOOL convert_printer_info(SPOOL_PRINTER_INFO_LEVEL uni,
-                          NT_PRINTER_INFO_LEVEL *printer,
-                         uint32 level);
-BOOL convert_printer_driver_info(SPOOL_PRINTER_DRIVER_INFO_LEVEL uni,
-                                 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
-                                uint32 level);
-BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode);
-BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL convert_specific_param(NT_PRINTER_PARAM **param, UNISTR2 value , uint32 type, uint8 *data, uint32 len);
-BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
+                       SEC_ACL *sacl, SEC_ACL *dacl, size_t *sec_desc_size);
+SEC_DESC *dup_sec_desc( SEC_DESC *src);
+void free_sec_desc(SEC_DESC **ppsd);
+SEC_DESC *make_standard_sec_desc(DOM_SID *owner_sid, DOM_SID *grp_sid,
+                                SEC_ACL *dacl, size_t *sec_desc_size);
+BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
+SEC_DESC_BUF *make_sec_desc_buf(int len, SEC_DESC *sec_desc);
+SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src);
+void free_sec_desc_buf(SEC_DESC_BUF **ppsdb);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_parse/parse_srv.c  */
 
-BOOL make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
-BOOL make_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark);
-BOOL make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
+void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark);
+void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
                                char *net_name, char *remark,
-                               char *path, char *pass);
-BOOL make_srv_share_info2(SH_INFO_2 *sh2,
+                               char *path, char *passwd);
+void init_srv_share_info2(SH_INFO_2 *sh2,
                                char *net_name, uint32 type, char *remark,
                                uint32 perms, uint32 max_uses, uint32 num_uses,
-                               char *path, char *pass);
-BOOL make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, 
-                               const char *srv_name, 
-                               uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
-                               uint32 preferred_len,
-                               ENUM_HND *hnd);
-BOOL srv_io_q_net_share_enum(char *desc,  SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_share_enum(char *desc,  SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
-BOOL make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
-BOOL make_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
-BOOL make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
-BOOL make_srv_sess_info1(SESS_INFO_1 *ss1, 
+                               char *path, char *passwd);
+void free_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr);
+void free_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n);
+void free_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n);
+void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, 
+                               char *srv_name, uint32 info_level,
+                               uint32 preferred_len, ENUM_HND *hnd);
+BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
+void free_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n);
+void free_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n);
+BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_struct *ps, int depth);
+void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
+void init_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
+void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
+void init_srv_sess_info1(SESS_INFO_1 *ss1, 
                                char *name, char *user,
                                uint32 num_opens, uint32 open_time, uint32 idle_time,
                                uint32 user_flags);
-BOOL make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
-                               char *user_name,
+void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
                                uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-BOOL srv_io_q_net_sess_enum(char *desc,  SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_sess_enum(char *desc,  SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth);
-BOOL make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
-BOOL make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
-BOOL make_srv_conn_info1(CONN_INFO_1 *ss1, 
+BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth);
+void init_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
+void init_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
+void init_srv_conn_info1(CONN_INFO_1 *ss1, 
                                uint32 id, uint32 type,
                                uint32 num_opens, uint32 num_users, uint32 open_time,
                                char *usr_name, char *net_name);
-BOOL make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
+void init_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
                                uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-BOOL srv_io_q_net_conn_enum(char *desc,  SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
 BOOL srv_io_r_net_conn_enum(char *desc,  SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth);
-BOOL make_srv_tprt_info0_str(TPRT_INFO_0_STR *tp0,
-                               char *trans_name,
-                               char *trans_addr, uint32 trans_addr_len,
-                               char *addr_name);
-BOOL make_srv_tprt_info0(TPRT_INFO_0 *tp0, 
-                               uint32 num_vcs, uint32 trans_addr_len,
-                               char *trans_name, char *trans_addr,
-                               char *addr_name);
-void free_srv_tprt_info_0(SRV_TPRT_INFO_0 *tp0);
-void free_srv_tprt_ctr(SRV_TPRT_INFO_CTR *ctr);
-BOOL make_srv_q_net_tprt_enum(SRV_Q_NET_TPRT_ENUM *q_n, 
-                               const char *srv_name, 
-                               uint32 tprt_level, SRV_TPRT_INFO_CTR *ctr,
-                               uint32 preferred_len,
-                               ENUM_HND *hnd);
-BOOL srv_io_q_net_tprt_enum(char *desc,  SRV_Q_NET_TPRT_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_tprt_enum(char *desc,  SRV_R_NET_TPRT_ENUM *r_n, prs_struct *ps, int depth);
-BOOL make_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name);
-BOOL make_srv_file_info3(FILE_INFO_3 *fl3,
+void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name);
+void init_srv_file_info3(FILE_INFO_3 *fl3,
                                uint32 id, uint32 perms, uint32 num_locks,
                                char *path_name, char *user_name);
-BOOL make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
-                               uint32 file_id,
+void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
                                uint32 file_level, SRV_FILE_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd);
-BOOL srv_io_q_net_file_enum(char *desc,  SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_file_enum(char *desc,  SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
-BOOL make_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
+BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
+void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
                                uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, char *comment);
-BOOL make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
+void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
                                char *comment, uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
                                uint32 announce, uint32 ann_delta, uint32 licenses,
                                char *usr_path);
-BOOL make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
                                char *server_name, uint32 switch_value);
-BOOL srv_io_q_net_srv_get_info(char *desc,  SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
-BOOL make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
+void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
                                uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
-BOOL srv_io_r_net_srv_get_info(char *desc,  SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
-BOOL make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name);
-BOOL srv_io_q_net_remote_tod(char *desc,  SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth);
-BOOL make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
+BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
+BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth);
+void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
                            uint32 hours, uint32 mins, uint32 secs, uint32 hunds,
                           uint32 zone, uint32 tintervals, uint32 day,
                           uint32 month, uint32 year, uint32 weekday);
 BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth);
 
-/*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 make_svc_r_open_sc_man(SVC_R_OPEN_SC_MAN *r_u, POLICY_HND *hnd,
-                               uint32 status)  ;
-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 make_svc_r_open_service(SVC_R_OPEN_SERVICE *r_u, POLICY_HND *hnd,
-                               uint32 status)  ;
-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, uint32 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 make_svc_r_query_disp_name(SVC_R_QUERY_DISP_NAME *r_d, 
-                               char *disp_name, uint32 status);
-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);
-
 /*The following definitions come from  rpc_parse/parse_wks.c  */
 
-BOOL make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
                                char *server, uint16 switch_value)  ;
 BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
-BOOL make_wks_info_100(WKS_INFO_100 *inf,
+void init_wks_info_100(WKS_INFO_100 *inf,
                                uint32 platform_id, uint32 ver_major, uint32 ver_minor,
                                char *my_name, char *domain_name);
-BOOL make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
                                uint32 switch_value, WKS_INFO_100 *wks100,
                                int status)  ;
-BOOL wks_io_r_query_info(char *desc,  WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
-
-/*The following definitions come from  rpc_server/srv_brs.c  */
-
-BOOL api_brs_rpc(rpcsrv_struct *p, prs_struct *data);
-
-/*The following definitions come from  rpc_server/srv_lookup.c  */
-
-int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids);
-int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid);
-uint32 lookup_builtin_sid(DOM_SID *sid, char *name, uint8 *type);
-uint32 lookup_added_sid(DOM_SID *sid, char *name, uint8 *type);
-uint32 lookup_sid(DOM_SID *sid, char *name, uint8 *type);
-uint32 lookup_wk_group_sid(DOM_SID *sid, char *group_name, uint8 *type);
-uint32 lookup_group_sid(DOM_SID *sid, char *group_name, uint8 *type);
-uint32 lookup_wk_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type);
-uint32 lookup_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type);
-uint32 lookup_wk_user_sid(DOM_SID *sid, char *user_name, uint8 *type);
-uint32 lookup_user_sid(DOM_SID *sid, char *user_name, uint8 *type);
-uint32 lookup_added_group_name(const char *grp_name, const char *domain,
-                               DOM_SID *sid, uint8 *type);
-uint32 lookup_added_alias_name(const char *als_name, const char *domain,
-                               DOM_SID *sid, uint8 *type);
-uint32 lookup_added_user_rids(char *nt_name,
-               uint32 *usr_rid, uint32 *grp_rid);
-uint32 lookup_name(char *name, DOM_SID *sid, uint8 *type);
+BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
 
 /*The following definitions come from  rpc_server/srv_lsa.c  */
 
-BOOL api_ntlsa_rpc(rpcsrv_struct *p, prs_struct *data);
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from  rpc_server/srv_lsa_hnd.c  */
+
+void init_lsa_policy_hnd(void);
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd);
+int find_lsa_policy_by_hnd(POLICY_HND *hnd);
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid);
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status);
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
+BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd);
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name);
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_server/srv_netlog.c  */
 
-BOOL api_netlog_rpc(rpcsrv_struct *p, prs_struct *data);
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_server/srv_pipe.c  */
 
-void rpcsrv_free_temp(rpcsrv_struct *l);
-BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start);
-void close_msrpc_command_processor(void);
-void add_msrpc_command_processor(char* pipe_name,
-                               char* process_name,
-                               BOOL (*fn) (rpcsrv_struct *, prs_struct *));
-BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len);
-BOOL rpc_send_and_rcv_pdu(pipes_struct *p);
-BOOL rpc_to_smb(pipes_struct *p, char *data, int len);
-BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
-                               prs_struct *data);
-BOOL is_complete_pdu(prs_struct *ps);
+BOOL create_next_pdu(pipes_struct *p);
+BOOL rpc_command(pipes_struct *p, char *input_data, int data_len);
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+                               prs_struct *rpc_in);
 
 /*The following definitions come from  rpc_server/srv_pipe_hnd.c  */
 
 void set_pipe_handle_offset(int max_open_files);
 void reset_chain_p(void);
 void init_rpc_pipe_hnd(void);
+BOOL pipe_init_outgoing_data( pipes_struct *p);
 pipes_struct *open_rpc_pipe_p(char *pipe_name, 
                              connection_struct *conn, uint16 vuid);
-ssize_t write_pipe(pipes_struct *p, char *data, size_t n);
-int read_pipe(pipes_struct *p, char *data, uint32 pos, int n);
+ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n);
+int read_from_pipe(pipes_struct *p, char *data, int n);
 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority);
 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state);
 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn);
@@ -3741,351 +2205,142 @@ pipes_struct *get_rpc_pipe(int pnum);
 
 /*The following definitions come from  rpc_server/srv_reg.c  */
 
-BOOL api_reg_rpc(rpcsrv_struct *p, prs_struct *data);
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_server/srv_samr.c  */
 
-BOOL api_samr_rpc(rpcsrv_struct *p, prs_struct *data);
-
-/*The following definitions come from  rpc_server/srv_spoolss.c  */
-
-void init_printer_hnd(void);
-uint32 size_of_notify_info_data(uint16 type, uint16 field);
-BOOL type_of_notify_info_data(uint16 type, uint16 field);
-BOOL api_spoolss_rpc(rpcsrv_struct *p, prs_struct *data);
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_server/srv_srvsvc.c  */
 
-BOOL api_srvsvc_rpc(rpcsrv_struct *p, prs_struct *data);
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
 
-/*The following definitions come from  rpc_server/srv_svcctl.c  */
+/*The following definitions come from  rpc_server/srv_util.c  */
 
-BOOL api_svcctl_rpc(rpcsrv_struct *p, prs_struct *data);
+int make_dom_gids(char *gids_str, DOM_GID **ppgids);
+void get_domain_user_groups(char *domain_groups, char *user);
+uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type);
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
+uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type);
+uint32 lookup_group_rid(char *group_name, uint32 *rid);
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid);
+uint32 lookup_user_rid(char *user_name, uint32 *rid);
 
 /*The following definitions come from  rpc_server/srv_wkssvc.c  */
 
-BOOL api_wkssvc_rpc(rpcsrv_struct *p, prs_struct *data);
-
-/*The following definitions come from  rpcclient/cmd_atsvc.c  */
-
-void cmd_at(struct client_info *info, int argc, char *argv[]);
-
-/*The following definitions come from  rpcclient/cmd_brs.c  */
-
-void cmd_brs_query_info(struct client_info *info, int argc, char *argv[]);
-
-/*The following definitions come from  rpcclient/cmd_eventlog.c  */
-
-void cmd_eventlog(struct client_info *info, int argc, char *argv[]);
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpcclient/cmd_lsarpc.c  */
 
-void cmd_lsa_enum_trust_dom(struct client_info *info, int argc, char *argv[]);
-void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[]);
-void cmd_lsa_lookup_names(struct client_info *info, int argc, char *argv[]);
-void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[]);
-void cmd_lsa_query_secret(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_query_info(struct client_info *info);
+void cmd_lsa_lookup_sids(struct client_info *info);
 
 /*The following definitions come from  rpcclient/cmd_netlogon.c  */
 
-void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]);
-void cmd_netlogon_domain_test(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_sync(struct client_info *info, int argc, char *argv[]);
+void cmd_netlogon_login_test(struct client_info *info);
 
 /*The following definitions come from  rpcclient/cmd_reg.c  */
 
-void split_server_keyname(char *srv_name, char *key, const char* arg);
-BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
-                               REG_FN(reg_fn),
-                               REG_KEY_FN(reg_key_fn),
-                               REG_VAL_FN(reg_val_fn));
-void cmd_reg_enum(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_query_info(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_query_key(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_create_val(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_delete_val(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_delete_key(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_create_key(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[]);
-void cmd_reg_shutdown(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_enum(struct client_info *info);
+void cmd_reg_query_key(struct client_info *info);
+void cmd_reg_create_val(struct client_info *info);
+void cmd_reg_delete_val(struct client_info *info);
+void cmd_reg_delete_key(struct client_info *info);
+void cmd_reg_create_key(struct client_info *info);
+void cmd_reg_test_key_sec(struct client_info *info);
+void cmd_reg_get_key_sec(struct client_info *info);
 
 /*The following definitions come from  rpcclient/cmd_samr.c  */
 
-void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_test(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_lookup_domain(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_del_aliasmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_delete_dom_alias(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_add_aliasmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_create_dom_trusting(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_create_dom_user(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_create_dom_alias(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_del_groupmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_delete_dom_group(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_add_groupmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_create_dom_group(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_enum_users(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_groupmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_group(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_user(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_set_userinfo2(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_set_userinfo(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_dispinfo(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_dominfo(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_aliasmem(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_query_alias(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_enum_aliases(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_enum_groups(struct client_info *info, int argc, char *argv[]);
-void cmd_sam_enum_domains(struct client_info *info, int argc, char *argv[]);
-
-/*The following definitions come from  rpcclient/cmd_spoolss.c  */
-
-BOOL msrpc_spoolss_enum_printers( const char* srv_name,
-                               uint32 level,
-                               uint32 *num,
-                               void ***ctr,
-                               PRINT_INFO_FN(fn));
-void cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[]);
-void cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[]);
-BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
-                               const char* station, const char* user_name, 
-                               uint32 level,
-                               uint32 *num,
-                               void ***ctr,
-                               JOB_INFO_FN(fn));
-void cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_ntchange_pwd(struct client_info *info);
+void cmd_sam_test(struct client_info *info);
+void cmd_sam_enum_users(struct client_info *info);
+void cmd_sam_query_user(struct client_info *info);
+void cmd_sam_query_groups(struct client_info *info);
+void cmd_sam_enum_aliases(struct client_info *info);
 
 /*The following definitions come from  rpcclient/cmd_srvsvc.c  */
 
-BOOL net_srv_get_info(struct client_info *info,
-               uint32 info_level,
-               SRV_INFO_CTR *ctr);
-void cmd_srv_query_info(struct client_info *info, int argc, char *argv[]);
-BOOL msrpc_srv_enum_tprt( const char* dest_srv,
-                               uint32 info_level,
-                               SRV_TPRT_INFO_CTR *ctr,
-                               TPRT_INFO_FN(tprt_fn));
-void cmd_srv_enum_tprt(struct client_info *info, int argc, char *argv[]);
-void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[]);
-void cmd_srv_enum_shares(struct client_info *info, int argc, char *argv[]);
-void cmd_srv_enum_sess(struct client_info *info, int argc, char *argv[]);
-void cmd_srv_enum_files(struct client_info *info, int argc, char *argv[]);
-void cmd_time(struct client_info *info, int argc, char *argv[]);
-
-/*The following definitions come from  rpcclient/cmd_svcctl.c  */
-
-void svc_display_query_svc_cfg(const QUERY_SERVICE_CONFIG *cfg);
-BOOL svc_query_service( POLICY_HND *pol_scm,
-                               const char *svc_name,
-                               SVC_QUERY_FN(svc_query_fn));
-void cmd_svc_info(struct client_info *info, int argc, char *argv[]);
-BOOL msrpc_svc_enum(const char* srv_name,
-                               ENUM_SRVC_STATUS **svcs,
-                               uint32 *num_svcs,
-                               SVC_INFO_FN(info_fn),
-                               SVC_QUERY_FN(query_fn));
-void cmd_svc_enum(struct client_info *info, int argc, char *argv[]);
-void cmd_svc_stop(struct client_info *info, int argc, char *argv[]);
-void cmd_svc_start(struct client_info *info, int argc, char *argv[]);
-void cmd_svc_set(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_query_info(struct client_info *info);
+void cmd_srv_enum_conn(struct client_info *info);
+void cmd_srv_enum_shares(struct client_info *info);
+void cmd_srv_enum_sess(struct client_info *info);
+void cmd_srv_enum_files(struct client_info *info);
 
 /*The following definitions come from  rpcclient/cmd_wkssvc.c  */
 
-void cmd_wks_query_info(struct client_info *info, int argc, char *argv[]);
+void cmd_wks_query_info(struct client_info *info);
 
-/*The following definitions come from  rpcclient/display_at.c  */
+/*The following definitions come from  rpcclient/display.c  */
 
-void display_at_enum_info(FILE *out_hnd, enum action_type action, 
-                               uint32 num_jobs, const AT_ENUM_INFO *const jobs,
-                               char *const *const commands);
-void display_at_job_info(FILE *out_hnd, enum action_type action, 
-                    AT_JOB_INFO *const job, fstring command);
-
-/*The following definitions come from  rpcclient/display_event.c  */
-
-void display_eventlog_eventrecord(FILE *out_hnd, enum action_type action, EVENTLOGRECORD *const ev);
-
-/*The following definitions come from  rpcclient/display_reg.c  */
-
-char *get_reg_val_type_str(uint32 type);
-void display_reg_value_info(FILE *out_hnd, enum action_type action, 
-                               const char *val_name, 
-                               uint32 val_type, const BUFFER2 *value);
-void display_reg_key_info(FILE *out_hnd, enum action_type action, 
-                               const char *key_name, time_t key_mod_time);
-
-/*The following definitions come from  rpcclient/display_sam.c  */
-
-void display_alias_members(FILE *out_hnd, enum action_type action, 
-                               uint32 num_mem, char *const *const sid_mem, 
-                               uint8 *const type);
-void display_alias_rid_info(FILE *out_hnd, enum action_type action, 
-                               DOM_SID *const sid, 
-                               uint32 num_rids, uint32 *const rid);
-void display_group_members(FILE *out_hnd, enum action_type action, 
-                               uint32 num_mem, char *const *const name, uint32 *const type);
-void display_group_info1(FILE *out_hnd, enum action_type action, GROUP_INFO1 *const info1);
-void display_group_info4(FILE *out_hnd, enum action_type action, GROUP_INFO4 *const info4);
-void display_group_info_ctr(FILE *out_hnd, enum action_type action, 
-                               GROUP_INFO_CTR *const ctr);
-void display_group_rid_info(FILE *out_hnd, enum action_type action, 
-                               uint32 num_gids, DOM_GID *const gid);
-void display_alias_name_info(FILE *out_hnd, enum action_type action, 
-                               uint32 num_aliases, fstring *const alias_name, const uint32 *const num_als_usrs);
-void display_alias_info3(FILE *out_hnd, enum action_type action, ALIAS_INFO3 *const info3);
-void display_alias_info_ctr(FILE *out_hnd, enum action_type action, 
-                               ALIAS_INFO_CTR *const ctr);
-void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *const usr);
-void display_sam_unk_info_2(FILE *out_hnd, enum action_type action, 
-                               SAM_UNK_INFO_2 *const info2);
-void display_sam_unk_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 switch_value, SAM_UNK_CTR *const ctr);
-void display_sam_info_1(FILE *out_hnd, enum action_type action, 
-               SAM_ENTRY1 *const e1, SAM_STR1 *const s1);
-void display_sam_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 count, SAM_DISPINFO_1 *const ctr);
-void display_sam_disp_info_ctr(FILE *out_hnd, enum action_type action, 
-                               uint16 level, uint32 count,
-                               SAM_DISPINFO_CTR *const ctr);
-
-/*The following definitions come from  rpcclient/display_sec.c  */
-
-char *get_sec_mask_str(uint32 type);
-void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *const info);
-void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *const ace);
-void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *const sec_acl);
-void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *const sec);
-
-/*The following definitions come from  rpcclient/display_spool.c  */
-
-void display_print_info_0(FILE *out_hnd, enum action_type action, 
-               PRINTER_INFO_0 *const i0);
-void display_print_info_1(FILE *out_hnd, enum action_type action, 
-               PRINTER_INFO_1 *const i1);
-void display_printer_info_0_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 count, PRINTER_INFO_0 *const *const ctr);
-void display_printer_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 count, PRINTER_INFO_1 *const *const ctr);
-void display_printer_info_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 level, uint32 count,
-                               void *const *const ctr);
-void display_job_info_2(FILE *out_hnd, enum action_type action, 
-               JOB_INFO_2 *const i2);
-void display_job_info_1(FILE *out_hnd, enum action_type action, 
-               JOB_INFO_1 *const i1);
-void display_job_info_2_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 count, JOB_INFO_2 *const *const ctr);
-void display_job_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 count, JOB_INFO_1 *const *const ctr);
-void display_job_info_ctr(FILE *out_hnd, enum action_type action, 
-                               uint32 level, uint32 count,
-                               void *const *const ctr);
-
-/*The following definitions come from  rpcclient/display_srv.c  */
-
-char *get_sid_name_use_str(uint8 sid_name_use);
 char *get_file_mode_str(uint32 share_mode);
 char *get_file_oplock_str(uint32 op_type);
 char *get_share_type_str(uint32 type);
 char *get_server_type_str(uint32 type);
-void display_srv_info_101(FILE *out_hnd, enum action_type action, 
-               SRV_INFO_101 *const sv101);
-void display_srv_info_102(FILE *out_hnd, enum action_type action, SRV_INFO_102 *const sv102);
-void display_srv_info_ctr(FILE *out_hnd, enum action_type action, SRV_INFO_CTR *const ctr);
-void display_conn_info_0(FILE *out_hnd, enum action_type action, 
-               CONN_INFO_0 *const info0);
-void display_conn_info_1(FILE *out_hnd, enum action_type action, 
-               CONN_INFO_1 *const info1, CONN_INFO_1_STR *const str1);
-void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_CONN_INFO_0 *const ctr);
-void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_CONN_INFO_1 *const ctr);
-void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_CONN_INFO_CTR *const ctr);
-void display_tprt_info_0(FILE *out_hnd, enum action_type action, 
-               TPRT_INFO_0 *const info0, TPRT_INFO_0_STR *const str0);
-void display_srv_tprt_info_0_ctr(FILE *out_hnd, enum action_type action, 
-                               const SRV_TPRT_INFO_0 *const ctr);
-void display_srv_tprt_info_ctr(FILE *out_hnd, enum action_type action, 
-                               const SRV_TPRT_INFO_CTR *const ctr);
-void display_share_info_1(FILE *out_hnd, enum action_type action, 
-               SH_INFO_1 *const info1, SH_INFO_1_STR *const str1);
-void display_share_info_2(FILE *out_hnd, enum action_type action, 
-               SH_INFO_2 *const info2, SH_INFO_2_STR *const str2);
-void display_srv_share_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SHARE_INFO_1 *const ctr);
-void display_srv_share_info_2_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SHARE_INFO_2 *const ctr);
-void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SHARE_INFO_CTR *const ctr);
-void display_file_info_3(FILE *out_hnd, enum action_type action, 
-               FILE_INFO_3 *const info3, FILE_INFO_3_STR *const str3);
-void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_FILE_INFO_3 *const ctr);
-void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_FILE_INFO_CTR *const ctr);
-void display_sess_info_0(FILE *out_hnd, enum action_type action, 
-               SESS_INFO_0 *const info0, SESS_INFO_0_STR *const str0);
-void display_sess_info_1(FILE *out_hnd, enum action_type action, 
-               SESS_INFO_1 *const info1, SESS_INFO_1_STR *const str1);
-void display_srv_sess_info_0_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SESS_INFO_0 *const ctr);
-void display_srv_sess_info_1_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SESS_INFO_1 *const ctr);
-void display_srv_sess_info_ctr(FILE *out_hnd, enum action_type action, 
-                               SRV_SESS_INFO_CTR *const ctr);
-void display_server(FILE *out_hnd, enum action_type action, 
-                               char *const sname, uint32 type, char *const comment);
-void display_share(FILE *out_hnd, enum action_type action, 
-                               char *const sname, uint32 type, char *const comment);
-void display_share2(FILE *out_hnd, enum action_type action, 
-                               char *const sname, uint32 type, char *const comment, 
-                               uint32 perms, uint32 max_uses, uint32 num_uses, 
-                               char *const path, char *const password);
-void display_name(FILE *out_hnd, enum action_type action, 
-                               char *const sname);
-
-/*The following definitions come from  rpcclient/display_svc.c  */
-
-char *get_svc_start_type_str(uint32 type);
-void display_query_svc_cfg(FILE *out_hnd, enum action_type action, 
-                               const QUERY_SERVICE_CONFIG *const cfg);
-void display_svc_info(FILE *out_hnd, enum action_type action,
-                               const ENUM_SRVC_STATUS *const svc);
-
-/*The following definitions come from  rpcclient/display_sync.c  */
-
-void display_sam_sync_ctr(FILE *out_hnd, enum action_type action, 
-                               SAM_DELTA_HDR *const delta, 
-                               SAM_DELTA_CTR *const ctr);
-void display_sam_sync(FILE *out_hnd, enum action_type action, 
-                               SAM_DELTA_HDR *const deltas, 
-                               SAM_DELTA_CTR *const ctr, 
-                               uint32 num);
+void display_srv_info_101(FILE *out_hnd, enum action_type action,
+               SRV_INFO_101 *sv101);
+void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102);
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr);
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+               CONN_INFO_0 *info0);
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+               CONN_INFO_1 *info1, CONN_INFO_1_STR *str1);
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_CONN_INFO_0 *ctr);
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_CONN_INFO_1 *ctr);
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_CONN_INFO_CTR *ctr);
+void display_share_info_1(FILE *out_hnd, enum action_type action,
+                         SRV_SHARE_INFO_1 *info1);
+void display_share_info_2(FILE *out_hnd, enum action_type action,
+                         SRV_SHARE_INFO_2 *info2);
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_SHARE_INFO_CTR *ctr);
+void display_file_info_3(FILE *out_hnd, enum action_type action,
+               FILE_INFO_3 *info3, FILE_INFO_3_STR *str3);
+void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_FILE_INFO_3 *ctr);
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+                               SRV_FILE_INFO_CTR *ctr);
+void display_server(FILE *out_hnd, enum action_type action,
+                               char *sname, uint32 type, char *comment);
+void display_share(FILE *out_hnd, enum action_type action,
+                               char *sname, uint32 type, char *comment);
+void display_share2(FILE *out_hnd, enum action_type action,
+                               char *sname, uint32 type, char *comment,
+                               uint32 perms, uint32 max_uses, uint32 num_uses,
+                               char *path, char *passwd);
+void display_name(FILE *out_hnd, enum action_type action,
+                               char *sname);
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+                               uint32 num_gids, DOM_GID *gid);
+void display_alias_name_info(FILE *out_hnd, enum action_type action,
+                               uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs);
+void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr);
+char *get_sec_mask_str(uint32 type);
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info);
+void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace);
+void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl);
+void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec);
+char *get_reg_val_type_str(uint32 type);
+void display_reg_value_info(FILE *out_hnd, enum action_type action,
+                               char *val_name, uint32 val_type, BUFFER2 *value);
+void display_reg_key_info(FILE *out_hnd, enum action_type action,
+                               char *key_name, time_t key_mod_time);
 
 /*The following definitions come from  rpcclient/rpcclient.c  */
 
-void readline_init(void);
-
-/*The following definitions come from  samrd/samrd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
+void rpcclient_init(void);
 
 /*The following definitions come from  smbd/blocking.c  */
 
 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  */
-
-void generate_next_challenge(char *challenge);
-BOOL set_challenge(unsigned char *challenge);
-BOOL last_challenge(unsigned char *challenge);
-
 /*The following definitions come from  smbd/chgpasswd.c  */
 
 BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
@@ -4105,8 +2360,7 @@ BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL overri
 
 /*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  */
 
@@ -4126,13 +2380,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  */
 
@@ -4142,11 +2391,11 @@ 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);
@@ -4180,19 +2429,19 @@ 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 file_size);
+ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
+void sync_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);
 
 /*The following definitions come from  smbd/files.c  */
@@ -4226,7 +2475,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  */
 
@@ -4252,6 +2501,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,
@@ -4259,30 +2509,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(file_fd_struct *fd_ptr, 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);
@@ -4290,9 +2546,22 @@ void check_kernel_oplocks(void);
 
 /*The following definitions come from  smbd/password.c  */
 
+void generate_next_challenge(char *challenge);
+BOOL set_challenge(unsigned char *challenge);
+user_struct *get_valid_user_struct(uint16 vuid);
+void invalidate_vuid(uint16 vuid);
+char *validated_username(uint16 vuid);
+int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
+uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest);
 void add_session_user(char *user);
-BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
-               uchar user_sess_key[16]);
+BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
+BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
+                     uchar lm_pass[24], uchar nt_pass[24]);
+BOOL pass_check_smb(char *user, char *domain,
+               uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
+               struct passwd *pwd);
+BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd);
+BOOL user_ok(char *user,int snum);
 BOOL authorise_login(int snum,char *user,char *password, int pwlen, 
                     BOOL *guest,BOOL *force,uint16 vuid);
 BOOL check_hosts_equiv(char *user);
@@ -4301,30 +2570,36 @@ struct cli_state *server_cryptkey(void);
 BOOL server_validate(char *user, char *domain, 
                     char *pass, int passlen,
                     char *ntpass, int ntpasslen);
+BOOL domain_client_validate( char *user, char *domain, 
+                             char *smb_apasswd, int smb_apasslen, 
+                             char *smb_ntpasswd, int smb_ntpasslen,
+                             BOOL *user_exists);
 
 /*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(char *inbuf,char *outbuf,int length,int dum_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  */
 
-ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num);
-void do_read_prediction(connection_struct *conn);
+ssize_t read_predict(int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num);
+void do_read_prediction(void);
 void invalidate_read_prediction(int fd);
 
 /*The following definitions come from  smbd/process.c  */
 
 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  */
@@ -4351,23 +2626,23 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
 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 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 reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, 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 reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, 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,
@@ -4380,6 +2655,7 @@ int reply_printqueue(connection_struct *conn,
                     char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
 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, 
                     char *inbuf, char *outbuf, char *name, 
@@ -4387,12 +2663,14 @@ int rename_internals(connection_struct *conn,
 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
 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 reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, 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 reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
 
 /*The following definitions come from  smbd/server.c  */
 
@@ -4431,53 +2709,13 @@ int reply_trans2(connection_struct *conn,
 
 void init_uid(void);
 BOOL become_guest(void);
-BOOL become_vuser(uint16 vuid);
-BOOL unbecome_vuser(void);
 BOOL become_user(connection_struct *conn, uint16 vuid);
 BOOL unbecome_user(void );
+BOOL become_authenticated_pipe_user(pipes_struct *p);
+BOOL unbecome_authenticated_pipe_user(pipes_struct *p);
 void become_root(BOOL save_dir) ;
 void unbecome_root(BOOL restore_dir);
 
-/*The following definitions come from  smbd/vfs-wrap.c  */
-
-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 *dfree, SMB_BIG_UINT *dsize);
-DIR *vfswrap_opendir(char *fname);
-struct dirent *vfswrap_readdir(DIR *dirp);
-int vfswrap_mkdir(char *path, mode_t mode);
-int vfswrap_rmdir(char *path);
-int vfswrap_closedir(DIR *dirp);
-int vfswrap_open(char *fname, int flags, mode_t mode);
-int vfswrap_close(int fd);
-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);
-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);
-
-/*The following definitions come from  smbd/vfs.c  */
-
-int vfs_init_default(connection_struct *conn);
-BOOL vfs_init_custom(connection_struct *conn);
-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, 
-                           int out_fd, files_struct *out_fsp,
-                           SMB_OFF_T n, char *header, int headlen, int align);
-char *vfs_readdirname(connection_struct *conn, void *p);
-
 /*The following definitions come from  smbwrapper/realcalls.c  */
 
 int real_utime(const char *name, struct utimbuf *buf);
@@ -4555,24 +2793,22 @@ int smbw_stat_printjob(struct smbw_server *srv,char *path,
 int smbw_fstat(int fd, struct stat *st);
 int smbw_stat(const char *fname, struct stat *st);
 
-/*The following definitions come from  spoolssd/spoolssd.c  */
+/*The following definitions come from  utils/nbio.c  */
 
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
-/*The following definitions come from  srvsvcd/srvsvcd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
-/*The following definitions come from  svcctld/svcctld.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
+void nb_setup(struct cli_state *cli);
+void nb_unlink(char *fname);
+void nb_open(char *fname, int handle, int size);
+void nb_write(int handle, int size, int offset);
+void nb_read(int handle, int size, int offset);
+void nb_close(int handle);
+void nb_mkdir(char *fname);
+void nb_rmdir(char *fname);
+void nb_rename(char *old, char *new);
+void nb_stat(char *fname, int size);
+void nb_create(char *fname, int size);
 
-/*The following definitions come from  utils/smbpasswd.c  */
+/*The following definitions come from  utils/torture.c  */
 
-int main(int argc, char **argv);
 
 /*The following definitions come from  web/cgi.c  */
 
@@ -4606,14 +2842,4 @@ void status_page(void);
 
 /*The following definitions come from  web/swat.c  */
 
-
-/*The following definitions come from  winregd/winregd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
-
-/*The following definitions come from  wkssvcd/wkssvcd.c  */
-
-void msrpc_service_init(void);
-BOOL reload_services(BOOL test);
 #endif /* _PROTO_H_ */
index 52544ac64222afd0578dec216c02d0be66c36047..9ffcf50337d0df45fa5d199d47189d76a9911c7d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "rpc_misc.h" /* this only pulls in STRHDR */
 
+
 /* DCE/RPC packet types */
 
 enum RPC_PKT_TYPE
@@ -35,15 +36,13 @@ enum RPC_PKT_TYPE
        RPC_FAULT    = 0x03,
        RPC_BIND     = 0x0B,
        RPC_BINDACK  = 0x0C,
-       RPC_ALTCONT     = 0x0E,
-       RPC_ALTCONTRESP = 0x0F,
+       RPC_BINDNACK = 0x0D,
        RPC_BINDRESP = 0x10 /* not the real name!  this is undocumented! */
 };
 
 /* DCE/RPC flags */
 #define RPC_FLG_FIRST 0x01
 #define RPC_FLG_LAST  0x02
-#define RPC_FLG_NOCALL 0x20
 
 /* NTLMSSP message types */
 enum NTLM_MESSAGE_TYPE
@@ -61,9 +60,7 @@ enum NTLM_MESSAGE_TYPE
 #define NTLMSSP_NEGOTIATE_SIGN             0x00000010
 #define NTLMSSP_NEGOTIATE_SEAL             0x00000020
 #define NTLMSSP_NEGOTIATE_LM_KEY           0x00000080
-#define NTLMSSP_NEGOTIATE_00000100         0x00000100
 #define NTLMSSP_NEGOTIATE_NTLM             0x00000200
-#define NTLMSSP_NEGOTIATE_00000400         0x00000400
 #define NTLMSSP_NEGOTIATE_00001000         0x00001000
 #define NTLMSSP_NEGOTIATE_00002000         0x00002000
 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN      0x00008000
@@ -72,18 +69,42 @@ enum NTLM_MESSAGE_TYPE
 #define NTLMSSP_NEGOTIATE_128              0x20000000
 #define NTLMSSP_NEGOTIATE_KEY_EXCH         0x40000000
 
+#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1
+
 /* NTLMSSP signature version */
 #define NTLMSSP_SIGN_VERSION 0x01
 
+/* NTLMSSP auth type and level. */
+#define NTLMSSP_AUTH_TYPE 0xa
+#define NTLMSSP_AUTH_LEVEL 0x6
+
+/* Maximum PDU fragment size. */
+#define MAX_PDU_FRAG_LEN 0x1630
+
+/*
+ * Actual structure of a DCE UUID
+ */
+
+typedef struct rpc_uuid
+{
+  uint32 time_low;
+  uint16 time_mid;
+  uint16 time_hi_and_version;
+  uint8 remaining[8];
+} RPC_UUID;
+
+#define RPC_UUID_LEN 16
 
 /* RPC_IFACE */
 typedef struct rpc_iface_info
 {
-  uint8 data[16];    /* 16 bytes of rpc interface identification */
+  RPC_UUID uuid;    /* 16 bytes of rpc interface identification */
   uint32 version;    /* the interface version number */
 
 } RPC_IFACE;
 
+#define RPC_IFACE_LEN (RPC_UUID_LEN + 4)
+
 struct pipe_id_info
 {
        /* the names appear not to matter: the syntaxes _do_ matter */
@@ -102,13 +123,15 @@ typedef struct rpc_hdr_info
   uint8  minor; /* 0 - RPC minor version */
   uint8  pkt_type; /* RPC_PKT_TYPE - RPC response packet */
   uint8  flags; /* DCE/RPC flags */
-  uint32 pack_type; /* 0x1000 0000 - packed data representation */
+  uint8  pack_type[4]; /* 0x1000 0000 - little-endian packed data representation */
   uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
   uint16 auth_len; /* 0 - authentication length  */
   uint32 call_id; /* call identifier.  matches 12th uint32 of incoming RPC data. */
 
 } RPC_HDR;
 
+#define RPC_HEADER_LEN 16
+
 /* RPC_HDR_REQ - ms request rpc header */
 typedef struct rpc_hdr_req_info
 {
@@ -118,6 +141,8 @@ typedef struct rpc_hdr_req_info
 
 } RPC_HDR_REQ;
 
+#define RPC_HDR_REQ_LEN 8
+
 /* RPC_HDR_RESP - ms response rpc header */
 typedef struct rpc_hdr_resp_info
 {
@@ -128,13 +153,7 @@ typedef struct rpc_hdr_resp_info
 
 } RPC_HDR_RESP;
 
-/* RPC_HDR_FAULT - ms fault rpc header */
-typedef struct rpc_hdr_fault_info
-{
-       uint32 status;
-       uint32 reserved; /* 0x0000 0000 */
-
-} RPC_HDR_FAULT;
+#define RPC_HDR_RESP_LEN 8
 
 /* this seems to be the same string name depending on the name of the pipe,
  * but is more likely to be linked to the interface name
@@ -160,6 +179,8 @@ typedef struct rpc_hdr_bba_info
 
 } RPC_HDR_BBA;
 
+#define RPC_HDR_BBA_LEN 8
+
 /* RPC_HDR_AUTHA */
 typedef struct rpc_hdr_autha_info
 {
@@ -175,6 +196,8 @@ typedef struct rpc_hdr_autha_info
 
 } RPC_HDR_AUTHA;
 
+#define RPC_HDR_AUTHA_LEN 12
+
 /* RPC_HDR_AUTH */
 typedef struct rpc_hdr_auth_info
 {
@@ -187,6 +210,8 @@ typedef struct rpc_hdr_auth_info
 
 } RPC_HDR_AUTH;
 
+#define RPC_HDR_AUTH_LEN 8
+
 /* RPC_BIND_REQ - ms req bind */
 typedef struct rpc_bind_req_info
 {
@@ -201,6 +226,13 @@ typedef struct rpc_bind_req_info
   
 } RPC_HDR_RB;
 
+/* 
+ * The following length is 8 bytes RPC_HDR_BBA_LEN, 8 bytes internals 
+ * (with 3 bytes padding), + 2 x RPC_IFACE_LEN bytes for RPC_IFACE structs.
+ */
+
+#define RPC_HDR_RB_LEN (RPC_HDR_BBA_LEN + 8 + (2*RPC_IFACE_LEN))
+
 /* RPC_RESULTS - can only cope with one reason, right now... */
 typedef struct rpc_results_info
 {
@@ -226,13 +258,13 @@ typedef struct rpc_hdr_ba_info
 
 } RPC_HDR_BA;
 
-/* RPC_AUTH_NTLMSSP_VERIFIER */
-typedef struct rpc_auth_ntlmssp_verif_info
+/* RPC_AUTH_VERIFIER */
+typedef struct rpc_auth_verif_info
 {
        fstring signature; /* "NTLMSSP" */
        uint32  msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) */
 
-} RPC_AUTH_NTLMSSP_VERIFIER;
+} RPC_AUTH_VERIFIER;
 
 /* this is TEMPORARILY coded up as a specific structure */
 /* this structure comes after the bind request */
@@ -267,8 +299,8 @@ typedef struct rpc_auth_ntlmssp_chal_info
 /* RPC_AUTH_NTLMSSP_RESP */
 typedef struct rpc_auth_ntlmssp_resp_info
 {
-       STRHDR hdr_lm_resp; /* LM response (NULL or 24 bytes) */
-       STRHDR hdr_nt_resp; /* NT response (NULL, 24 or variable-length) */
+       STRHDR hdr_lm_resp; /* 24 byte response */
+       STRHDR hdr_nt_resp; /* 24 byte response */
        STRHDR hdr_domain;
        STRHDR hdr_usr;
        STRHDR hdr_wks;
@@ -284,7 +316,6 @@ typedef struct rpc_auth_ntlmssp_resp_info
 
 } RPC_AUTH_NTLMSSP_RESP;
 
-
 /* attached to the end of encrypted rpc requests and responses */
 /* RPC_AUTH_NTLMSSP_CHK */
 typedef struct rpc_auth_ntlmssp_chk_info
@@ -296,5 +327,6 @@ typedef struct rpc_auth_ntlmssp_chk_info
 
 } RPC_AUTH_NTLMSSP_CHK;
 
-#endif /* _DCE_RPC_H */
+#define RPC_AUTH_NTLMSSP_CHK_LEN 16
 
+#endif /* _DCE_RPC_H */
index f4d36fef9c19d95c00f66d9e2a68a2a4cfc6aa67..c7fe77021b03d8ad42c131a6b631aaafb58927d8 100644 (file)
@@ -46,10 +46,12 @@ enum SID_NAME_USE
 #define LSA_LOOKUPSIDS         0x0f
 #define LSA_OPENPOLICY         0x06
 #define LSA_OPENPOLICY2        0x2c
-#define LSA_OPENSECRET         0x1c
-#define LSA_QUERYSECRET        0x1e
+#define LSA_OPENSECRET         0x1C
 
-#define LSA_MAX_GROUPS 32
+/* XXXX these are here to get a compile! */
+#define LSA_LOOKUPRIDS      0xFD
+
+#define LSA_MAX_GROUPS 96
 #define LSA_MAX_SIDS 32
 
 /* DOM_QUERY - info class 3 and 5 LSA Query response */
@@ -94,7 +96,7 @@ typedef struct obj_attr_info
 typedef struct lsa_q_open_pol_info
 {
        uint32 ptr;         /* undocumented buffer pointer */
-       uint16 system_name; /* system name BUG!!! (should be \\server!) */
+       uint16 system_name; /* 0x5c - system name */
        LSA_OBJ_ATTR attr ; /* object attributes */
 
        uint32 des_access; /* desired access attributes */
@@ -132,7 +134,7 @@ typedef struct lsa_r_open_pol2_info
 typedef struct lsa_query_info
 {
        POLICY_HND pol; /* policy handle */
-       uint16 info_class; /* info class */
+    uint16 info_class; /* info class */
 
 } LSA_Q_QUERY_INFO;
 
@@ -153,74 +155,15 @@ typedef struct lsa_r_query_info
 
 } LSA_R_QUERY_INFO;
 
-/* LSA_Q_OPEN_SECRET - LSA Open Secret */
-typedef struct lsa_q_open_secret_info
-{
-       POLICY_HND pol;
-       UNIHDR hdr_secret;
-       UNISTR2 uni_secret;
-
-       uint32 des_access; /* desired access attributes */
-
-} LSA_Q_OPEN_SECRET;
-
-/* LSA_R_OPEN_SECRET - response to LSA Open Secret */
-typedef struct lsa_r_open_secret_info
-{
-       POLICY_HND pol;
-       uint32 status;
-
-} LSA_R_OPEN_SECRET;
-
-typedef struct lsa_secret_value_info
-{
-       uint32 ptr_secret;
-       STRHDR2 hdr_secret;
-       STRING2 enc_secret; /* encrypted, see nt_encrypt_string2 */
-
-} LSA_SECRET_VALUE;
-
-typedef struct lsa_secret_info_info
-{
-       uint32 ptr_value;
-       LSA_SECRET_VALUE value;
-
-       uint32 ptr_update;
-       NTTIME last_update; /* N.B. 64-bit alignment? */
-
-} LSA_SECRET_INFO;
-
-/* LSA_Q_QUERY_SECRET - LSA Query Secret */
-typedef struct lsa_q_query_secret_info
-{
-       POLICY_HND pol;
-
-       LSA_SECRET_INFO info;    /* [in, out] */
-       LSA_SECRET_INFO oldinfo;
-
-} LSA_Q_QUERY_SECRET;
-
-/* LSA_R_QUERY_SECRET - response to LSA Query Secret */
-typedef struct lsa_r_query_secret_info
-{
-       LSA_SECRET_INFO info;
-       LSA_SECRET_INFO oldinfo;
-
-       uint32 status;
-
-} LSA_R_QUERY_SECRET;
-
 /* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
 typedef struct lsa_enum_trust_dom_info
 {
        POLICY_HND pol; /* policy handle */
-       uint32 enum_context; /* enumeration context handle */
-       uint32 preferred_len; /* preferred maximum length */
+    uint32 enum_context; /* enumeration context handle */
+    uint32 preferred_len; /* preferred maximum length */
 
 } LSA_Q_ENUM_TRUST_DOM;
 
-#define MAX_TRUSTED_DOMS 10
-
 /* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
 typedef struct lsa_r_enum_trust_dom_info
 {
@@ -229,12 +172,12 @@ typedef struct lsa_r_enum_trust_dom_info
        uint32 ptr_enum_domains; /* buffer pointer to num domains */
 
        /* this lot is only added if ptr_enum_domains is non-NULL */
-       uint32 num_domains2; /* number of domains */
-       UNIHDR2 hdr_domain_name[MAX_TRUSTED_DOMS];
-       UNISTR2 uni_domain_name[MAX_TRUSTED_DOMS];
-       DOM_SID2 domain_sid[MAX_TRUSTED_DOMS];
+               uint32 num_domains2; /* number of domains */
+               UNIHDR2 hdr_domain_name;
+               UNISTR2 uni_domain_name;
+               DOM_SID2 other_domain_sid;
 
-       uint32 status; /* return code */
+    uint32 status; /* return code */
 
 } LSA_R_ENUM_TRUST_DOM;
 
@@ -255,7 +198,7 @@ typedef struct lsa_r_close_info
 } LSA_R_CLOSE;
 
 
-#define MAX_REF_DOMAINS 10
+#define MAX_REF_DOMAINS 32
 
 /* DOM_TRUST_HDR */
 typedef struct dom_trust_hdr
@@ -276,13 +219,13 @@ typedef struct dom_trust_info
 /* DOM_R_REF */
 typedef struct dom_ref_info
 {
-       uint32 num_ref_doms_1; /* num referenced domains */
-       uint32 ptr_ref_dom; /* pointer to referenced domains */
-       uint32 max_entries; /* 32 - max number of entries */
-       uint32 num_ref_doms_2; /* num referenced domains */
+    uint32 num_ref_doms_1; /* num referenced domains */
+    uint32 ptr_ref_dom; /* pointer to referenced domains */
+    uint32 max_entries; /* 32 - max number of entries */
+    uint32 num_ref_doms_2; /* num referenced domains */
 
-       DOM_TRUST_HDR  hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */
-       DOM_TRUST_INFO ref_dom    [MAX_REF_DOMAINS]; /* referenced domains */
+    DOM_TRUST_HDR  hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */
+    DOM_TRUST_INFO ref_dom    [MAX_REF_DOMAINS]; /* referenced domains */
 
 } DOM_R_REF;
 
@@ -347,20 +290,19 @@ typedef struct lsa_r_lookup_sids
 
 } LSA_R_LOOKUP_SIDS;
 
-
 /* LSA_Q_LOOKUP_NAMES - LSA Lookup NAMEs */
 typedef struct lsa_q_lookup_names
 {
-    POLICY_HND pol; /* policy handle */
-    uint32 num_entries;
-    uint32 num_entries2;
-    UNIHDR  hdr_name[MAX_LOOKUP_SIDS]; /* name buffer pointers */
-    UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
+       POLICY_HND pol; /* policy handle */
+       uint32 num_entries;
+       uint32 num_entries2;
+       UNIHDR  hdr_name[MAX_LOOKUP_SIDS]; /* name buffer pointers */
+       UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
 
-    uint32 num_trans_entries; 
-    uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */
-    uint32 lookup_level; 
-    uint32 mapped_count; 
+       uint32 num_trans_entries;
+       uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */
+       uint32 lookup_level;
+       uint32 mapped_count;
 
 } LSA_Q_LOOKUP_NAMES;
 
@@ -372,15 +314,14 @@ typedef struct lsa_r_lookup_names
 
        uint32 num_entries;
        uint32 ptr_entries;
-       uint32 num_entries2; 
+       uint32 num_entries2;
        DOM_RID2 *dom_rid; /* domain RIDs being looked up */
 
-       uint32 mapped_count; 
+       uint32 mapped_count;
 
        uint32 status; /* return code */
 
 } LSA_R_LOOKUP_NAMES;
 
-
 #endif /* _RPC_LSA_H */
 
index ed8cbd96bb443f9cecf5c28fd7b45b8c09edf101..b837c8a67c5952ef9fd757fb867813eca98e734b 100644 (file)
 #ifndef _RPC_MISC_H /* _RPC_MISC_H */
 #define _RPC_MISC_H 
 
-/*
- * macros to wrap prs_xxxx routines.
- */
-#define prs_uint8(name, ps, depth, data8) \
-       if (!_prs_uint8(name, ps, depth, data8)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint16(name, ps, depth, data16) \
-       if (!_prs_uint16(name, ps, depth, data16)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_hash1(x_ps, x_offset, x_sess_key) \
-       if (!_prs_hash1(x_ps, x_offset, x_sess_key)) \
-       {\
-               x_ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint32(name, ps, depth, data32) \
-       if (!_prs_uint32(name, ps, depth, data32)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint8s(charmode, name, ps, depth, data8s, len) \
-       if (!_prs_uint8s(charmode, name, ps, depth, data8s, len)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint16s(charmode, name, ps, depth, data16s, len) \
-       if (!_prs_uint16s(charmode, name, ps, depth, data16s, len)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint32s(charmode, name, ps, depth, data32s, len) \
-       if (!_prs_uint32s(charmode, name, ps, depth, data32s, len)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_buffer2(charmode, name, ps, depth, str) \
-       if (!_prs_buffer2(charmode, name, ps, depth, str)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_string2(charmode, name, ps, depth, str) \
-       if (!_prs_string2(charmode, name, ps, depth, str)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_unistr2(charmode, name, ps, depth, str) \
-       if (!_prs_unistr2(charmode, name, ps, depth, str)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_unistr3(charmode, name, str, ps, depth) \
-       if (!_prs_unistr3(charmode, name, str, ps, depth)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_unistr(name, ps, depth, str) \
-       if (!_prs_unistr(name, ps, depth, str)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_string(name, ps, depth, str, len, max_buf_size) \
-       if (!_prs_string(name, ps, depth, str, len, max_buf_size)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint16_pre(x_name, x_ps, x_depth, x_data16, x_offset) \
-       if (!_prs_uint16_pre(x_name, x_ps, x_depth, x_data16, x_offset)) \
-       {\
-               x_ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint16_post(name, ps, depth, data16, ptr_uint16, data_size) \
-       if (!_prs_uint16_post(name, ps, depth, data16, ptr_uint16, data_size)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint32_pre(x_name, x_ps, x_depth, x_data32, x_offset) \
-       if (!_prs_uint32_pre(x_name, x_ps, x_depth, x_data32, x_offset)) \
-       {\
-               x_ps->offset = 0;\
-               return False;\
-       }
-#define prs_uint32_post(name, ps, depth, data32, ptr_uint32, data_size) \
-       if (!_prs_uint32_post(name, ps, depth, data32, ptr_uint32, data_size)) \
-       {\
-               ps->offset = 0;\
-               return False;\
-       }
 
 #include "rpc_dce.h"
 
 #define BUILTIN_ALIAS_RID_USERS         (0x00000221L)
 #define BUILTIN_ALIAS_RID_GUESTS        (0x00000222L)
 #define BUILTIN_ALIAS_RID_POWER_USERS   (0x00000223L)
+
 #define BUILTIN_ALIAS_RID_ACCOUNT_OPS   (0x00000224L)
 #define BUILTIN_ALIAS_RID_SYSTEM_OPS    (0x00000225L)
 #define BUILTIN_ALIAS_RID_PRINT_OPS     (0x00000226L)
 #define BUILTIN_ALIAS_RID_BACKUP_OPS    (0x00000227L)
+
 #define BUILTIN_ALIAS_RID_REPLICATOR    (0x00000228L)
 
 /*
  * NT RIDS.
  */
 
-/* Take the bottom bits. */
-#define RID_TYPE_MASK 2
-#define RID_MULTIPLIER 4
-
-/* The three common types. */
-#define RID_TYPE_USER    0
-#define RID_TYPE_GROUP   1
-#define RID_TYPE_ALIAS   2
-
-/* BIGINT - NT-style 64-bit integer */
-typedef struct bigint_info
-{
-       uint32 low;
-       uint32 high;
-
-} BIGINT;
+/* Take the bottom bit. */
+#define RID_TYPE_MASK 1
+#define RID_MULTIPLIER 2
 
+/* The two common types. */
+#define USER_RID_TYPE 0
+#define GROUP_RID_TYPE 1
 
 /* ENUM_HND */
 typedef struct enum_hnd_info
@@ -210,15 +97,6 @@ typedef struct header_info
 
 } STRHDR;
 
-/* STRHDR2 - string header, 32-bit lengths */
-typedef struct header2_info
-{
-  uint32 str_str_len;
-  uint32 str_max_len;
-  uint32 buffer;
-
-} STRHDR2;
-
 /* UNIHDR - unicode string header */
 typedef struct unihdr_info
 {
@@ -244,8 +122,8 @@ typedef struct unihdr2_info
 /* UNISTR - unicode string size and buffer */
 typedef struct unistr_info
 {
-  uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. ***MUST*** be null-terminated */
-
+  /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
+  uint16 buffer[MAX_UNISTRLEN];
 } UNISTR;
 
 /* BUFHDR - buffer header */
@@ -256,15 +134,6 @@ typedef struct bufhdr_info
 
 } BUFHDR;
 
-/* BUFHDR2 - another buffer header, with info level */
-typedef struct bufhdr2_info
-{
-  uint32 info_level;
-  uint32 length; /* uint8 chars */
-  uint32 buffer;
-
-} BUFHDR2;
-
 /* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
 /* pathetic.  some stupid team of \PIPE\winreg writers got the concept */
 /* of a unicode string different from the other \PIPE\ writers */
@@ -273,7 +142,8 @@ typedef struct buffer2_info
   uint32 buf_max_len;
   uint32 undoc;
   uint32 buf_len;
-  uint8 buffer[MAX_UNISTRLEN];
+  /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
+  uint16 buffer[MAX_UNISTRLEN];
 
 } BUFFER2;
 
@@ -286,28 +156,14 @@ typedef struct buffer3_info
 
 } BUFFER3;
 
-/* BUFFER4 - simple length and buffer */
-typedef struct buffer4_info
-{
-  uint32 buf_len;
-  uint8  buffer[MAX_BUFFERLEN];
-
-} BUFFER4;
-
-/* BUFFER5 */
-typedef struct buffer5_info
-{
-  uint32 buf_len;
-  uint16 *buffer; /* data */
-} BUFFER5;
-
 /* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
 typedef struct unistr2_info
 {
   uint32 uni_max_len;
   uint32 undoc;
   uint32 uni_str_len;
-  uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
+  /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
+  uint16 buffer[MAX_UNISTRLEN];
 
 } UNISTR2;
 
@@ -350,6 +206,15 @@ typedef struct domrid3_info
 
 } DOM_RID3;
 
+/* DOM_RID4 - rid + user attributes */
+typedef struct domrid4_info
+{
+  uint32 unknown;
+  uint16 attr;
+  uint32 rid;  /* user RID */
+
+} DOM_RID4;
+
 /* DOM_CLNT_SRV - client / server names */
 typedef struct clnt_srv_info
 {
@@ -422,4 +287,3 @@ typedef struct lsa_policy_info
 } POLICY_HND;
 
 #endif /* _RPC_MISC_H */
-
index 31d8a3c1e5d878a49e6adae33b363e0a4873db89..06caa53f4de82caeff96330d065ac1fe3679191a 100644 (file)
 #define NET_SRVPWSET           0x06
 #define NET_SAMLOGON           0x02
 #define NET_SAMLOGOFF          0x03
-#define NET_AUTH               0x05
 #define NET_AUTH2              0x0f
 #define NET_LOGON_CTRL2        0x0e
 #define NET_TRUST_DOM_LIST     0x13
 
-#define NET_SAM_SYNC           0x10
-#define NET_SAM_DELTAS         0x07
-
 /* Secure Channel types.  used in NetrServerAuthenticate negotiation */
 #define SEC_CHAN_WKSTA   2
 #define SEC_CHAN_DOMAIN  4
-#define SEC_CHAN_BDC     6
 
+#if 0
+/* JRATEST.... */
+/* NET_USER_INFO_2 */
+typedef struct net_user_info_2
+{
+        uint32 ptr_user_info;
+
+        NTTIME logon_time;            /* logon time */
+        NTTIME logoff_time;           /* logoff time */
+        NTTIME kickoff_time;          /* kickoff time */
+        NTTIME pass_last_set_time;    /* password last set time */
+        NTTIME pass_can_change_time;  /* password can change time */
+        NTTIME pass_must_change_time; /* password must change time */
+
+....
+       uint32 user_id;       /* User ID */
+       uint32 group_id;      /* Group ID */
+....
+       uint32 num_groups2;        /* num groups */
+       DOM_GID gids[LSA_MAX_GROUPS]; /* group info */
+
+       UNIHDR hdr_logon_srv; /* logon server unicode string header */
+       UNISTR2 uni_logon_dom; /* logon domain unicode string */
+       DOM_SID2 dom_sid;
        
+} NET_USER_INFO_2;
+/* ! JRATEST.... */
+#endif
+
 /* NET_USER_INFO_3 */
 typedef struct net_user_info_3
 {
@@ -192,7 +215,7 @@ typedef struct net_q_trust_dom_info
 /* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
 typedef struct net_r_trust_dom_info
 {
-       BUFFER2 uni_trust_dom_name;
+       UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
 
        uint32 status; /* return code */
 
@@ -227,24 +250,8 @@ typedef struct net_r_req_chal_info
 
 } NET_R_REQ_CHAL;
 
-/* NET_Q_AUTH */
-typedef struct net_q_auth_info
-{
-    DOM_LOG_INFO clnt_id; /* client identification info */
-    DOM_CHAL clnt_chal;     /* client-calculated credentials */
 
 
-} NET_Q_AUTH;
-
-/* NET_R_AUTH */
-typedef struct net_r_auth_info
-{
-    DOM_CHAL srv_chal;     /* server-calculated credentials */
-
-  uint32 status; /* return code */
-
-} NET_R_AUTH;
-
 /* NET_Q_AUTH_2 */
 typedef struct net_q_auth2_info
 {
@@ -255,6 +262,7 @@ typedef struct net_q_auth2_info
 
 } NET_Q_AUTH_2;
 
+
 /* NET_R_AUTH_2 */
 typedef struct net_r_auth2_info
 {
@@ -265,6 +273,7 @@ typedef struct net_r_auth2_info
 
 } NET_R_AUTH_2;
 
+
 /* NET_Q_SRV_PWSET */
 typedef struct net_q_srv_pwset_info
 {
@@ -288,7 +297,7 @@ typedef struct net_network_info_2
        uint32            ptr_id_info2;        /* pointer to id_info_2 */
        UNIHDR            hdr_domain_name;     /* domain name unicode header */
        uint32            param_ctrl;          /* param control (0x2) */
-       BIGINT            logon_id;            /* logon ID */
+       DOM_LOGON_ID      logon_id;            /* logon ID */
        UNIHDR            hdr_user_name;       /* user name unicode header */
        UNIHDR            hdr_wksta_name;      /* workstation name unicode header */
        uint8             lm_chal[8];          /* lan manager 8 byte challenge */
@@ -309,7 +318,7 @@ typedef struct id_info_1
        uint32            ptr_id_info1;        /* pointer to id_info_1 */
        UNIHDR            hdr_domain_name;     /* domain name unicode header */
        uint32            param_ctrl;          /* param control */
-       BIGINT            logon_id;            /* logon ID */
+       DOM_LOGON_ID      logon_id;            /* logon ID */
        UNIHDR            hdr_user_name;       /* user name unicode header */
        UNIHDR            hdr_wksta_name;      /* workstation name unicode header */
        OWF_INFO          lm_owf;              /* LM OWF Password */
@@ -351,7 +360,7 @@ typedef struct sam_info
 /* NET_Q_SAM_LOGON */
 typedef struct net_q_sam_logon_info
 {
-       DOM_SAM_INFO sam_id;
+    DOM_SAM_INFO sam_id;
        uint16          validation_level;
 
 } NET_Q_SAM_LOGON;
@@ -390,270 +399,5 @@ typedef struct net_r_sam_logoff_info
 } NET_R_SAM_LOGOFF;
 
 
-/* NET_Q_SAM_SYNC */
-typedef struct net_q_sam_sync_info
-{
-       UNISTR2 uni_srv_name; /* \\PDC */
-       UNISTR2 uni_cli_name; /* BDC */
-       DOM_CRED cli_creds;
-       DOM_CRED ret_creds;
-
-       uint32 database_id;
-       uint32 restart_state;
-       uint32 sync_context;
-
-       uint32 max_size;       /* preferred maximum length */
-
-} NET_Q_SAM_SYNC;
-
-#define MAX_GROUP_MEM  256
-#define MAX_SAM_DELTAS 256
-
-/* SAM_DELTA_HDR */
-typedef struct sam_delta_hdr_info
-{
-       uint16 type;  /* type of structure attached, see below */
-       uint16 type2;
-       uint32 target_rid;
-
-       uint32 type3;
-       uint32 ptr_delta;
-
-} SAM_DELTA_HDR;
-
-/* SAM_DOMAIN_INFO (0x1) */
-typedef struct sam_domain_info_info
-{
-       UNIHDR hdr_dom_name;
-       UNIHDR hdr_oem_info;
-
-       BIGINT force_logoff;
-       uint16 min_pwd_len;
-       uint16 pwd_history_len;
-       BIGINT max_pwd_age;
-       BIGINT min_pwd_age;
-       BIGINT dom_mod_count;
-       NTTIME creation_time;
-
-       BUFHDR2 hdr_sec_desc; /* security descriptor */
-       UNIHDR hdr_unknown;
-       uint8 reserved[40];
-
-       UNISTR2 uni_dom_name;
-       UNISTR2 buf_oem_info; /* never seen */
-
-       BUFFER4 buf_sec_desc;
-       UNISTR2 buf_unknown;
-
-} SAM_DOMAIN_INFO;
-
-/* SAM_GROUP_INFO (0x2) */
-typedef struct sam_group_info_info
-{
-       UNIHDR hdr_grp_name;
-       DOM_GID gid;
-       UNIHDR hdr_grp_desc;
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-       uint8 reserved[48];
-
-       UNISTR2 uni_grp_name;
-       UNISTR2 uni_grp_desc;
-       BUFFER4 buf_sec_desc;
-
-} SAM_GROUP_INFO;
-
-/* SAM_PWD */
-typedef struct sam_passwd_info
-{
-       /* this structure probably contains password history */
-       /* this is probably a count of lm/nt pairs */
-       uint32 unk_0; /* 0x0000 0002 */
-
-       UNIHDR hdr_lm_pwd;
-       uint8  buf_lm_pwd[16];
-
-       UNIHDR hdr_nt_pwd;
-       uint8  buf_nt_pwd[16];
-
-       UNIHDR hdr_empty_lm;
-       UNIHDR hdr_empty_nt;
-
-} SAM_PWD;
-
-/* SAM_ACCOUNT_INFO (0x5) */
-typedef struct sam_account_info_info
-{
-       UNIHDR hdr_acct_name;
-       UNIHDR hdr_full_name;
-
-       uint32 user_rid;
-       uint32 group_rid;
-
-       UNIHDR hdr_home_dir;
-       UNIHDR hdr_dir_drive;
-       UNIHDR hdr_logon_script;
-       UNIHDR hdr_acct_desc;
-       UNIHDR hdr_workstations;
-
-       NTTIME logon_time;
-       NTTIME logoff_time;
-
-       uint32 logon_divs; /* 0xA8 */
-       uint32 ptr_logon_hrs;
-
-       uint16 bad_pwd_count;
-       uint16 logon_count;
-       NTTIME pwd_last_set_time;
-       NTTIME acct_expiry_time;
-
-       uint32 acb_info;
-       uint8 nt_pwd[16];
-       uint8 lm_pwd[16];
-       uint8 nt_pwd_present;
-       uint8 lm_pwd_present;
-       uint8 pwd_expired;
-
-       UNIHDR hdr_comment;
-       UNIHDR hdr_parameters;
-       uint16 country;
-       uint16 codepage;
-
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-
-       UNIHDR  hdr_profile;
-       UNIHDR  hdr_reserved[3];  /* space for more strings */
-       uint32  dw_reserved[4];   /* space for more data - first two seem to
-                                    be an NTTIME */
-
-       UNISTR2 uni_acct_name;
-       UNISTR2 uni_full_name;
-       UNISTR2 uni_home_dir;
-       UNISTR2 uni_dir_drive;
-       UNISTR2 uni_logon_script;
-       UNISTR2 uni_acct_desc;
-       UNISTR2 uni_workstations;
-
-       uint32 unknown1; /* 0x4EC */
-       uint32 unknown2; /* 0 */
-
-       BUFFER4 buf_logon_hrs;
-       UNISTR2 uni_comment;
-       UNISTR2 uni_parameters;
-       SAM_PWD pass;
-       BUFFER4 buf_sec_desc;
-       UNISTR2 uni_profile;
-
-} SAM_ACCOUNT_INFO;
-
-/* SAM_GROUP_MEM_INFO (0x8) */
-typedef struct sam_group_mem_info_info
-{
-       uint32 ptr_rids;
-       uint32 ptr_attribs;
-       uint32 num_members;
-       uint8 unknown[16];
-
-       uint32 num_members2;
-       uint32 rids[MAX_GROUP_MEM];
-
-       uint32 num_members3;
-       uint32 attribs[MAX_GROUP_MEM];
-
-} SAM_GROUP_MEM_INFO;
-
-/* SAM_ALIAS_INFO (0x9) */
-typedef struct sam_alias_info_info
-{
-       UNIHDR hdr_als_name;
-       uint32 als_rid;
-       BUFHDR2 hdr_sec_desc;  /* security descriptor */
-       UNIHDR hdr_als_desc;
-       uint8 reserved[40];
-
-       UNISTR2 uni_als_name;
-       BUFFER4 buf_sec_desc;
-       UNISTR2 uni_als_desc;
-
-} SAM_ALIAS_INFO;
-
-/* SAM_ALIAS_MEM_INFO (0xC) */
-typedef struct sam_alias_mem_info_info
-{
-       uint32 num_members;
-       uint32 ptr_members;
-       uint8 unknown[16];
-
-       uint32 num_sids;
-       uint32 ptr_sids[MAX_GROUP_MEM];
-       DOM_SID2 sids[MAX_GROUP_MEM];
-
-} SAM_ALIAS_MEM_INFO;
-
-/* SAM_DELTA_CTR */
-typedef union sam_delta_ctr_info
-{
-       SAM_DOMAIN_INFO    domain_info ;
-       SAM_GROUP_INFO     group_info  ;
-       SAM_ACCOUNT_INFO   account_info;
-       SAM_GROUP_MEM_INFO grp_mem_info;
-       SAM_ALIAS_INFO     alias_info  ;
-       SAM_ALIAS_MEM_INFO als_mem_info;
-
-} SAM_DELTA_CTR;
-
-/* NET_R_SAM_SYNC */
-typedef struct net_r_sam_sync_info
-{
-       DOM_CRED srv_creds;
-
-       uint32 sync_context;
-
-       uint32 ptr_deltas;
-       uint32 num_deltas;
-       uint32 ptr_deltas2;
-       uint32 num_deltas2;
-
-       SAM_DELTA_HDR *hdr_deltas;
-       SAM_DELTA_CTR *deltas;
-
-       uint32 status;
-
-} NET_R_SAM_SYNC;
-
-
-/* NET_Q_SAM_DELTAS */
-typedef struct net_q_sam_deltas_info
-{
-       UNISTR2 uni_srv_name;
-       UNISTR2 uni_cli_name;
-       DOM_CRED cli_creds;
-       DOM_CRED ret_creds;
-
-       uint32 database_id;
-       BIGINT dom_mod_count;  /* domain mod count at last sync */
-
-       uint32 max_size;       /* preferred maximum length */
-
-} NET_Q_SAM_DELTAS;
-
-/* NET_R_SAM_DELTAS */
-typedef struct net_r_sam_deltas_info
-{
-       DOM_CRED srv_creds;
-
-       BIGINT dom_mod_count;   /* new domain mod count */
-
-       uint32 num_deltas;
-       uint32 ptr_deltas;
-       uint32 num_deltas2;
-
-       SAM_DELTA_HDR *hdr_deltas;
-       SAM_DELTA_CTR *deltas;
-
-       uint32 status;
-
-} NET_R_SAM_DELTAS;
-
-
 #endif /* _RPC_NETLOGON_H */
 
index 7e74af8ab8357c0958f7ad5efceb83a57c2e44f0..776605258884e379efb485ddb0b2e27dfb7e77d5 100644 (file)
@@ -26,7 +26,6 @@
 
 
 /* winreg pipe defines */
-#define REG_OPEN_HKCR       0x00
 #define REG_OPEN_HKLM       0x02
 #define REG_OPEN_HKU        0x04
 #define REG_FLUSH_KEY       0x0B
 #define REG_OPEN_ENTRY      0x0f
 #define REG_INFO            0x11
 #define REG_CLOSE           0x05
-#define REG_SHUTDOWN        0x18
 
-#define HKEY_CLASSES_ROOT  0x80000000
-#define HKEY_CURRENT_USER  0x80000001
-#define HKEY_LOCAL_MACHINE 0x80000002
+#define HKEY_LOCAL_MACHINE 0x80000000
 #define HKEY_USERS         0x80000003
 
-/* REG_Q_OPEN_HKCR   */
-typedef struct q_reg_open_hkcr_info
-{
-       uint32 ptr;
-       uint16 unknown_0; /* 0x5428      - 16 bit unknown */
-       uint16 unknown_1; /* random.  changes */
-       uint32 level;     /* 0x0200 0000 */
-
-} REG_Q_OPEN_HKCR;
-
-/* REG_R_OPEN_HKCR   */
-typedef struct r_reg_open_hkcr_info
-{
-       POLICY_HND pol;       /* policy handle */
-       uint32 status;         /* return status */
-
-} REG_R_OPEN_HKCR;
-
-
 /* REG_Q_OPEN_HKLM   */
-typedef struct q_reg_open_hklm_info
+typedef struct q_reg_open_policy_info
 {
        uint32 ptr;
        uint16 unknown_0; /* 0xE084      - 16 bit unknown */
@@ -80,7 +57,7 @@ typedef struct q_reg_open_hklm_info
 } REG_Q_OPEN_HKLM  ;
 
 /* REG_R_OPEN_HKLM   */
-typedef struct r_reg_open_hklm_info
+typedef struct r_reg_open_policy_info
 {
        POLICY_HND pol;       /* policy handle */
        uint32 status;         /* return status */
@@ -89,7 +66,7 @@ typedef struct r_reg_open_hklm_info
 
 
 /* REG_Q_OPEN_HKU */
-typedef struct q_reg_open_hku_info
+typedef struct q_reg_open_unk4_info
 {
        uint32 ptr;
        uint16 unknown_0; /* 0xE084      - 16 bit unknown */
@@ -99,7 +76,7 @@ typedef struct q_reg_open_hku_info
 } REG_Q_OPEN_HKU;
 
 /* REG_R_OPEN_HKU */
-typedef struct r_reg_open_hku_info
+typedef struct r_reg_open_unk4_info
 {
        POLICY_HND pol;       /* policy handle */
        uint32 status;         /* return status */
@@ -159,6 +136,8 @@ typedef struct q_reg_get_key_sec_info
 /* REG_R_GET_KEY_SEC */
 typedef struct r_reg_get_key_sec_info
 {
+       uint32 sec_info;       /* xxxx_SECURITY_INFORMATION */
+
        uint32 ptr;       /* pointer */
        BUFHDR hdr_sec;    /* header for security data */
        SEC_DESC_BUF *data;    /* security data */
@@ -419,37 +398,39 @@ typedef struct q_reg_info_info
 {
        POLICY_HND pol;        /* policy handle */
 
-       UNIHDR  hdr_val;       /* unicode product type header */
-       UNISTR2 uni_val;       /* unicode product type - "ProductType" */
+       UNIHDR  hdr_type;       /* unicode product type header */
+       UNISTR2 uni_type;       /* unicode product type - "ProductType" */
 
-       uint32 ptr_type;            /* pointer */
-       uint32 type;            /* type of buffer */
-
-       uint32 ptr_uni_type;       /* pointer to o/s type */
-       BUFFER2 uni_type;      /* unicode string o/s type - "LanmanNT" */
+       uint32 ptr1;            /* pointer */
+       NTTIME time;            /* current time? */
+       uint8  major_version1;  /* 0x4 - os major version? */
+       uint8  minor_version1;  /* 0x1 - os minor version? */
+       uint8  pad1[10];        /* padding - zeros */
 
-       uint32 ptr_max_len;           /* pointer to unknown_0 */
-       uint32 buf_max_len;    /* 0x12 */
+       uint32 ptr2;            /* pointer */
+       uint8  major_version2;  /* 0x4 - os major version? */
+       uint8  minor_version2;  /* 0x1 - os minor version? */
+       uint8  pad2[2];         /* padding - zeros */
 
-       uint32 ptr_len;           /* pointer to unknown_1 */
-       uint32 buf_len;        /* 0x12 */
+       uint32 ptr3;            /* pointer */
+       uint32 unknown;         /* 0x0000 0000 */
 
 } REG_Q_INFO;
 
 /* REG_R_INFO */
 typedef struct r_reg_info_info
 { 
-       uint32 ptr_type;            /* buffer pointer */
-       uint32 *type;          /* 0x1 - info level? */
+       uint32 ptr1;            /* buffer pointer */
+       uint32 level;          /* 0x1 - info level? */
 
-       uint32 ptr_uni_type;       /* pointer to o/s type */
-       BUFFER2 *uni_type;      /* unicode string o/s type - "LanmanNT" */
+       uint32 ptr_type;       /* pointer to o/s type */
+       BUFFER2 uni_type;      /* unicode string o/s type - "LanmanNT" */
 
-       uint32 ptr_max_len;    /* pointer to unknown_0 */
-       uint32 buf_max_len;    /* 0x12 */
+       uint32 ptr2;           /* pointer to unknown_0 */
+       uint32 unknown_0;      /* 0x12 */
 
-       uint32 ptr_len;    /* pointer to unknown_1 */
-       uint32 buf_len;        /* 0x12 */
+       uint32 ptr3;           /* pointer to unknown_1 */
+       uint32 unknown_1;      /* 0x12 */
 
        uint32 status;         /* return status */
 
@@ -480,26 +461,6 @@ typedef struct r_reg_open_entry_info
 } REG_R_OPEN_ENTRY;
 
 
-/* REG_Q_SHUTDOWN */
-typedef struct q_reg_shutdown_info
-{
-       uint32 ptr_0;
-       uint32 ptr_1;
-       uint32 ptr_2;
-       UNIHDR hdr_msg;   /* shutdown message */
-       UNISTR2 uni_msg;
-       uint32 timeout; /* seconds */
-       uint16 flags;       
-
-} REG_Q_SHUTDOWN;
-
-/* REG_R_SHUTDOWN */
-typedef struct r_reg_shutdown_info
-{ 
-       uint32 status; /* return status */
-
-} REG_R_SHUTDOWN;
-
 
 #endif /* _RPC_REG_H */
 
index 2c9a719ff5cd3544769838c5fe69c42264e41b99..1444d932b460c4510504740cbf1b6ad2c5e21fe0 100644 (file)
@@ -2,9 +2,9 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    SMB parameters and setup
-   Copyright (C) Andrew Tridgell 1992-1998
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1998
-   Copyright (C) Paul Ashton 1997-1998
+   Copyright (C) Andrew Tridgell 1992-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+   Copyright (C) Paul Ashton 1997
    
    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 following information comes from a QuickView on samsrv.dll,
  and gives an idea of exactly what is needed:
  
-SamrAddMemberToAlias
-SamrAddMemberToGroup
+SamrAddMemberToAlias
+SamrAddMemberToGroup
 SamrAddMultipleMembersToAlias
-SamrChangePasswordUser
+SamrChangePasswordUser
 x SamrCloseHandle
 x SamrConnect
-SamrCreateAliasInDomain
-SamrCreateGroupInDomain
-SamrCreateUserInDomain
-SamrDeleteAlias
+SamrCreateAliasInDomain
+SamrCreateGroupInDomain
+SamrCreateUserInDomain
+SamrDeleteAlias
 SamrDeleteGroup
 SamrDeleteUser
 x SamrEnumerateAliasesInDomain
@@ -54,7 +54,7 @@ SamrLookupDomainInSamServer
 x SamrLookupNamesInDomain
 x SamrOpenAlias
 x SamrOpenDomain
-SamrOpenGroup
+SamrOpenGroup
 x SamrOpenUser
 x SamrQueryDisplayInformation
 x SamrQueryInformationAlias
@@ -65,10 +65,10 @@ SamrRemoveMemberFromAlias
 SamrRemoveMemberFromForiegnDomain
 SamrRemoveMemberFromGroup
 SamrRemoveMultipleMembersFromAlias
-SamrSetInformationAlias
+SamrSetInformationAlias
 SamrSetInformationDomain
-SamrSetInformationGroup
-SamrSetInformationUser
+SamrSetInformationGroup
+SamrSetInformationUser
 SamrSetMemberAttributesOfGroup
 SamrSetSecurityObject
 SamrShutdownSamServer
@@ -77,62 +77,30 @@ SamrTestPrivateFunctionsUser
 
 ********************************************************************/
 
-#define SAMR_CONNECT_ANON      0x00
 #define SAMR_CLOSE_HND         0x01
-
-#define SAMR_QUERY_SEC_OBJECT  0x03
-#define SAMR_LOOKUP_DOMAIN     0x05
 #define SAMR_OPEN_DOMAIN       0x07
-#define SAMR_ENUM_DOMAINS      0x06
-
 #define SAMR_QUERY_DOMAIN_INFO 0x08
-
-#define SAMR_CREATE_DOM_GROUP  0x0a
-#define SAMR_ENUM_DOM_GROUPS   0x0b
-#define SAMR_ENUM_DOM_USERS    0x0d
-#define SAMR_CREATE_DOM_ALIAS  0x0e
-#define SAMR_ENUM_DOM_ALIASES  0x0f
-#define SAMR_QUERY_USERALIASES 0x10
-
+#define SAMR_LOOKUP_IDS        0x10
 #define SAMR_LOOKUP_NAMES      0x11
-#define SAMR_LOOKUP_RIDS       0x12
-
-#define SAMR_OPEN_GROUP        0x13
-#define SAMR_QUERY_GROUPINFO   0x14
-#define SAMR_SET_GROUPINFO     0x15
-#define SAMR_ADD_GROUPMEM      0x16
-#define SAMR_DELETE_DOM_GROUP  0x17
-#define SAMR_DEL_GROUPMEM      0x18
-#define SAMR_QUERY_GROUPMEM    0x19
-
-#define SAMR_OPEN_ALIAS        0x1b
-#define SAMR_QUERY_ALIASINFO   0x1c
-#define SAMR_SET_ALIASINFO     0x1d
-#define SAMR_DELETE_DOM_ALIAS  0x1e
-#define SAMR_ADD_ALIASMEM      0x1f
-#define SAMR_DEL_ALIASMEM      0x20
-#define SAMR_QUERY_ALIASMEM    0x21
-
+#define SAMR_UNKNOWN_3         0x03
+#define SAMR_QUERY_DISPINFO    0x28
 #define SAMR_OPEN_USER         0x22
 #define SAMR_QUERY_USERINFO    0x24
-#define SAMR_SET_USERINFO2     0x25
 #define SAMR_QUERY_USERGROUPS  0x27
-#define SAMR_CREATE_USER       0x32
-#define SAMR_SET_USERINFO      0x3A
-
-#define SAMR_QUERY_DISPINFO    0x28
-
-#define SAMR_GET_USRDOM_PWINFO 0x2c
-#define SAMR_QUERY_DISPINFO3   0x30 /* Alias for SAMR_QUERY_DISPINFO
-                                      with info level 3 */
-#define SAMR_QUERY_DISPINFO4   0x33 /* Alias for SAMR_QUERY_DISPINFO
-                                      with info level 4 */
-#define SAMR_ADDMULTI_ALIASMEM 0x34
-
+#define SAMR_UNKNOWN_12        0x12
+#define SAMR_UNKNOWN_21        0x21
+#define SAMR_UNKNOWN_2C        0x2c
+#define SAMR_UNKNOWN_32        0x32
+#define SAMR_UNKNOWN_34        0x34
 #define SAMR_CHGPASSWD_USER    0x37
-#define SAMR_GET_DOM_PWINFO    0x38
-
+#define SAMR_UNKNOWN_38        0x38
 #define SAMR_CONNECT           0x39
+#define SAMR_CONNECT_ANON      0x00
+#define SAMR_OPEN_ALIAS        0x1b
+#define SAMR_QUERY_ALIASINFO   0x1c
+#define SAMR_ENUM_DOM_USERS    0x0d
+#define SAMR_ENUM_DOM_ALIASES  0x0f
+#define SAMR_ENUM_DOM_GROUPS   0x30
 
 
 typedef struct logon_hours_info
@@ -142,83 +110,6 @@ typedef struct logon_hours_info
 
 } LOGON_HRS;
 
-/* SAM_USER_INFO_16 */
-typedef struct sam_user_info_16
-{
-       uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
-
-} SAM_USER_INFO_16;
-
-/* SAM_USER_INFO_23 */
-typedef struct sam_user_info_23
-{
-       /* TIMES MAY NOT IN RIGHT ORDER!!!! */
-       NTTIME logon_time;            /* logon time */
-       NTTIME logoff_time;           /* logoff time */
-       NTTIME kickoff_time;          /* kickoff time */
-       NTTIME pass_last_set_time;    /* password last set time */
-       NTTIME pass_can_change_time;  /* password can change time */
-       NTTIME pass_must_change_time; /* password must change time */
-
-       UNIHDR hdr_user_name;    /* NULL - user name unicode string header */
-       UNIHDR hdr_full_name;    /* user's full name unicode string header */
-       UNIHDR hdr_home_dir;     /* home directory unicode string header */
-       UNIHDR hdr_dir_drive;    /* home drive unicode string header */
-       UNIHDR hdr_logon_script; /* logon script unicode string header */
-       UNIHDR hdr_profile_path; /* profile path unicode string header */
-       UNIHDR hdr_acct_desc  ;  /* user description */
-       UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */
-       UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */
-       UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
-
-       uint8 lm_pwd[16];    /* lm user passwords */
-       uint8 nt_pwd[16];    /* nt user passwords */
-
-       uint32 user_rid;      /* Primary User ID */
-       uint32 group_rid;     /* Primary Group ID */
-
-       uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
-       /* uint8 pad[2] */
-
-       uint32 unknown_3; /* 0x09f8 27fa */
-
-       uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
-       /* uint8 pad[2] */
-       uint32 ptr_logon_hrs; /* pointer to logon hours */
-
-       uint8 padding1[8];
-
-       uint32 unknown_5;     /* 0x0001 0000 */
-
-       uint8 pass[516];
-
-       UNISTR2 uni_user_name;    /* NULL - username unicode string */
-       UNISTR2 uni_full_name;    /* user's full name unicode string */
-       UNISTR2 uni_home_dir;     /* home directory unicode string */
-       UNISTR2 uni_dir_drive;    /* home directory drive unicode string */
-       UNISTR2 uni_logon_script; /* logon script unicode string */
-       UNISTR2 uni_profile_path; /* profile path unicode string */
-       UNISTR2 uni_acct_desc  ;  /* user description unicode string */
-       UNISTR2 uni_workstations; /* login from workstations unicode string */
-       UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
-       UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel number */
-
-       uint32 unknown_6; /* 0x0000 04ec */
-       uint32 padding4;
-
-       LOGON_HRS logon_hrs;
-
-} SAM_USER_INFO_23;
-
-/* SAM_USER_INFO_24 */
-typedef struct sam_user_info_24
-{
-       uint8 pass[516];
-       uint16 unk_0;
-
-} SAM_USER_INFO_24;
-
-
 /* SAM_USER_INFO_21 */
 typedef struct sam_user_info_21
 {
@@ -337,7 +228,7 @@ typedef struct q_samr_close_hnd_info
 /* SAMR_R_CLOSE_HND - probably a policy handle close */
 typedef struct r_samr_close_hnd_info
 {
-       POLICY_HND pol;       /* policy handle */
+    POLICY_HND pol;       /* policy handle */
        uint32 status;         /* return status */
 
 } SAMR_R_CLOSE_HND;
@@ -454,33 +345,11 @@ SAMR_Q_QUERY_DOMAIN_INFO - probably a query on domain group info.
 typedef struct q_samr_query_domain_info
 {
        POLICY_HND domain_pol;   /* policy handle */
-       uint16 switch_value;     /* 0x0002, 0x0001 */
+       uint16 switch_value;     /* 0x0002 */
 
 } SAMR_Q_QUERY_DOMAIN_INFO;
 
-typedef struct sam_unknown_info_3_info
-{
-       uint32 unknown_0; /* 0x0000 0000 */
-       uint32 unknown_1; /* 0x8000 0000 */
-
-} SAM_UNK_INFO_3;
-
-typedef struct sam_unknown_info_6_info
-{
-       uint32 unknown_0; /* 0x0000 0000 */
-
-       uint32 ptr_0;     /* pointer to unknown structure */
-       uint8  padding[12]; /* 12 bytes zeros */
-
-} SAM_UNK_INFO_6;
-
-typedef struct sam_unknown_info_7_info
-{
-       uint16 unknown_0; /* 0x0003 */
-
-} SAM_UNK_INFO_7;
-
-typedef struct sam_unknown_info_2_inf
+typedef struct sam_unkown_info_2_info
 {
        uint32 unknown_0; /* 0x0000 0000 */
        uint32 unknown_1; /* 0x8000 0000 */
@@ -511,24 +380,12 @@ typedef struct sam_unknown_info_2_inf
 
 } SAM_UNK_INFO_2;
 
-typedef struct sam_unknown_info_1_inf
-{
-       uint8 padding[12]; /* 12 bytes zeros */
-       uint32 unknown_1; /* 0x8000 0000 */
-       uint32 unknown_2; /* 0x0000 0000 */
-
-} SAM_UNK_INFO_1;
-
 
 typedef struct sam_unknown_ctr_info
 {
        union
        {
-               SAM_UNK_INFO_1 inf1;
                SAM_UNK_INFO_2 inf2;
-               SAM_UNK_INFO_3 inf3;
-               SAM_UNK_INFO_6 inf6;
-               SAM_UNK_INFO_7 inf7;
 
        } info;
 
@@ -548,28 +405,6 @@ typedef struct r_samr_query_domain_info
 } SAMR_R_QUERY_DOMAIN_INFO;
 
 
-/* SAMR_Q_LOOKUP_DOMAIN - obtain SID for a local domain */
-typedef struct q_samr_lookup_domain_info
-{
-       POLICY_HND connect_pol;
-
-       UNIHDR  hdr_domain;
-       UNISTR2 uni_domain;
-
-} SAMR_Q_LOOKUP_DOMAIN;
-
-
-/* SAMR_R_LOOKUP_DOMAIN */
-typedef struct r_samr_lookup_domain_info
-{
-       uint32   ptr_sid;
-       DOM_SID2 dom_sid;
-
-       uint32 status;
-
-} SAMR_R_LOOKUP_DOMAIN;
-
-
 /****************************************************************************
 SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs:
 
@@ -581,7 +416,7 @@ SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs:
 typedef struct q_samr_open_domain_info
 {
        POLICY_HND connect_pol;   /* policy handle */
-       uint32 flags;               /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - flags? */
+       uint32 rid;               /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - a RID? */
        DOM_SID2 dom_sid;         /* domain SID */
 
 } SAMR_Q_OPEN_DOMAIN;
@@ -595,6 +430,7 @@ typedef struct r_samr_open_domain_info
 
 } SAMR_R_OPEN_DOMAIN;
 
+
 #define MAX_SAM_ENTRIES 250
 
 typedef struct samr_entry_info
@@ -604,43 +440,13 @@ typedef struct samr_entry_info
 
 } SAM_ENTRY;
 
-
-/* SAMR_Q_ENUM_DOMAINS - SAM rids and names */
-typedef struct q_samr_enum_domains_info
-{
-       POLICY_HND pol;     /* policy handle */
-
-       uint32 start_idx;   /* enumeration handle */
-       uint32 max_size;    /* 0x0000 ffff */
-
-} SAMR_Q_ENUM_DOMAINS;
-
-/* SAMR_R_ENUM_DOMAINS - SAM rids and Domain names */
-typedef struct r_samr_enum_domains_info
-{
-       uint32 next_idx;     /* next starting index required for enum */
-       uint32 ptr_entries1;  
-
-       uint32 num_entries2;
-       uint32 ptr_entries2;
-
-       uint32 num_entries3;
-
-       SAM_ENTRY *sam;
-       UNISTR2 *uni_dom_name;
-
-       uint32 num_entries4;
-
-       uint32 status;
-
-} SAMR_R_ENUM_DOMAINS;
-
 /* SAMR_Q_ENUM_DOM_USERS - SAM rids and names */
 typedef struct q_samr_enum_dom_users_info
 {
        POLICY_HND pol;          /* policy handle */
 
-       uint32 start_idx;   /* number of values (0 indicates unlimited?) */
+       uint16 req_num_entries;   /* number of values (0 indicates unlimited?) */
+       uint16 unknown_0;         /* enumeration context? */
        uint16 acb_mask;          /* 0x0000 indicates all */
        uint16 unknown_1;         /* 0x0000 */
 
@@ -652,16 +458,17 @@ typedef struct q_samr_enum_dom_users_info
 /* SAMR_R_ENUM_DOM_USERS - SAM rids and names */
 typedef struct r_samr_enum_dom_users_info
 {
-       uint32 next_idx;     /* next starting index required for enum */
-       uint32 ptr_entries1;  
+       uint16 total_num_entries;  /* number of entries that match without the acb mask */
+       uint16 unknown_0;          /* same as unknown_0 (enum context?) in request */
+       uint32 ptr_entries1;       /* actual number of entries to follow, having masked some out */
 
        uint32 num_entries2;
        uint32 ptr_entries2;
 
        uint32 num_entries3;
 
-       SAM_ENTRY *sam;
-       UNISTR2 *uni_acct_name;
+       SAM_ENTRY sam[MAX_SAM_ENTRIES];
+       UNISTR2 uni_acct_name[MAX_SAM_ENTRIES];
 
        uint32 num_entries4;
 
@@ -670,15 +477,37 @@ typedef struct r_samr_enum_dom_users_info
 } SAMR_R_ENUM_DOM_USERS;
 
 
+typedef struct samr_entry_info3
+{
+       uint32 grp_idx;
+
+       uint32 rid_grp;
+       uint32 attr;
+
+       UNIHDR hdr_grp_name;
+       UNIHDR hdr_grp_desc;
+
+} SAM_ENTRY3;
+
+typedef struct samr_str_entry_info3
+{
+       UNISTR2 uni_grp_name;
+       UNISTR2 uni_grp_desc;
+
+} SAM_STR3;
+
 /* SAMR_Q_ENUM_DOM_GROUPS - SAM rids and names */
 typedef struct q_samr_enum_dom_groups_info
 {
        POLICY_HND pol;          /* policy handle */
 
-       /* this is possibly an enumeration context handle... */
-       uint32 start_idx;         /* 0x0000 0000 */
+       /* these are possibly an enumeration context handle... */
+       uint16 switch_level;      /* 0x0003 */
+       uint16 unknown_0;         /* 0x0000 */
+       uint32 start_idx;       /* presumably the start enumeration index */
+       uint32 unknown_1;       /* 0x0000 07d0 */
 
-       uint32 max_size;              /* 0x0000 ffff */
+       uint32 max_size;        /* 0x0000 7fff */
 
 } SAMR_Q_ENUM_DOM_GROUPS;
 
@@ -686,50 +515,49 @@ typedef struct q_samr_enum_dom_groups_info
 /* SAMR_R_ENUM_DOM_GROUPS - SAM rids and names */
 typedef struct r_samr_enum_dom_groups_info
 {
-       uint32 next_idx;
-       uint32 ptr_entries1;
-
-       uint32 num_entries2;
-       uint32 ptr_entries2;
+       uint32 unknown_0;        /* 0x0000 0492 or 0x0000 00be */
+       uint32 unknown_1;        /* 0x0000 049a or 0x0000 00be */
+       uint32 switch_level;     /* 0x0000 0003 */
 
-       uint32 num_entries3;
+       uint32 num_entries;
+       uint32 ptr_entries;
 
-       SAM_ENTRY *sam;
-       UNISTR2 *uni_grp_name;
+       uint32 num_entries2;
 
-       uint32 num_entries4;
+       SAM_ENTRY3 sam[MAX_SAM_ENTRIES];
+       SAM_STR3   str[MAX_SAM_ENTRIES];
 
        uint32 status;
 
 } SAMR_R_ENUM_DOM_GROUPS;
 
 
+
 /* SAMR_Q_ENUM_DOM_ALIASES - SAM rids and names */
 typedef struct q_samr_enum_dom_aliases_info
 {
        POLICY_HND pol;          /* policy handle */
 
        /* this is possibly an enumeration context handle... */
-       uint32 start_idx;         /* 0x0000 0000 */
+       uint32 unknown_0;         /* 0x0000 0000 */
 
        uint32 max_size;              /* 0x0000 ffff */
 
 } SAMR_Q_ENUM_DOM_ALIASES;
 
-
 /* SAMR_R_ENUM_DOM_ALIASES - SAM rids and names */
 typedef struct r_samr_enum_dom_aliases_info
 {
-       uint32 next_idx;
-       uint32 ptr_entries1;
+       uint32 num_entries;
+       uint32 ptr_entries;
 
        uint32 num_entries2;
        uint32 ptr_entries2;
 
        uint32 num_entries3;
 
-       SAM_ENTRY *sam;
-       UNISTR2 *uni_grp_name;
+       SAM_ENTRY sam[MAX_SAM_ENTRIES];
+       UNISTR2 uni_grp_name[MAX_SAM_ENTRIES];
 
        uint32 num_entries4;
 
@@ -738,7 +566,20 @@ typedef struct r_samr_enum_dom_aliases_info
 } SAMR_R_ENUM_DOM_ALIASES;
 
 
-/* -- Level 1 Display Info - User Information -- */
+
+/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */
+typedef struct q_samr_query_disp_info
+{
+       POLICY_HND pol;        /* policy handle */
+
+       uint16 switch_level;    /* 0x0001 and 0x0002 seen */
+       uint16 unknown_0;       /* 0x0000 and 0x2000 seen */
+       uint32 start_idx;       /* presumably the start enumeration index */
+       uint32 unknown_1;       /* 0x0000 07d0, 0x0000 0400 and 0x0000 0200 seen */
+
+       uint32 max_size;        /* 0x0000 7fff, 0x0000 7ffe and 0x0000 3fff seen*/
+
+} SAMR_Q_QUERY_DISPINFO;
 
 typedef struct samr_entry_info1
 {
@@ -764,13 +605,15 @@ typedef struct samr_str_entry_info1
 
 typedef struct sam_entry_info_1
 {
+       uint32 num_entries;
+       uint32 ptr_entries;
+       uint32 num_entries2;
+
        SAM_ENTRY1 sam[MAX_SAM_ENTRIES];
        SAM_STR1   str[MAX_SAM_ENTRIES];
 
-} SAM_DISPINFO_1;
-
 
-/* -- Level 2 Display Info - Trust Account Information -- */
+} SAM_INFO_1;
 
 typedef struct samr_entry_info2
 {
@@ -794,295 +637,45 @@ typedef struct samr_str_entry_info2
 
 typedef struct sam_entry_info_2
 {
+       uint32 num_entries;
+       uint32 ptr_entries;
+       uint32 num_entries2;
+
        SAM_ENTRY2 sam[MAX_SAM_ENTRIES];
        SAM_STR2   str[MAX_SAM_ENTRIES];
 
-} SAM_DISPINFO_2;
-
-
-/* -- Level 3 Display Info - Domain Group Information -- */
-
-typedef struct samr_entry_info3
-{
-       uint32 grp_idx;
-
-       uint32 rid_grp;
-       uint32 attr;     /* SE_GROUP_xxx, usually 7 */
-
-       UNIHDR hdr_grp_name;
-       UNIHDR hdr_grp_desc;
-
-} SAM_ENTRY3;
-
-typedef struct samr_str_entry_info3
-{
-       UNISTR2 uni_grp_name;
-       UNISTR2 uni_grp_desc;
-
-} SAM_STR3;
-
-typedef struct sam_entry_info_3
-{
-       SAM_ENTRY3 sam[MAX_SAM_ENTRIES];
-       SAM_STR3   str[MAX_SAM_ENTRIES];
-
-} SAM_DISPINFO_3;
-
-
-/* -- Level 4 Display Info - User List (ASCII) -- */
-
-typedef struct samr_entry_info4
-{
-       uint32 user_idx;
-       STRHDR hdr_acct_name;
-
-} SAM_ENTRY4;
-
-typedef struct samr_str_entry_info4
-{
-       STRING2 acct_name;
-
-} SAM_STR4;
-
-typedef struct sam_entry_info_4
-{
-       SAM_ENTRY4 sam[MAX_SAM_ENTRIES];
-       SAM_STR4   str[MAX_SAM_ENTRIES];
-
-} SAM_DISPINFO_4;
-
-
-/* -- Level 5 Display Info - Group List (ASCII) -- */
-
-typedef struct samr_entry_info5
-{
-       uint32 grp_idx;
-       STRHDR hdr_grp_name;
-
-} SAM_ENTRY5;
-
-typedef struct samr_str_entry_info5
-{
-       STRING2 grp_name;
-
-} SAM_STR5;
+} SAM_INFO_2;
 
-typedef struct sam_entry_info_5
-{
-       SAM_ENTRY5 sam[MAX_SAM_ENTRIES];
-       SAM_STR5   str[MAX_SAM_ENTRIES];
-
-} SAM_DISPINFO_5;
-
-
-typedef struct sam_dispinfo_ctr_info
+typedef struct sam_info_ctr_info
 {
        union
        {
-               SAM_DISPINFO_1 *info1; /* users/names/descriptions */
-               SAM_DISPINFO_2 *info2; /* trust accounts */
-               SAM_DISPINFO_3 *info3; /* domain groups/descriptions */
-               SAM_DISPINFO_4 *info4; /* user list (ASCII) - used by Win95 */
-               SAM_DISPINFO_5 *info5; /* group list (ASCII) */
+               SAM_INFO_1 *info1; /* server info */
+               SAM_INFO_2 *info2; /* user info */
                void       *info; /* allows assignment without typecasting, */
 
        } sam;
 
-} SAM_DISPINFO_CTR;
+} SAM_INFO_CTR;
 
-
-/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */
-typedef struct q_samr_query_disp_info
-{
-       POLICY_HND domain_pol;
-
-       uint16 switch_level;    /* see SAM_DISPINFO_CTR above */
-       /* align */
-
-       uint32 start_idx;       /* start enumeration index */
-       uint32 max_entries;     /* maximum number of entries to return */
-       uint32 max_size;        /* recommended data size; if exceeded server
-                                  should return STATUS_MORE_ENTRIES */
-
-} SAMR_Q_QUERY_DISPINFO;
-
-
-/* SAMR_R_QUERY_DISPINFO  */
+/* SAMR_R_QUERY_DISPINFO - SAM rids, names and descriptions */
 typedef struct r_samr_query_dispinfo_info
 {
-       uint32 total_size;     /* total data size for all matching entries
-                                 (0 = uncalculated) */
-       uint32 data_size;      /* actual data size returned = size of SAM_ENTRY
-                                 structures + total length of strings */
-
-       uint16 switch_level;   /* see SAM_DISPINFO_CTR above */
-       /* align */
+       uint32 unknown_0;        /* container length? 0x0000 0492 or 0x0000 00be */
+       uint32 unknown_1;        /* container length? 0x0000 049a or 0x0000 00be */
+       uint16 switch_level;     /* 0x0001 or 0x0002 */
+       /*uint8 pad[2] */
 
-       uint32 num_entries;    /* number of entries returned */
-       uint32 ptr_entries;
-       uint32 num_entries2;
-
-       SAM_DISPINFO_CTR *ctr;
+       SAM_INFO_CTR *ctr;
 
        uint32 status;
 
 } SAMR_R_QUERY_DISPINFO;
 
 
-/* SAMR_Q_DELETE_DOM_GROUP - delete domain group */
-typedef struct q_samr_delete_dom_group_info
-{
-    POLICY_HND group_pol;          /* policy handle */
-
-} SAMR_Q_DELETE_DOM_GROUP;
-
-
-/* SAMR_R_DELETE_DOM_GROUP - delete domain group */
-typedef struct r_samr_delete_dom_group_info
-{
-       POLICY_HND pol;       /* policy handle */
-       uint32 status;        /* return status */
-
-} SAMR_R_DELETE_DOM_GROUP;
-
-
-/* SAMR_Q_CREATE_DOM_GROUP - SAM create group */
-typedef struct q_samr_create_dom_group_info
-{
-       POLICY_HND pol;        /* policy handle */
-
-       UNIHDR hdr_acct_desc;
-       UNISTR2 uni_acct_desc;
-
-       uint16 unknown_1;    /* 0x0002 */
-       uint16 unknown_2;    /* 0x0001 */
-
-} SAMR_Q_CREATE_DOM_GROUP;
-
-/* SAMR_R_CREATE_DOM_GROUP - SAM create group */
-typedef struct r_samr_create_dom_group_info
-{
-       POLICY_HND pol;        /* policy handle */
-
-       uint32 rid;    
-       uint32 status;    
-
-} SAMR_R_CREATE_DOM_GROUP;
-
-/* SAMR_Q_QUERY_GROUPINFO - SAM Group Info */
-typedef struct q_samr_query_group_info
-{
-       POLICY_HND pol;        /* policy handle */
-
-       uint16 switch_level;    /* 0x0001 seen */
-
-} SAMR_Q_QUERY_GROUPINFO;
-
-typedef struct samr_group_info1
-{
-       UNIHDR hdr_acct_name;
-
-       uint32 unknown_1; /* 0x0000 0003 - number of group members? */
-       uint32 num_members; /* 0x0000 0001 - number of group members? */
-
-       UNIHDR hdr_acct_desc;
-
-       UNISTR2 uni_acct_name;
-       UNISTR2 uni_acct_desc;
-
-} GROUP_INFO1;
-
-typedef struct samr_group_info4
-{
-       UNIHDR hdr_acct_desc;
-       UNISTR2 uni_acct_desc;
-
-} GROUP_INFO4;
-
-/* GROUP_INFO_CTR */
-typedef struct group_info_ctr
-{
-       uint16 switch_value1;
-       uint16 switch_value2;
-
-       union
-       {
-               GROUP_INFO4 info4;
-               GROUP_INFO1 info1;
-
-       } group;
-
-} GROUP_INFO_CTR;
-
-/* SAMR_R_QUERY_GROUPINFO - SAM Group Info */
-typedef struct r_samr_query_groupinfo_info
-{
-       uint32 ptr;        
-       GROUP_INFO_CTR *ctr;
-
-       uint32 status;
-
-} SAMR_R_QUERY_GROUPINFO;
-
-
-/* SAMR_Q_SET_GROUPINFO - SAM Group Info */
-typedef struct q_samr_set_group_info
-{
-       POLICY_HND pol;        /* policy handle */
-       GROUP_INFO_CTR *ctr;
-
-} SAMR_Q_SET_GROUPINFO;
-
-/* SAMR_R_SET_GROUPINFO - SAM Group Info */
-typedef struct r_samr_set_group_info
-{
-       uint32 status;
-
-} SAMR_R_SET_GROUPINFO;
-
-
-/* SAMR_Q_DELETE_DOM_ALIAS - delete domain alias */
-typedef struct q_samr_delete_dom_alias_info
-{
-    POLICY_HND alias_pol;          /* policy handle */
-
-} SAMR_Q_DELETE_DOM_ALIAS;
-
-
-/* SAMR_R_DELETE_DOM_ALIAS - delete domain alias */
-typedef struct r_samr_delete_dom_alias_info
-{
-       POLICY_HND pol;       /* policy handle */
-       uint32 status;        /* return status */
-
-} SAMR_R_DELETE_DOM_ALIAS;
-
-
-/* SAMR_Q_CREATE_DOM_ALIAS - SAM create alias */
-typedef struct q_samr_create_dom_alias_info
-{
-       POLICY_HND dom_pol;        /* policy handle */
-
-       UNIHDR hdr_acct_desc;
-       UNISTR2 uni_acct_desc;
-
-       uint16 unknown_1;    /* 0x001f */
-       uint16 unknown_2;    /* 0x000f */
-
-} SAMR_Q_CREATE_DOM_ALIAS;
-
-/* SAMR_R_CREATE_DOM_ALIAS - SAM create alias */
-typedef struct r_samr_create_dom_alias_info
-{
-       POLICY_HND alias_pol;        /* policy handle */
-
-       uint32 rid;    
-       uint32 status;    
-
-} SAMR_R_CREATE_DOM_ALIAS;
 
 /* SAMR_Q_QUERY_ALIASINFO - SAM Alias Info */
-typedef struct q_samr_query_alias_info
+typedef struct q_samr_enum_alias_info
 {
        POLICY_HND pol;        /* policy handle */
 
@@ -1097,11 +690,12 @@ typedef struct samr_alias_info3
 
 } ALIAS_INFO3;
 
-/* ALIAS_INFO_CTR */
-typedef struct alias_info_ctr
+/* SAMR_R_QUERY_ALIASINFO - SAM rids, names and descriptions */
+typedef struct r_samr_query_aliasinfo_info
 {
-       uint16 switch_value1;
-       uint16 switch_value2;
+       uint32 ptr;        
+       uint16 switch_value;     /* 0x0003 */
+       /* uint8[2] padding */
 
        union
        {
@@ -1109,35 +703,11 @@ typedef struct alias_info_ctr
 
        } alias;
 
-} ALIAS_INFO_CTR;
-
-/* SAMR_R_QUERY_ALIASINFO - SAM alias info */
-typedef struct r_samr_query_aliasinfo_info
-{
-       uint32 ptr;        
-       ALIAS_INFO_CTR *ctr;
-
        uint32 status;
 
 } SAMR_R_QUERY_ALIASINFO;
 
 
-/* SAMR_Q_SET_ALIASINFO - SAM Alias Info */
-typedef struct q_samr_set_alias_info
-{
-       POLICY_HND alias_pol;        /* policy handle */
-       ALIAS_INFO_CTR *ctr;
-
-} SAMR_Q_SET_ALIASINFO;
-
-/* SAMR_R_SET_ALIASINFO - SAM alias info */
-typedef struct r_samr_set_aliasinfo_info
-{
-       uint32 status;
-
-} SAMR_R_SET_ALIASINFO;
-
-
 /* SAMR_Q_QUERY_USERGROUPS - */
 typedef struct q_samr_query_usergroup_info
 {
@@ -1160,54 +730,6 @@ typedef struct r_samr_query_usergroup_info
 } SAMR_R_QUERY_USERGROUPS;
 
 
-/* SAMR_Q_SET_USERINFO2 - set sam info */
-typedef struct q_samr_set_user_info2
-{
-       POLICY_HND pol;          /* policy handle associated with user */
-       uint16 switch_value;      /* 0x0010 */
-       uint16 switch_value2;      /* 0x0010 */
-
-       union
-       {
-               SAM_USER_INFO_16 *id16; /* auth-level 0x10 */
-               void* id; /* to make typecasting easy */
-
-       } info;
-
-} SAMR_Q_SET_USERINFO2;
-
-/* SAMR_R_SET_USERINFO2 - set sam info */
-typedef struct r_samr_set_user_info2
-{
-       uint32 status;         /* return status */
-
-} SAMR_R_SET_USERINFO2;
-
-/* SAMR_Q_SET_USERINFO - set sam info */
-typedef struct q_samr_set_user_info
-{
-       POLICY_HND pol;          /* policy handle associated with user */
-       uint16 switch_value;      /* 0x0017 */
-       uint16 switch_value2;      /* 0x0017 */
-
-       union
-       {
-               SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
-               SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
-               void* id; /* to make typecasting easy */
-
-       } info;
-
-} SAMR_Q_SET_USERINFO;
-
-/* SAMR_R_SET_USERINFO - set sam info */
-typedef struct r_samr_set_user_info
-{
-       uint32 status;         /* return status */
-
-} SAMR_R_SET_USERINFO;
-
-
 /* SAMR_Q_QUERY_USERINFO - probably a get sam info */
 typedef struct q_samr_query_user_info
 {
@@ -1228,8 +750,6 @@ typedef struct r_samr_query_user_info
                SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
                SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
                SAM_USER_INFO_21 *id21; /* auth-level 21 */
-               SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
-               SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
                void* id; /* to make typecasting easy */
 
        } info;
@@ -1240,40 +760,39 @@ typedef struct r_samr_query_user_info
 
 
 /****************************************************************************
-SAMR_Q_QUERY_USERALIASES - do a conversion from name to RID.
+SAMR_Q_LOOKUP_IDS - do a conversion from name to RID.
 
 the policy handle allocated by an "samr open secret" call is associated
 with a SID.  this policy handle is what is queried here, *not* the SID
 itself.  the response to the lookup rids is relative to this SID.
 *****************************************************************************/
-/* SAMR_Q_QUERY_USERALIASES */
-typedef struct q_samr_query_useraliases_info
+/* SAMR_Q_LOOKUP_IDS */
+typedef struct q_samr_lookup_ids_info
 {
-       POLICY_HND pol;       /* policy handle */
+    POLICY_HND pol;       /* policy handle */
 
        uint32 num_sids1;      /* number of rids being looked up */
        uint32 ptr;            /* buffer pointer */
        uint32 num_sids2;      /* number of rids being looked up */
 
-       uint32   *ptr_sid; /* pointers to sids to be looked up */
-       DOM_SID2 *sid    ; /* sids to be looked up. */
+       uint32   ptr_sid[MAX_LOOKUP_SIDS]; /* pointers to sids to be looked up */
+       DOM_SID2 sid    [MAX_LOOKUP_SIDS]; /* sids to be looked up. */
 
-} SAMR_Q_QUERY_USERALIASES;
+} SAMR_Q_LOOKUP_IDS;
 
 
-/* SAMR_R_QUERY_USERALIASES */
-typedef struct r_samr_query_useraliases_info
+/* SAMR_R_LOOKUP_IDS */
+typedef struct r_samr_lookup_ids_info
 {
        uint32 num_entries;
        uint32 ptr; /* undocumented buffer pointer */
 
        uint32 num_entries2; 
-       uint32 *rid; /* domain RIDs being looked up */
+       uint32 rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
 
        uint32 status; /* return code */
 
-} SAMR_R_QUERY_USERALIASES;
-
+} SAMR_R_LOOKUP_IDS;
 
 /****************************************************************************
 SAMR_Q_LOOKUP_NAMES - do a conversion from Names to RIDs+types.
@@ -1281,7 +800,7 @@ SAMR_Q_LOOKUP_NAMES - do a conversion from Names to RIDs+types.
 /* SAMR_Q_LOOKUP_NAMES */
 typedef struct q_samr_lookup_names_info
 {
-    POLICY_HND pol;       /* policy handle */
+       POLICY_HND pol;       /* policy handle */
 
        uint32 num_names1;      /* number of names being looked up */
        uint32 flags;           /* 0x0000 03e8 - unknown */
@@ -1293,7 +812,6 @@ typedef struct q_samr_lookup_names_info
 
 } SAMR_Q_LOOKUP_NAMES;
 
-
 /* SAMR_R_LOOKUP_NAMES */
 typedef struct r_samr_lookup_names_info
 {
@@ -1313,56 +831,57 @@ typedef struct r_samr_lookup_names_info
 
 } SAMR_R_LOOKUP_NAMES;
 
-
 /****************************************************************************
-SAMR_Q_LOOKUP_RIDS - do a conversion from RID groups to something.
+SAMR_Q_UNKNOWN_12 - do a conversion from RID groups to something.
 
 called to resolve domain RID groups.
 *****************************************************************************/
-/* SAMR_Q_LOOKUP_RIDS */
-typedef struct q_samr_lookup_rids_info
+/* SAMR_Q_UNKNOWN_12 */
+typedef struct q_samr_unknown_12_info
 {
-       POLICY_HND pol;       /* policy handle */
+    POLICY_HND pol;       /* policy handle */
 
-       uint32 num_rids1;      /* number of rids being looked up */
-       uint32 flags;          /* 0x0000 03e8 - unknown */
+       uint32 num_gids1;      /* number of rids being looked up */
+       uint32 rid;            /* 0x0000 03e8 - RID of the server doing the query? */
        uint32 ptr;            /* 0x0000 0000 - 32 bit unknown */
-       uint32 num_rids2;      /* number of rids being looked up */
+       uint32 num_gids2;      /* number of rids being looked up */
 
-       uint32 *rid; /* domain RIDs being looked up */
+       uint32 gid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
 
-} SAMR_Q_LOOKUP_RIDS;
+} SAMR_Q_UNKNOWN_12;
 
 
 /****************************************************************************
-SAMR_R_LOOKUP_RIDS - do a conversion from group RID to names
+SAMR_R_UNKNOWN_12 - do a conversion from group RID to names
 
 *****************************************************************************/
-/* SAMR_R_LOOKUP_RIDS */
-typedef struct r_samr_lookup_rids_info
+/* SAMR_R_UNKNOWN_12 */
+typedef struct r_samr_unknown_12_info
 {
-       uint32 num_names1;      /* number of aliases being looked up */
-       uint32 ptr_names;       /* pointer to aliases */
-       uint32 num_names2;      /* number of aliases being looked up */
+    POLICY_HND pol;       /* policy handle */
 
-       UNIHDR  *hdr_name; /* unicode account name header */
-       UNISTR2 *uni_name; /* unicode account name string */
+       uint32 num_aliases1;      /* number of aliases being looked up */
+       uint32 ptr_aliases;       /* pointer to aliases */
+       uint32 num_aliases2;      /* number of aliases being looked up */
 
-       uint32 num_types1;      /* number of users in aliases being looked up */
-       uint32 ptr_types;       /* pointer to users in aliases */
-       uint32 num_types2;      /* number of users in aliases being looked up */
+       UNIHDR  hdr_als_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
+       UNISTR2 uni_als_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
+
+       uint32 num_als_usrs1;      /* number of users in aliases being looked up */
+       uint32 ptr_als_usrs;       /* pointer to users in aliases */
+       uint32 num_als_usrs2;      /* number of users in aliases being looked up */
 
-       uint32 *type; /* SID_ENUM type */
+       uint32 num_als_usrs[MAX_LOOKUP_SIDS]; /* number of users per group */
 
        uint32 status;
 
-} SAMR_R_LOOKUP_RIDS;
+} SAMR_R_UNKNOWN_12;
 
 
 /* SAMR_Q_OPEN_USER - probably an open */
 typedef struct q_samr_open_user_info
 {
-       POLICY_HND domain_pol;       /* policy handle */
+    POLICY_HND domain_pol;       /* policy handle */
        uint32 unknown_0;     /* 32 bit unknown - 0x02011b */
        uint32 user_rid;      /* user RID */
 
@@ -1372,187 +891,64 @@ typedef struct q_samr_open_user_info
 /* SAMR_R_OPEN_USER - probably an open */
 typedef struct r_samr_open_user_info
 {
-       POLICY_HND user_pol;       /* policy handle associated with unknown id */
+    POLICY_HND user_pol;       /* policy handle associated with unknown id */
        uint32 status;         /* return status */
 
 } SAMR_R_OPEN_USER;
 
 
-/* SAMR_Q_CREATE_USER - probably a create */
-typedef struct q_samr_create_user_info
+/* SAMR_Q_UNKNOWN_13 - probably an open alias in domain */
+typedef struct q_samr_unknown_13_info
 {
-       POLICY_HND domain_pol;       /* policy handle */
+    POLICY_HND alias_pol;        /* policy handle */
 
-       UNIHDR  hdr_name;       /* unicode account name header */
-       UNISTR2 uni_name;       /* unicode account name */
+       uint16 unknown_1;            /* 16 bit unknown - 0x0200 */
+       uint16 unknown_2;            /* 16 bit unknown - 0x0000 */
 
-       uint16 acb_info;      /* account control info */
-       uint32 unknown_1;     /* 0xe005 00b0 */
+} SAMR_Q_UNKNOWN_13;
 
-} SAMR_Q_CREATE_USER;
 
-
-/* SAMR_R_CREATE_USER - probably a create */
-typedef struct r_samr_create_user_info
+/* SAMR_Q_UNKNOWN_21 - probably an open group in domain */
+typedef struct q_samr_unknown_21_info
 {
-       POLICY_HND user_pol;       /* policy handle associated with user */
+    POLICY_HND group_pol;        /* policy handle */
 
-       uint32 unknown_0;     /* 0x0007 03ff */
-       uint32 user_rid;      /* user RID */
-       uint32 status;         /* return status */
-
-} SAMR_R_CREATE_USER;
+       uint16 unknown_1;            /* 16 bit unknown - 0x0477 */
+       uint16 unknown_2;            /* 16 bit unknown - 0x0000 */
 
+} SAMR_Q_UNKNOWN_21;
 
 
-/* SAMR_Q_QUERY_GROUPMEM - query group members */
-typedef struct q_samr_query_groupmem_info
+/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */
+typedef struct q_samr_unknown_32_info
 {
-       POLICY_HND group_pol;        /* policy handle */
-
-} SAMR_Q_QUERY_GROUPMEM;
+    POLICY_HND pol;             /* policy handle */
 
+       UNIHDR  hdr_mach_acct;       /* unicode machine account name header */
+       UNISTR2 uni_mach_acct;       /* unicode machine account name */
 
-/* SAMR_R_QUERY_GROUPMEM - query group members */
-typedef struct r_samr_query_groupmem_info
-{
-       uint32 ptr;
-       uint32 num_entries;
-
-       uint32 ptr_rids;
-       uint32 ptr_attrs;
-
-       uint32 num_rids;
-       uint32 *rid;
-
-       uint32 num_attrs;
-       uint32 *attr;
-
-       uint32 status;
-
-} SAMR_R_QUERY_GROUPMEM;
-
-
-/* SAMR_Q_DEL_GROUPMEM - probably an del group member */
-typedef struct q_samr_del_group_mem_info
-{
-       POLICY_HND pol;       /* policy handle */
-
-       uint32 rid;         /* rid */
+       uint32 acct_ctrl;            /* 32 bit ACB_XXXX */
+       uint16 unknown_1;            /* 16 bit unknown - 0x00B0 */
+       uint16 unknown_2;            /* 16 bit unknown - 0xe005 */
 
-} SAMR_Q_DEL_GROUPMEM;
+} SAMR_Q_UNKNOWN_32;
 
 
-/* SAMR_R_DEL_GROUPMEM - probably an del group member */
-typedef struct r_samr_del_group_mem_info
+/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */
+typedef struct r_samr_unknown_32_info
 {
-       uint32 status;         /* return status */
-
-} SAMR_R_DEL_GROUPMEM;
-
-
-/* SAMR_Q_ADD_GROUPMEM - probably an add group member */
-typedef struct q_samr_add_group_mem_info
-{
-       POLICY_HND pol;       /* policy handle */
-
-       uint32 rid;         /* rid */
-       uint32 unknown;     /* 0x0000 0005 */
-
-} SAMR_Q_ADD_GROUPMEM;
-
-
-/* SAMR_R_ADD_GROUPMEM - probably an add group member */
-typedef struct r_samr_add_group_mem_info
-{
-       uint32 status;         /* return status */
-
-} SAMR_R_ADD_GROUPMEM;
-
-
-/* SAMR_Q_OPEN_GROUP - probably an open */
-typedef struct q_samr_open_group_info
-{
-       POLICY_HND domain_pol;       /* policy handle */
-       uint32 unknown;         /* 0x0000 0001, 0x0000 0003, 0x0000 001f */
-       uint32 rid_group;        /* rid */
-
-} SAMR_Q_OPEN_GROUP;
-
-
-/* SAMR_R_OPEN_GROUP - probably an open */
-typedef struct r_samr_open_group_info
-{
-       POLICY_HND pol;       /* policy handle */
-       uint32 status;         /* return status */
-
-} SAMR_R_OPEN_GROUP;
-
-
-/* SAMR_Q_QUERY_ALIASMEM - query alias members */
-typedef struct q_samr_query_aliasmem_info
-{
-       POLICY_HND alias_pol;        /* policy handle */
-
-} SAMR_Q_QUERY_ALIASMEM;
-
-
-/* SAMR_R_QUERY_ALIASMEM - query alias members */
-typedef struct r_samr_query_aliasmem_info
-{
-       uint32 num_sids;
-       uint32 ptr;
-       uint32 num_sids1;
-
-       DOM_SID2 *sid;
-
-       uint32 status;
-
-} SAMR_R_QUERY_ALIASMEM;
-
-
-/* SAMR_Q_ADD_ALIASMEM - add alias member */
-typedef struct q_samr_add_alias_mem_info
-{
-       POLICY_HND alias_pol;       /* policy handle */
-
-       DOM_SID2 sid; /* member sid to be added to the alias */
-
-} SAMR_Q_ADD_ALIASMEM;
-
-
-/* SAMR_R_ADD_ALIASMEM - add alias member */
-typedef struct r_samr_add_alias_mem_info
-{
-       uint32 status;         /* return status */
-
-} SAMR_R_ADD_ALIASMEM;
-
-
-/* SAMR_Q_DEL_ALIASMEM - add an add alias member */
-typedef struct q_samr_del_alias_mem_info
-{
-       POLICY_HND alias_pol;       /* policy handle */
-
-       DOM_SID2 sid; /* member sid to be added to alias */
-
-} SAMR_Q_DEL_ALIASMEM;
-
-
-/* SAMR_R_DEL_ALIASMEM - delete alias member */
-typedef struct r_samr_del_alias_mem_info
-{
-       uint32 status;         /* return status */
+    POLICY_HND pol;       /* policy handle */
 
-} SAMR_R_DEL_ALIASMEM;
+       /* rid4.unknown - fail: 0030 success: 0x03ff */
+       DOM_RID4 rid4;         /* rid and attributes */
 
+       uint32 status;         /* return status - fail: 0xC000 0099: user exists */
 
+} SAMR_R_UNKNOWN_32;
 
 /* SAMR_Q_OPEN_ALIAS - probably an open */
 typedef struct q_samr_open_alias_info
 {
-       POLICY_HND dom_pol;
-
        uint32 unknown_0;         /* 0x0000 0008 */
        uint32 rid_alias;        /* rid */
 
@@ -1621,6 +1017,7 @@ typedef struct r_samr_unknown_38
        uint16 unk_1;
        uint16 unk_2;
        uint16 unk_3;
+       uint32 status;         /* return status */
 
 } SAMR_R_UNKNOWN_38;
 
index 8a86fc98330873eee4366fdadde4e18ae41044c9..f497c25db6497d39089c32ef6a63090073f108b1 100644 (file)
@@ -88,21 +88,16 @@ typedef struct security_ace_info
 
 } SEC_ACE;
 
-
-#define MAX_SEC_ACES 16
-
 /* SEC_ACL */
 typedef struct security_acl_info
 {
        uint16 revision; /* 0x0002 */
        uint16 size; /* size in bytes of the entire ACL structure */
        uint32 num_aces; /* number of Access Control Entries */
-
-       SEC_ACE *ace;
+       SEC_ACE *ace_list;
 
 } SEC_ACL;
 
-
 /* SEC_DESC */
 typedef struct security_descriptor_info
 {
index 25be11d1997bce92236de1512bcb380b6cdd4f8d..78949a7a7d99a56b4992508541c725f48c618c89 100644 (file)
 
 
 /* srvsvc pipe */
-#define SRV_NETCONNENUM      0x08
-#define SRV_NETFILEENUM      0x09
-#define SRV_NETSESSENUM      0x0c
-#define SRV_NETSHAREENUM     0x0f
-#define SRV_NETTRANSPORTENUM 0x1a
-#define SRV_NET_SRV_GET_INFO 0x15
-#define SRV_NET_SRV_SET_INFO 0x16
-#define        SRV_NET_REMOTE_TOD   0x1c
+#define SRV_NETCONNENUM        0x08
+#define SRV_NETFILEENUM        0x09
+#define SRV_NETSESSENUM        0x0c
+#define SRV_NETSHAREENUM       0x0f
+#define SRV_NET_SHARE_GET_INFO 0x10
+#define SRV_NET_SRV_GET_INFO   0x15
+#define SRV_NET_SRV_SET_INFO   0x16
+#define SRV_NET_REMOTE_TOD     0x1c
 
 /* SESS_INFO_0 (pointers to level 0 session info strings) */
 typedef struct ptr_sess_info0
@@ -104,11 +104,11 @@ typedef struct srv_sess_info_ctr_info
        uint32 switch_value;         /* switch value */
        uint32 ptr_sess_ctr;       /* pointer to sess info union */
        union
-       {
+    {
                SRV_SESS_INFO_0 info0; /* session info level 0 */
                SRV_SESS_INFO_1 info1; /* session info level 1 */
 
-       } sess;
+    } sess;
 
 } SRV_SESS_INFO_CTR;
 
@@ -122,9 +122,6 @@ typedef struct q_net_sess_enum_info
        uint32 ptr_qual_name;         /* pointer (to qualifier name) */
        UNISTR2 uni_qual_name;        /* qualifier name "\\qualifier" */
 
-       uint32 ptr_user_name;         /* pointer (to user name) */
-       UNISTR2 uni_user_name;        /* user name */
-
        uint32 sess_level;          /* session level */
 
        SRV_SESS_INFO_CTR *ctr;
@@ -210,11 +207,11 @@ typedef struct srv_conn_info_ctr_info
        uint32 switch_value;         /* switch value */
        uint32 ptr_conn_ctr;       /* pointer to conn info union */
        union
-       {
+    {
                SRV_CONN_INFO_0 info0; /* connection info level 0 */
                SRV_CONN_INFO_1 info1; /* connection info level 1 */
 
-       } conn;
+    } conn;
 
 } SRV_CONN_INFO_CTR;
 
@@ -251,89 +248,6 @@ typedef struct r_net_conn_enum_info
 
 } SRV_R_NET_CONN_ENUM;
 
-/* oops - this is going to take up a *massive* amount of stack. */
-/* the UNISTR2s already have 1024 uint16 chars in them... */
-#define MAX_TPRT_ENTRIES 32
-
-/* TPRT_INFO_0 (pointers to level 0 transport info strings) */
-typedef struct ptr_tprt_info0
-{
-       uint32 num_vcs;   /* number of clients using transport */
-       uint32 ptr_trans_name; /* pointer to transport name. */
-       uint32 ptr_trans_addr; /* pointer to transport address */
-       uint32 trans_addr_len; /* length of transport address */
-       uint32 ptr_addr_name; /* pointer to network address name. */
-
-} TPRT_INFO_0;
-
-/* TPRT_INFO_0_STR (level 0 transport info strings) */
-typedef struct str_tprt_info0
-{
-       UNISTR2 uni_trans_name; /* unicode string of transport */
-       BUFFER4 buf_trans_addr; /* buffer for transport address */
-       UNISTR2 uni_addr_name; /* unicode string of network address */
-
-} TPRT_INFO_0_STR;
-
-/* SRV_TPRT_INFO_0 */
-typedef struct srv_tprt_info_0_info
-{
-       uint32 num_entries_read;                     /* EntriesRead */
-       uint32 ptr_tprt_info;                        /* Buffer */
-       uint32 num_entries_read2;                    /* EntriesRead */
-
-       TPRT_INFO_0     *info_0; /* transport entry pointers */
-       TPRT_INFO_0_STR *info_0_str; /* transport entry strings */
-
-} SRV_TPRT_INFO_0;
-
-/* SRV_TPRT_INFO_CTR */
-typedef struct srv_tprt_info_ctr_info
-{
-       uint32 switch_value;         /* switch value */
-       uint32 ptr_tprt_ctr;       /* pointer to tprt info union */
-       union
-       {
-               SRV_TPRT_INFO_0 info0; /* transport info level 0 */
-
-       } tprt;
-
-} SRV_TPRT_INFO_CTR;
-
-
-/* SRV_Q_NET_TPRT_ENUM */
-typedef struct q_net_tprt_enum_info
-{
-       uint32 ptr_srv_name;         /* pointer (to server name) */
-       UNISTR2 uni_srv_name;        /* server name "\\server" */
-
-       uint32 tprt_level;          /* transport level */
-
-       SRV_TPRT_INFO_CTR *ctr;
-
-       uint32 preferred_len;        /* preferred maximum length (0xffff ffff) */
-       ENUM_HND enum_hnd;
-
-} SRV_Q_NET_TPRT_ENUM;
-
-/* SRV_R_NET_TPRT_ENUM */
-typedef struct r_net_tprt_enum_info
-{
-       uint32 tprt_level;          /* share level */
-
-       SRV_TPRT_INFO_CTR *ctr;
-
-       uint32 total_entries;                    /* total number of entries */
-       ENUM_HND enum_hnd;
-
-       uint32 status;               /* return status */
-
-} SRV_R_NET_TPRT_ENUM;
-
-/* oops - this is going to take up a *massive* amount of stack. */
-/* the UNISTR2s already have 1024 uint16 chars in them... */
-#define MAX_SHARE_ENTRIES 128
-
 /* SH_INFO_1 (pointers to level 1 share info strings) */
 typedef struct ptr_share_info1
 {
@@ -354,12 +268,8 @@ typedef struct str_share_info1
 /* SRV_SHARE_INFO_1 */
 typedef struct share_info_1_info
 {
-       uint32 num_entries_read;                     /* EntriesRead */
-       uint32 ptr_share_info;                       /* Buffer */
-       uint32 num_entries_read2;                    /* EntriesRead */
-
-       SH_INFO_1     info_1    [MAX_SHARE_ENTRIES]; /* share entry pointers */
-       SH_INFO_1_STR info_1_str[MAX_SHARE_ENTRIES]; /* share entry strings */
+       SH_INFO_1 info_1;
+       SH_INFO_1_STR info_1_str;
 
 } SRV_SHARE_INFO_1;
 
@@ -390,24 +300,26 @@ typedef struct str_share_info2
 /* SRV_SHARE_INFO_2 */
 typedef struct share_info_2_info
 {
-       uint32 num_entries_read;                     /* EntriesRead */
-       uint32 ptr_share_info;                       /* Buffer */
-       uint32 num_entries_read2;                    /* EntriesRead */
-
-       SH_INFO_2     info_2    [MAX_SHARE_ENTRIES]; /* share entry pointers */
-       SH_INFO_2_STR info_2_str[MAX_SHARE_ENTRIES]; /* share entry strings */
+       SH_INFO_2 info_2;
+       SH_INFO_2_STR info_2_str;
 
 } SRV_SHARE_INFO_2;
 
 /* SRV_SHARE_INFO_CTR */
-typedef struct srv_share_info_1_info
+typedef struct srv_share_info_ctr_info
 {
-       uint32 switch_value;         /* switch value */
-       uint32 ptr_share_ctr;       /* pointer to share info union */
-       union
-       {
-               SRV_SHARE_INFO_1 info1; /* share info level 1 */
-               SRV_SHARE_INFO_2 info2; /* share info level 2 */
+       uint32 info_level;
+       uint32 switch_value;
+       uint32 ptr_share_info;
+
+       uint32 num_entries;
+       uint32 ptr_entries;
+       uint32 num_entries2;
+
+       union {
+               SRV_SHARE_INFO_1 *info1; /* share info level 1 */
+               SRV_SHARE_INFO_2 *info2; /* share info level 2 */
+               void *info;
 
        } share;
 
@@ -419,9 +331,7 @@ typedef struct q_net_share_enum_info
        uint32 ptr_srv_name;         /* pointer (to server name?) */
        UNISTR2 uni_srv_name;        /* server name */
 
-       uint32 share_level;          /* share level */
-
-       SRV_SHARE_INFO_CTR *ctr;     /* share info container */
+       SRV_SHARE_INFO_CTR ctr;     /* share info container */
 
        uint32 preferred_len;        /* preferred maximum length (0xffff ffff) */
 
@@ -433,8 +343,7 @@ typedef struct q_net_share_enum_info
 /* SRV_R_NET_SHARE_ENUM */
 typedef struct r_net_share_enum_info
 {
-       uint32 share_level;          /* share level */
-       SRV_SHARE_INFO_CTR *ctr;     /* share info container */
+       SRV_SHARE_INFO_CTR ctr;     /* share info container */
 
        uint32 total_entries;                    /* total number of entries */
        ENUM_HND enum_hnd;
@@ -443,6 +352,35 @@ typedef struct r_net_share_enum_info
 
 } SRV_R_NET_SHARE_ENUM;
 
+
+/* SRV_Q_NET_SHARE_GET_INFO */
+typedef struct q_net_share_get_info_info
+{
+       uint32 ptr_srv_name;
+       UNISTR2 uni_srv_name;
+
+       UNISTR2 uni_share_name;
+       uint32 info_level;
+
+} SRV_Q_NET_SHARE_GET_INFO;
+
+/* SRV_R_NET_SHARE_GET_INFO */
+typedef struct r_net_share_get_info_info
+{
+       uint32 switch_value;
+       uint32 ptr_share_ctr;
+
+       union {
+               SRV_SHARE_INFO_1 info1;
+               SRV_SHARE_INFO_2 info2;
+
+       } share;
+
+       uint32 status;
+
+} SRV_R_NET_SHARE_GET_INFO;
+
+
 /* FILE_INFO_3 (level 3 file info strings) */
 typedef struct file_info3_info
 {
@@ -485,10 +423,10 @@ typedef struct srv_file_info_3_info
        uint32 switch_value;         /* switch value */
        uint32 ptr_file_ctr;       /* pointer to file info union */
        union
-       {
+    {
                SRV_FILE_INFO_3 info3; /* file info with 0 entries */
 
-       } file;
+    } file;
 
 } SRV_FILE_INFO_CTR;
 
@@ -502,8 +440,6 @@ typedef struct q_net_file_enum_info
        uint32 ptr_qual_name;         /* pointer (to qualifier name) */
        UNISTR2 uni_qual_name;        /* qualifier name "\\qualifier" */
 
-       uint32 file_id;             /* file id */
-
        uint32 file_level;          /* file level */
 
        SRV_FILE_INFO_CTR *ctr;
@@ -573,11 +509,11 @@ typedef struct srv_info_ctr_info
        uint32 switch_value;         /* switch value */
        uint32 ptr_srv_ctr;         /* pointer to server info */
        union
-       {
+    {
                SRV_INFO_102 sv102; /* server info level 102 */
                SRV_INFO_101 sv101; /* server info level 101 */
 
-       } srv;
+    } srv;
 
 } SRV_INFO_CTR;
 
@@ -658,4 +594,3 @@ typedef struct r_net_remote_tod
 
 
 #endif /* _RPC_SRVSVC_H */
-
index 63b8e83a555814b777d228ae7c4b70b0674a0f1b..dc2be5d2b856a2df45f199025c49beb28b4dc846 100644 (file)
@@ -24,8 +24,6 @@
 #ifndef _RPCCLIENT_H
 #define _RPCCLIENT_H
 
-#define report fprintf
-
 struct tar_client_info
 {
     int blocksize;
@@ -59,8 +57,14 @@ struct nt_client_info
     NET_ID_INFO_CTR ctr;
     NET_USER_INFO_3 user_info3;
 
+    /************** \PIPE\winreg stuff ********************/
+
+    POLICY_HND reg_pol_connect;
+
     /************** \PIPE\lsarpc stuff ********************/
 
+    POLICY_HND lsa_info_pol;
+
     /* domain member */
     DOM_SID level3_sid;
     DOM_SID level5_sid;
@@ -69,34 +73,52 @@ struct nt_client_info
     fstring level3_dom;
     fstring level5_dom;
 
+    /************** \PIPE\samr stuff  ********************/
+
+    POLICY_HND samr_pol_connect;
+    POLICY_HND samr_pol_open_domain;
+    POLICY_HND samr_pol_open_user;
+
+    struct acct_info *sam;
+    int num_sam_entries;
 };
 
 struct client_info
 {
     struct in_addr dest_ip;
     fstring dest_host;
+    fstring query_host;
+    uint8 name_type;
 
     fstring myhostname;
     fstring mach_acct;
 
+    pstring cur_dir;
+    pstring base_dir;
+    pstring file_sel;
+
+    fstring service;
+    fstring share;
+    fstring svc_type;
+
+    time_t newer_than;
+    int archive_level;
+    int dir_total;
+    int put_total_time_ms;
+    int put_total_size;
+    int get_total_time_ms;
+    int get_total_size;
+    int print_mode;
+    BOOL translation;
+    BOOL recurse_dir;
+    BOOL prompt;
+    BOOL lowercase;
+    BOOL abort_mget;
+
     struct tar_client_info tar;
     struct nt_client_info dom;
-
-       BOOL reuse;
 };
 
 enum action_type {ACTION_HEADER, ACTION_ENUMERATE, ACTION_FOOTER};
 
-/****************************************************************************
- This defines the commands supported by this client
- ****************************************************************************/
-struct command_set
-{
-       char *name;
-       void (*fn)(struct client_info*, int, char*[]);
-       char *description;
-       char compl_args[2];
-
-};
-
 #endif /* _RPCCLIENT_H */
index 43c5dc6bb1e300627c3e54e2164f80038a97e4ca..d3d64a2edf0848374e946680a3a1e442818403fe 100644 (file)
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
-
 #ifndef _SMB_H
 #define _SMB_H
 
-#include "md5.h"
-#include "hmacmd5.h"
-
 #define BUFFER_SIZE (0xFFFF)
 #define SAFETY_MARGIN 1024
 
 #define NMB_PORT 137
 #define DGRAM_PORT 138
 #define SMB_PORT 139
-#define SMB_PORT2 445
 
 #define False (0)
 #define True (1)
-#define Auto (2)
+#define BOOLSTR(b) ((b) ? "Yes" : "No")
+#define BITSETB(ptr,bit) ((((char *)ptr)[0] & (1<<(bit)))!=0)
+#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
+
+#define IS_BITS_SET_ALL(var,bit) (((var)&(bit))==(bit))
+#define IS_BITS_SET_SOME(var,bit) (((var)&(bit))!=0)
+#define IS_BITS_CLR_ALL(var,bit) (((var)&(bit))==0)
+
+#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
 
-#ifndef _BOOL
 typedef int BOOL;
-#define _BOOL       /* So we don't typedef BOOL again in vfs.h */
-#endif
 
 /* limiting size of ipc replies */
 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
@@ -57,9 +57,93 @@ typedef int BOOL;
 /* how long to wait for secondary SMB packets (milli-seconds) */
 #define SMB_SECONDARY_WAIT (60*1000)
 
-/* Debugging stuff */
+/* -------------------------------------------------------------------------- **
+ * Debugging code.  See also debug.c
+ */
 
-#include <debug.h>
+/* mkproto.awk has trouble with ifdef'd function definitions (it ignores
+ * the #ifdef directive and will read both definitions, thus creating two
+ * diffferent prototype declarations), so we must do these by hand.
+ */
+/* I know the __attribute__ stuff is ugly, but it does ensure we get the 
+   arguemnts to DEBUG() right. We have got them wrong too often in the 
+   past */
+#ifdef HAVE_STDARG_H
+int  Debug1( char *, ... )
+#ifdef __GNUC__
+     __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+BOOL dbgtext( char *, ... )
+#ifdef __GNUC__
+     __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+#else
+int  Debug1();
+BOOL dbgtext();
+#endif
+
+/* If we have these macros, we can add additional info to the header. */
+#ifdef HAVE_FILE_MACRO
+#define FILE_MACRO (__FILE__)
+#else
+#define FILE_MACRO ("")
+#endif
+
+#ifdef HAVE_FUNCTION_MACRO
+#define FUNCTION_MACRO  (__FUNCTION__)
+#else
+#define FUNCTION_MACRO  ("")
+#endif
+
+/* Debugging macros. 
+ *  DEBUGLVL() - If level is <= the system-wide DEBUGLEVEL then generate a
+ *               header using the default macros for file, line, and
+ *               function name.
+ *               Returns True if the debug level was <= DEBUGLEVEL.
+ *               Example usage:
+ *                 if( DEBUGLVL( 2 ) )
+ *                   dbgtext( "Some text.\n" );
+ *  DEGUG()    - Good old DEBUG().  Each call to DEBUG() will generate a new
+ *               header *unless* the previous debug output was unterminated
+ *               (i.e., no '\n').  See debug.c:dbghdr() for more info.
+ *               Example usage:
+ *                 DEBUG( 2, ("Some text.\n") );
+ *  DEBUGADD() - If level <= DEBUGLEVEL, then the text is appended to the
+ *               current message (i.e., no header).
+ *               Usage:
+ *                 DEBUGADD( 2, ("Some additional text.\n") );
+ */
+#define DEBUGLVL( level ) \
+  ( (DEBUGLEVEL >= (level)) \
+   && dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) )
+
+#if 0
+
+#define DEBUG( level, body ) \
+  ( ( DEBUGLEVEL >= (level) \
+   && dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) ) \
+      ? (void)(dbgtext body) : (void)0 )
+
+#define DEBUGADD( level, body ) \
+     ( (DEBUGLEVEL >= (level)) ? (void)(dbgtext body) : (void)0 )
+
+#else
+
+#define DEBUG( level, body ) \
+  (void)( (DEBUGLEVEL >= (level)) \
+       && (dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) )) \
+       && (dbgtext body) )
+
+#define DEBUGADD( level, body ) \
+  (void)( (DEBUGLEVEL >= (level)) && (dbgtext body) )
+
+#endif
+
+/* End Debugging code section.
+ * -------------------------------------------------------------------------- **
+ */
 
 /* this defines the error codes that receive_smb can put in smb_read_error */
 #define READ_TIMEOUT 1
@@ -83,6 +167,13 @@ implemented */
 #define aDIR (1L<<4)
 #define aARCH (1L<<5)
 
+/* 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)
+
 /* deny modes */
 #define DENY_DOS 0
 #define DENY_ALL 1
@@ -238,32 +329,22 @@ implemented */
 #define ERRsharebufexc 36 /* share buffer exceeded */
 #define ERRdiskfull 39
 
-#ifndef _PSTRING
-#define PSTRING_LEN 1024
-#define FSTRING_LEN 128
 
-typedef char pstring[PSTRING_LEN];
-typedef char fstring[FSTRING_LEN];
-#define _PSTRING
-#endif
+typedef char pstring[1024];
+typedef char fstring[128];
 
 /* pipe string names */
 #define PIPE_LANMAN   "\\PIPE\\LANMAN"
-#define PIPE_BROWSER  "\\PIPE\\browser"
 #define PIPE_SRVSVC   "\\PIPE\\srvsvc"
 #define PIPE_SAMR     "\\PIPE\\samr"
 #define PIPE_WINREG   "\\PIPE\\winreg"
 #define PIPE_WKSSVC   "\\PIPE\\wkssvc"
 #define PIPE_NETLOGON "\\PIPE\\NETLOGON"
-#define PIPE_SVCCTL   "\\PIPE\\svcctl"
 #define PIPE_NTLSA    "\\PIPE\\ntlsa"
 #define PIPE_NTSVCS   "\\PIPE\\ntsvcs"
 #define PIPE_LSASS    "\\PIPE\\lsass"
 #define PIPE_LSARPC   "\\PIPE\\lsarpc"
-#define PIPE_EPMAPPER "\\PIPE\\epmapper"
-#define PIPE_ATSVC    "\\PIPE\\atsvc"
-#define PIPE_SPOOLSS  "\\PIPE\\spoolss"
-#define PIPE_EVENTLOG "\\PIPE\\EVENTLOG"
+
 
 /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
 typedef struct nttime_info
@@ -285,21 +366,19 @@ typedef struct nttime_info
 #define ACB_SVRTRUST   0x0100  /* 1 = Server trust account */
 #define ACB_PWNOEXP    0x0200  /* 1 = User password does not expire */
 #define ACB_AUTOLOCK   0x0400  /* 1 = Account auto locked */
-#define ACB_PWLOCK     0x0800  /* 1 = Password is locked and connot be changed remotely */
  
 #define MAX_HOURS_LEN 32
 
 struct sam_passwd
 {
-       NTTIME logon_time;            /* logon time */
-       NTTIME logoff_time;           /* logoff time */
-       NTTIME kickoff_time;          /* kickoff time */
-       NTTIME pass_last_set_time;    /* password last set time */
-       NTTIME pass_can_change_time;  /* password can change time */
-       NTTIME pass_must_change_time; /* password must change time */
-
-       char *unix_name;    /* unix username string */
-       char *nt_name;      /* nt username string */
+       time_t logon_time;            /* logon time */
+       time_t logoff_time;           /* logoff time */
+       time_t kickoff_time;          /* kickoff time */
+       time_t pass_last_set_time;    /* password last set time */
+       time_t pass_can_change_time;  /* password can change time */
+       time_t pass_must_change_time; /* password must change time */
+
+       char *smb_name;     /* username string */
        char *full_name;    /* user's full name string */
        char *home_dir;     /* home directory string */
        char *dir_drive;    /* home directory drive string */
@@ -310,8 +389,8 @@ struct sam_passwd
        char *unknown_str ; /* don't know what this is, yet. */
        char *munged_dial ; /* munged path name and dial-back tel number */
 
-       uid_t unix_uid;       /* this is actually the unix uid_t */
-       gid_t unix_gid;        /* this is actually the unix gid_t */
+       uid_t smb_userid;       /* this is actually the unix uid_t */
+       gid_t smb_grpid;        /* this is actually the unix gid_t */
        uint32 user_rid;      /* Primary User ID */
        uint32 group_rid;     /* Primary Group ID */
 
@@ -331,11 +410,8 @@ struct sam_passwd
 
 struct smb_passwd
 {
-       uid_t unix_uid;     /* unix userid */
-       char *unix_name;     /* unix username string */
-
-       uint32 user_rid;     /* Primary User ID */
-       char *nt_name;     /* unix username string */
+       uid_t smb_userid;     /* this is actually the unix uid_t */
+       char *smb_name;     /* username string */
 
        unsigned char *smb_passwd; /* Null if no password */
        unsigned char *smb_nt_passwd; /* Null if no password */
@@ -348,16 +424,8 @@ struct smb_passwd
 struct sam_disp_info
 {
        uint32 user_rid;      /* Primary User ID */
-       char *nt_name;        /* username string */
-       char *full_name;      /* user's full name string */
-};
-
-struct use_info
-{
-       BOOL connected;
-       char *srv_name;
-       char *user_name;
-       char *domain;
+       char *smb_name;     /* username string */
+       char *full_name;    /* user's full name string */
 };
 
 #define MAXSUBAUTHS 15 /* max sub authorities in a SID */
@@ -377,28 +445,6 @@ typedef struct sid_info
 } DOM_SID;
 
 
-typedef struct group_name_info
-{
-       char *nt_name;
-       char *nt_domain;
-       char *unix_name;
-
-       DOM_SID sid;
-       uint8 type;
-       uint32 unix_id;
-
-} DOM_NAME_MAP;
-
-/* map either local aliases, domain groups or builtin aliases */
-typedef enum 
-{
-       DOM_MAP_LOCAL,
-       DOM_MAP_DOMAIN,
-       DOM_MAP_USER
-
-} DOM_MAP_TYPE;
-
-
 /*** query a local group, get a list of these: shows who is in that group ***/
 
 /* local group member info */
@@ -417,22 +463,9 @@ typedef struct local_grp_info
 {
        fstring name;
        fstring comment;
-       uint32  rid; /* alias rid */
 
 } LOCAL_GRP;
 
-/*** query a domain group, get a list of these: shows who is in that group ***/
-
-/* domain group info */
-typedef struct domain_grp_member_info
-{
-       fstring name;
-       uint8   attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
-       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;
-
 /*** enumerate these to get list of domain groups ***/
 
 /* domain group member info */
@@ -445,6 +478,16 @@ typedef struct domain_grp_info
 
 } DOMAIN_GRP;
 
+/*** query a domain group, get a list of these: shows who is in that group ***/
+
+/* domain group info */
+typedef struct domain_grp_member_info
+{
+       fstring name;
+       uint8   attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+
+} DOMAIN_GRP_MEMBER;
+
 /* DOM_CHAL - challenge info */
 typedef struct chal_info
 {
@@ -496,34 +539,6 @@ typedef struct file_fd_struct
        BOOL delete_on_close;
 } file_fd_struct;
 
-typedef struct files_struct
-{
-       struct files_struct *next, *prev;
-       int fnum;
-       struct connection_struct *conn;
-       file_fd_struct *fd_ptr;
-       SMB_OFF_T pos;
-       SMB_OFF_T size;
-       mode_t mode;
-       uint16 vuid;
-       char *mmap_ptr;
-       SMB_OFF_T mmap_size;
-       write_bmpx_struct *wbmpx_ptr;
-       struct timeval open_time;
-        int share_mode;
-       time_t pending_modtime;
-       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;
-       char *fsp_name;
-} files_struct;
-
 /*
  * Structure used to keep directory state information around.
  * Used in NT change-notify code.
@@ -546,13 +561,6 @@ typedef struct
   BOOL is_wild;
 } name_compare_entry;
 
-/* Include VFS stuff */
-
-#include "vfs.h"
-
-
-#include "vagent.h"
-
 typedef struct connection_struct
 {
        struct connection_struct *next, *prev;
@@ -568,22 +576,19 @@ typedef struct connection_struct
        char *dirpath;
        char *connectpath;
        char *origpath;
-        struct vfs_ops vfs_ops;             /* Filesystem operations */
-        struct vfs_connection_struct *vfs_conn;
-
        char *user; /* name of user who *opened* this connection */
-
        uid_t uid; /* uid of user who *opened* this connection */
        gid_t gid; /* gid of user who *opened* this connection */
+       char client_address[18]; /* String version of client IP address. */
 
-       /* This groups info is valid for the user that *opened* the connection */
-       int ngroups;
-       gid_t *groups;
-       
        uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
 
        /* following groups stuff added by ih */
 
+       /* This groups info is valid for the user that *opened* the connection */
+       int ngroups;
+       gid_t *groups;
+       
        time_t lastused;
        BOOL used;
        int num_files_open;
@@ -603,6 +608,57 @@ struct current_user
        gid_t *groups;
 };
 
+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;
+
+/*
+ * 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 };     
+
+typedef struct files_struct
+{
+       struct files_struct *next, *prev;
+       int fnum;
+       connection_struct *conn;
+       file_fd_struct *fd_ptr;
+       SMB_OFF_T pos;
+       SMB_OFF_T size;
+       mode_t mode;
+       uint16 vuid;
+       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 is_directory;
+       BOOL directory_delete_on_close;
+       BOOL stat_open;
+       char *fsp_name;
+} files_struct;
+
+/* Defines for the sent_oplock_break field above. */
+#define NO_BREAK_SENT 0
+#define EXCLUSIVE_BREAK_SENT 1
+#define LEVEL_II_BREAK_SENT 2
+
 /* Domain controller authentication protocol info */
 struct dcinfo
 {
@@ -630,7 +686,11 @@ typedef struct
   int n_groups;
   gid_t *groups;
 
-       uchar user_sess_key[16];
+  int n_sids;
+  int *sids;
+
+  /* per-user authentication information on NT RPCs */
+  struct dcinfo dc;
 
 } user_struct;
 
@@ -670,7 +730,7 @@ struct server_info_struct
 /* used for network interfaces */
 struct interface
 {
-       struct interface *next;
+       struct interface *next, *prev;
        struct in_addr ip;
        struct in_addr bcast;
        struct in_addr nmask;
@@ -679,7 +739,7 @@ struct interface
 /* struct returned by get_share_modes */
 typedef struct
 {
-  int pid;
+  pid_t pid;
   uint16 op_port;
   uint16 op_type;
   int share_mode;
@@ -721,60 +781,40 @@ struct shmem_ops {
  * to support the following operations.
  */
 
-struct smb_passdb_ops
-{
-       /*
-        * Password database operations.
-        */
-       void *(*startsmbpwent)(BOOL);
-       void (*endsmbpwent)(void *);
-       SMB_BIG_UINT (*getsmbpwpos)(void *);
-       BOOL (*setsmbpwpos)(void *, SMB_BIG_UINT);
-
-       /*
-        * smb password database query functions.
-        */
-       struct smb_passwd *(*getsmbpwnam)(const char *);
-       struct smb_passwd *(*getsmbpwuid)(uid_t);
-       struct smb_passwd *(*getsmbpwent)(void *);
-
-       /*
-        * smb password database modification functions.
-        */
-       BOOL (*add_smbpwd_entry)(struct smb_passwd *);
-       BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL);
+struct passdb_ops {
+  /*
+   * Password database ops.
+   */
+  void *(*startsmbpwent)(BOOL);
+  void (*endsmbpwent)(void *);
+  SMB_BIG_UINT (*getsmbpwpos)(void *);
+  BOOL (*setsmbpwpos)(void *, SMB_BIG_UINT);
 
-#if 0
   /*
-   * password checking functions
+   * smb password database query functions.
    */
-  struct smb_passwd *(*smb_password_chal  )(const char *username, const char lm_pass[24], const char nt_pass[24], char chal[8]);
-  struct smb_passwd *(*smb_password_check )(const char *username, const char lm_hash[16], const char nt_hash[16]);
-  struct passwd     *(*unix_password_check)(const char *username, const char *pass, int pass_len);
-#endif
-};
+  struct smb_passwd *(*getsmbpwnam)(char *);
+  struct smb_passwd *(*getsmbpwuid)(uid_t);
+  struct smb_passwd *(*getsmbpwrid)(uint32);
+  struct smb_passwd *(*getsmbpwent)(void *);
 
-/*
- * Each implementation of the password database code needs
- * to support the following operations.
- */
+  /*
+   * smb password database modification functions.
+   */
+  BOOL (*add_smbpwd_entry)(struct smb_passwd *);
+  BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL);
 
-struct sam_passdb_ops {
   /*
-   * Password database operations.
+   * Functions that manupulate a struct sam_passwd.
    */
-  void *(*startsam21pwent)(BOOL);
-  void (*endsam21pwent)(void *);
-  SMB_BIG_UINT (*getsam21pwpos)(void *);
-  BOOL (*setsam21pwpos)(void *, SMB_BIG_UINT);
+  struct sam_passwd *(*getsam21pwent)(void *);
 
   /*
    * sam password database query functions.
    */
-  struct sam_passwd *(*getsam21pwntnam)(const char *);
+  struct sam_passwd *(*getsam21pwnam)(char *);
   struct sam_passwd *(*getsam21pwuid)(uid_t);
   struct sam_passwd *(*getsam21pwrid)(uint32);
-  struct sam_passwd *(*getsam21pwent)(void *);
 
   /*
    * sam password database modification functions.
@@ -785,120 +825,18 @@ struct sam_passdb_ops {
   /*
    * sam query display info functions.
    */
-  struct sam_disp_info *(*getsamdispntnam)(const char *);
+  struct sam_disp_info *(*getsamdispnam)(char *);
   struct sam_disp_info *(*getsamdisprid)(uint32);
   struct sam_disp_info *(*getsamdispent)(void *);
 
-};
-
-/*
- * Each implementation of the passgrp database code needs
- * to support the following operations.
- */
-
-struct passgrp_ops
-{
-       /*
-        * Password group database ops.
-        */
-       void *(*startsmbgrpent)(BOOL);
-       void (*endsmbgrpent)(void *);
-       SMB_BIG_UINT (*getsmbgrppos)(void *);
-       BOOL (*setsmbgrppos)(void *, SMB_BIG_UINT);
-
-       /*
-        * smb passgrp database query functions, by user attributes.
-        */
-       struct smb_passwd *(*getsmbgrpntnam)(const char *, uint32**, int*, uint32**, int*);
-       struct smb_passwd *(*getsmbgrpuid)(uid_t , uint32**, int*, uint32**, int*);
-       struct smb_passwd *(*getsmbgrprid)(uint32, uint32**, int*, uint32**, int*);
-       struct smb_passwd *(*getsmbgrpent)(void *, uint32**, int*, uint32**, int*);
-};
-
-/*
- * Each implementation of the group database code needs
- * to support the following operations.
- *
- * This allows enumeration, modification and addition of groups.  there
- * is _no_ deletion of groups: you can only modify them to a status of
- * "deleted" (this by the way is a requirement of c2 rating)
- */
-
-struct groupdb_ops
-{
-       /*
-        * Group database ops.
-        */
-       void *(*startgroupent)(BOOL);
-       void (*endgroupent)(void *);
-       SMB_BIG_UINT (*getgrouppos)(void *);
-       BOOL (*setgrouppos)(void *, SMB_BIG_UINT);
-
-       /*
-        * group database query functions. 
-        */
-       DOMAIN_GRP *(*getgroupntnam)(const char *, DOMAIN_GRP_MEMBER **, int *);
-       DOMAIN_GRP *(*getgroupgid)(gid_t , DOMAIN_GRP_MEMBER **, int *);
-       DOMAIN_GRP *(*getgrouprid)(uint32, DOMAIN_GRP_MEMBER **, int *);
-       DOMAIN_GRP *(*getgroupent)(void *, DOMAIN_GRP_MEMBER **, int *);
-
-       /*
-        * group database modification functions.
-        */
-       BOOL (*add_group_entry)(DOMAIN_GRP *);
-       BOOL (*mod_group_entry)(DOMAIN_GRP *);
-       BOOL (*del_group_entry)(uint32);
-
-       BOOL (*add_group_member)(uint32, uint32);
-       BOOL (*del_group_member)(uint32, uint32);
-
-       /*
-        * user group functions
-        */
-       BOOL (*getusergroupsntnam)(const char *, DOMAIN_GRP **, int *);
-};
-
-/*
- * Each implementation of the alias database code needs
- * to support the following operations.
- *
- * This allows enumeration, modification and addition of aliases.  there
- * is _no_ deletion of aliases: you can only modify them to a status of
- * "deleted" (this by the way is a requirement of c2 rating)
- */
-
-struct aliasdb_ops
-{
-       /*
-        * Alias database ops.
-        */
-       void *(*startaliasent)(BOOL);
-       void (*endaliasent)(void *);
-       SMB_BIG_UINT (*getaliaspos)(void *);
-       BOOL (*setaliaspos)(void *, SMB_BIG_UINT);
-
-       /*
-        * alias database query functions. 
-        */
-       LOCAL_GRP *(*getaliasntnam)(const char *, LOCAL_GRP_MEMBER **, int *);
-       LOCAL_GRP *(*getaliasgid)(gid_t , LOCAL_GRP_MEMBER **, int *);
-       LOCAL_GRP *(*getaliasrid)(uint32, LOCAL_GRP_MEMBER **, int *);
-       LOCAL_GRP *(*getaliasent)(void *, LOCAL_GRP_MEMBER **, int *);
-
-       /*
-        * alias database modification functions.
-        */
-       BOOL (*add_alias_entry)(LOCAL_GRP *);
-       BOOL (*mod_alias_entry)(LOCAL_GRP *);
-       BOOL (*del_alias_entry)(uint32);
-
-       BOOL (*add_alias_member)(uint32, DOM_SID*);
-       BOOL (*del_alias_member)(uint32, DOM_SID*);
-
-       /*
-        * user alias functions
-        */
-       BOOL (*getuseraliasntnam)(const char *, LOCAL_GRP **, int *);
+#if 0
+  /*
+   * password checking functions
+   */
+  struct smb_passwd *(*smb_password_chal  )(char *username, char lm_pass[24], char nt_pass[24], char chal[8]);
+  struct smb_passwd *(*smb_password_check )(char *username, char lm_hash[16], char nt_hash[16]);
+  struct passwd     *(*unix_password_check)(char *username, char *pass, int pass_len);
+#endif
 };
 
 /* this is used for smbstatus */
@@ -906,7 +844,7 @@ struct aliasdb_ops
 struct connect_record
 {
   int magic;
-  int pid;
+  pid_t pid;
   int cnum;
   uid_t uid;
   gid_t gid;
@@ -916,30 +854,11 @@ struct connect_record
   time_t start;
 };
 
-/* This is used by smbclient to send it to a smbfs mount point */
-struct connection_options {
-  int protocol;
-  /* Connection-Options */
-  uint32 max_xmit;
-  uint16 server_vuid;
-  uint16 tid;
-  /* The following are LANMAN 1.0 options */
-  uint16 sec_mode;
-  uint16 max_mux;
-  uint16 max_vcs;
-  uint16 rawmode;
-  uint32 sesskey;
-  /* The following are NT LM 0.12 options */
-  uint32 maxraw;
-  uint32 capabilities;
-  uint16 serverzone;
-};
-
 /* the following are used by loadparm for option lists */
 typedef enum
 {
   P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
-  P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM,P_PTR,P_SEP
+  P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM,P_SEP
 } parm_type;
 
 typedef enum
@@ -974,16 +893,67 @@ 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 */
 
+/* these are useful macros for checking validity of handles */
+#define OPEN_FSP(fsp)    ((fsp) && (fsp)->open && !(fsp)->is_directory)
+#define OPEN_CONN(conn)    ((conn) && (conn)->open)
+#define IS_IPC(conn)       ((conn) && (conn)->ipc)
+#define IS_PRINT(conn)       ((conn) && (conn)->printer)
+#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn)
+
+#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \
+                               return(ERROR(ERRDOS,ERRbadfid)); \
+                            else if((fsp)->fd_ptr == NULL) \
+                               return(ERROR(ERRDOS,ERRbadaccess))
+
+#define CHECK_READ(fsp) if (!(fsp)->can_read) \
+                               return(ERROR(ERRDOS,ERRbadaccess))
+#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
+                               return(ERROR(ERRDOS,ERRbadaccess))
+#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
+                               return(CACHED_ERROR(fsp))
+
+/* translates a connection number into a service number */
+#define SNUM(conn)         ((conn)?(conn)->service:-1)
+
+/* access various service details */
+#define SERVICE(snum)      (lp_servicename(snum))
+#define PRINTCAP           (lp_printcapname())
+#define PRINTCOMMAND(snum) (lp_printcommand(snum))
+#define PRINTERNAME(snum)  (lp_printername(snum))
+#define CAN_WRITE(conn)    (!conn->read_only)
+#define VALID_SNUM(snum)   (lp_snum_ok(snum))
+#define GUEST_OK(snum)     (VALID_SNUM(snum) && lp_guest_ok(snum))
+#define GUEST_ONLY(snum)   (VALID_SNUM(snum) && lp_guest_only(snum))
+#define CAN_SETDIR(snum)   (!lp_no_set_dir(snum))
+#define CAN_PRINT(conn)    ((conn) && lp_print_ok((conn)->service))
+#define MAP_HIDDEN(conn)   ((conn) && lp_map_hidden((conn)->service))
+#define MAP_SYSTEM(conn)   ((conn) && lp_map_system((conn)->service))
+#define MAP_ARCHIVE(conn)   ((conn) && lp_map_archive((conn)->service))
+#define IS_HIDDEN_PATH(conn,path)  ((conn) && is_in_path((path),(conn)->hide_list))
+#define IS_VETO_PATH(conn,path)  ((conn) && is_in_path((path),(conn)->veto_list))
+#define IS_VETO_OPLOCK_PATH(conn,path)  ((conn) && is_in_path((path),(conn)->veto_oplock_list))
+
+/* 
+ * Used by the stat cache code to check if a returned
+ * stat structure is valid.
+ */
+
+#define VALID_STAT(st) (st.st_nlink != 0)  
+#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR(st.st_mode))
+
+#define SMBENCRYPT()       (lp_encrypted_passwords())
 
 /* the basic packet size, assuming no words or bytes */
 #define smb_size 39
@@ -1138,13 +1108,15 @@ struct bitmap {
 #define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
 
 /* These are the NT transact sub commands. */
-#define NT_TRANSACT_CREATE                 1
-#define NT_TRANSACT_IOCTL                  2
-#define NT_TRANSACT_SET_SECURITY_DESC      3
-#define NT_TRANSACT_NOTIFY_CHANGE          4
-#define NT_TRANSACT_RENAME                 5
-#define NT_TRANSACT_QUERY_SECURITY_DESC    6
-#define NT_TRANSACT_GET_DFS_REFERRAL    0x10
+#define NT_TRANSACT_CREATE                1
+#define NT_TRANSACT_IOCTL                 2
+#define NT_TRANSACT_SET_SECURITY_DESC     3
+#define NT_TRANSACT_NOTIFY_CHANGE         4
+#define NT_TRANSACT_RENAME                5
+#define NT_TRANSACT_QUERY_SECURITY_DESC   6
+
+/* Relevant IOCTL codes */
+#define IOCTL_QUERY_JOB_INFO      0x530060
 
 /* these are the trans2 sub fields for primary requests */
 #define smb_tpscnt smb_vwv0
@@ -1246,6 +1218,8 @@ struct bitmap {
 #define FILE_DELETE_CHILD     0x040
 #define FILE_READ_ATTRIBUTES  0x080
 #define FILE_WRITE_ATTRIBUTES 0x100
+
+#define FILE_ALL_ATTRIBUTES   0x1FF
  
 /* Generic access masks & rights. */
 #define SPECIFIC_RIGHTS_MASK 0x00FFFFL
@@ -1255,7 +1229,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
@@ -1326,7 +1324,7 @@ struct bitmap {
 #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_PERSISTENT_ACLS 0x8
 
 /* ChangeNotify flags. */
 #define FILE_NOTIFY_CHANGE_FILE_NAME   0x001
@@ -1343,6 +1341,11 @@ struct bitmap {
 #define smb_base(buf) (((char *)(buf))+4)
 
 
+/* we don't allow server strings to be longer than 48 characters as
+   otherwise NT will not honour the announce packets */
+#define MAX_SERVER_STRING_LENGTH 48
+
+
 #define SMB_SUCCESS 0  /* The request was successful. */
 #define ERRDOS 0x01 /*  Error is from the core DOS operating system set. */
 #define ERRSRV 0x02  /* Error is generated by the server network file manager.*/
@@ -1368,6 +1371,17 @@ extern int dcelogin_atmost_once;
 char *strdup(char *s);
 #endif
 
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+#ifndef ABS
+#define ABS(a) ((a)>0?(a):(-(a)))
+#endif
+
 #ifndef SIGNAL_CAST
 #define SIGNAL_CAST (RETSIGTYPE (*)(int))
 #endif
@@ -1472,7 +1486,6 @@ char *strdup(char *s);
    
 #define FLAGS2_LONG_PATH_COMPONENTS   0x0001
 #define FLAGS2_EXTENDED_ATTRIBUTES    0x0002
-#define FLAGS2_EXT_SEC                0x0800
 #define FLAGS2_DFS_PATHNAMES          0x1000
 #define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
 #define FLAGS2_32_BIT_ERROR_CODES     0x4000 
@@ -1480,19 +1493,18 @@ char *strdup(char *s);
 
 /* Capabilities.  see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
 
-#define CAP_RAW_MODE          0x00000001
-#define CAP_MPX_MODE          0x00000002
-#define CAP_UNICODE           0x00000004
-#define CAP_LARGE_FILES       0x00000008
-#define CAP_NT_SMBS           0x00000010
-#define CAP_RPC_REMOTE_APIS   0x00000020
-#define CAP_STATUS32          0x00000040
-#define CAP_LEVEL_II_OPLOCKS  0x00000080
-#define CAP_LOCK_AND_READ     0x00000100
-#define CAP_NT_FIND           0x00000200
-#define CAP_DFS               0x00001000
-#define CAP_LARGE_READX       0x00004000
-#define CAP_EXTENDED_SECURITY 0x80000000
+#define CAP_RAW_MODE         0x0001
+#define CAP_MPX_MODE         0x0002
+#define CAP_UNICODE          0x0004
+#define CAP_LARGE_FILES      0x0008
+#define CAP_NT_SMBS          0x0010
+#define CAP_RPC_REMOTE_APIS  0x0020
+#define CAP_STATUS32         0x0040
+#define CAP_LEVEL_II_OPLOCKS 0x0080
+#define CAP_LOCK_AND_READ    0x0100
+#define CAP_NT_FIND          0x0200
+#define CAP_DFS              0x1000
+#define CAP_LARGE_READX      0x4000
 
 /* protocol types. It assumes that higher protocols include lower protocols
    as subsets */
@@ -1501,21 +1513,12 @@ enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANM
 /* security levels */
 enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN};
 
-/* server roles */
-enum server_types
-{
-       ROLE_DOMAIN_NONE,
-       ROLE_DOMAIN_MEMBER,
-       ROLE_DOMAIN_BDC,
-       ROLE_DOMAIN_PDC
-};
-
 /* 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};
+enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA};
 
 /* case handling */
 enum case_handling {CASE_LOWER,CASE_UPPER};
@@ -1525,6 +1528,38 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
 enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
 #endif /* WITH_SSL */
 
+/* Macros to get at offsets within smb_lkrng and smb_unlkrng
+   structures. We cannot define these as actual structures
+   due to possible differences in structure packing
+   on different machines/compilers. */
+
+#define SMB_LPID_OFFSET(indx) (10 * (indx))
+#define SMB_LKOFF_OFFSET(indx) ( 2 + (10 * (indx)))
+#define SMB_LKLEN_OFFSET(indx) ( 6 + (10 * (indx)))
+#define SMB_LARGE_LKOFF_OFFSET_HIGH(indx) (4 + (20 * (indx)))
+#define SMB_LARGE_LKOFF_OFFSET_LOW(indx) (8 + (20 * (indx)))
+#define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
+#define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
+
+/* Macro to cache an error in a write_bmpx_struct */
+#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
+                           w->wr_discard = True, -1)
+/* Macro to test if an error has been cached for this fnum */
+#define HAS_CACHED_ERROR(fsp) ((fsp)->open && (fsp)->wbmpx_ptr && \
+                               (fsp)->wbmpx_ptr->wr_discard)
+/* Macro to turn the cached error into an error packet */
+#define CACHED_ERROR(fsp) cached_error_packet(inbuf,outbuf,fsp,__LINE__)
+
+/* these are the datagram types */
+#define DGRAM_DIRECT_UNIQUE 0x10
+
+#define ERROR(class,x) error_packet(inbuf,outbuf,class,x,__LINE__)
+
+/* this is how errors are generated */
+#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,__LINE__)
+
+#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
+
 /*
  * Global value meaing that the smb_uid field should be
  * ingored (in share level security and protocol level == CORE)
@@ -1593,12 +1628,28 @@ extern int unix_ERR_code;
 /*
  * Bits we test with.
  */
+
+#define NO_OPLOCK 0
 #define EXCLUSIVE_OPLOCK 1
 #define BATCH_OPLOCK 2
+#define LEVEL_II_OPLOCK 4
+
+#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
+#define BATCH_OPLOCK_TYPE(lck) ((lck) & BATCH_OPLOCK)
+#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & LEVEL_II_OPLOCK)
 
 #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.
  */
@@ -1611,8 +1662,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
  *  +----+--------+--------+--------+-------+--------+
@@ -1622,12 +1674,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.
  */
@@ -1655,9 +1709,26 @@ extern int unix_ERR_code;
 
 #define CMD_REPLY 0x8000
 
-#include "smb_macros.h"
+/* useful macros */
+
+/* zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/* zero a structure given a pointer to the structure - no zero check */
+#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x)))
+
+/* zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) { if ((x) != NULL) ZERO_STRUCTPN(x); }
+
+/* zero an array - note that sizeof(array) must work - ie. it must not be a 
+   pointer */
+#define ZERO_ARRAY(x) memset((char *)(x), 0, sizeof(x))
+
+#define SMB_ASSERT(b) ((b)?(void)0: \
+        (DEBUG(0,("PANIC: assert failed at %s(%d)\n", \
+                __FILE__, __LINE__)), smb_panic("assert failed")))
+#define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n))
 
-#include "nt_printing.h"
 #include "ntdomain.h"
 
 /* A netbios name structure. */
@@ -1667,8 +1738,8 @@ struct nmb_name {
   unsigned int name_type;
 };
 
-
-#include "dfs.h"
+#include "client.h"
+#include "rpcclient.h"
 
 /*
  * Size of new password account encoding string. DO NOT CHANGE.
@@ -1701,63 +1772,10 @@ struct nmb_name {
 #define MAP_TO_GUEST_ON_BAD_USER 1
 #define MAP_TO_GUEST_ON_BAD_PASSWORD 2
 
-/* associate bit field or enumeration field with a string */
-struct field_info
-{
-       uint32 bits;
-       char *str;
-};
-
-#define AGENT_CMD_CON       0
-#define AGENT_CMD_CON_ANON  2
-#define AGENT_CMD_CON_REUSE 1
-
-#define MAX_MAX_MUX_LIMIT 16
-
-struct nmb_state
-{
-       struct in_addr ip;
-       int port;
-};
-
-struct pwd_info
-{
-       BOOL null_pwd;
-       BOOL cleartext;
-       BOOL crypted;
-
-       fstring password;
-
-       uchar smb_lm_pwd[16];
-       uchar smb_nt_pwd[16];
-
-       uchar smb_lm_owf[24];
-       uchar smb_nt_owf[128];
-       size_t nt_owf_len;
-
-       uchar lm_cli_chal[8];
-       uchar nt_cli_chal[128];
-       size_t nt_cli_chal_len;
-
-       uchar sess_key[16];
-};
-
-#include "rpc_creds.h"
-
-struct msrpc_state
-{
-       fstring pipe_name;
-       struct user_creds usr;
-       int fd;
-       BOOL redirect;
-       BOOL initialised;
-       char *inbuf;
-       char *outbuf;
-};
+/*
+ * SMB UCS2 (16-bit unicode) internal type.
+ */
 
-#include "client.h"
-#include "rpcclient.h"
+typedef uint16 smb_ucs2_t;
 
 #endif /* _SMB_H */
-
-/* _SMB_H */
index 634244a1932e8370a5a17a5d8eefcf558a86a97c..bbe796b74253e056059875dea15cedc7a8544af9 100644 (file)
@@ -239,6 +239,26 @@ Byte offset   Type     name                description
 
 #define DIRLEN_GUESS (45+MAX(l1_achName,l2_achName))
 
+/*
+ * DeviceType and Characteristics returned in a
+ * SMB_QUERY_FS_DEVICE_INFO call.
+ */
+
+#define DEVICETYPE_CD_ROM              0x2
+#define DEVICETYPE_CD_ROM_FILE_SYSTEM  0x3
+#define DEVICETYPE_DISK                        0x7
+#define DEVICETYPE_DISK_FILE_SYSTEM    0x8
+#define DEVICETYPE_FILE_SYSTEM         0x9
+
+/* Characteristics. */
+#define TYPE_REMOVABLE_MEDIA           0x1
+#define TYPE_READ_ONLY_DEVICE          0x2
+#define TYPE_FLOPPY                    0x4
+#define TYPE_WORM                      0x8
+#define TYPE_REMOTE                    0x10
+#define TYPE_MOUNTED                   0x20
+#define TYPE_VIRTUAL                   0x40
+
 #endif
 
 
index 3714273aa09759bda53c5aeef97e9625765b8968..1c37111a17dbb21df733f3a1a40f634d7be42252 100644 (file)
@@ -1 +1 @@
-#define VERSION "2.1.0-prealpha"
+#define VERSION "pre-2.0.6"
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..8f91e4573af47a463e3bfab93b3022c1dacfd0f4 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>
@@ -120,36 +128,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 +190,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 +240,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 fc2924a155ab8e398485bcfa8ca01072785a7da9..6e5a4b48cbab3a28baeab82d11de096b8cd98f8f 100644 (file)
@@ -320,8 +320,9 @@ clean_and_exit:
 }
 
 /****************************************************************************
-initialise the client codepage.
+ Initialise the client codepage.
 ****************************************************************************/
+
 void codepage_initialise(int client_codepage)
 {
   int i;
@@ -369,6 +370,9 @@ for code page %d failed. Using default client codepage 850\n",
     for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++)
       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 39c01fa30fb74cde76b9d170688f24d90bd1f65e..16b337c764bd42c0a5eba03fc223bf62dfc530c8 100644 (file)
@@ -56,14 +56,12 @@ static unsigned long CRCTable[256] =
         0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
 };
 
-uint32 crc32_calc_buffer( uint32 count, char *buffer)
+uint32 crc32_calc_buffer( char *buffer, uint32 count)
 {
         uint32 crc=0xffffffff;
-       uint32 i;
+       int i;
         for(i=0;i<count;i++)
-       {
                 crc = (crc>>8) ^ CRCTable[(buffer[i] ^ crc) & 0xff];
-       }
         crc^=0xffffffff;
        DEBUG(10,("crc32_calc_buffer: %x\n", crc));
        dump_data(100, buffer, count);
index ab11d81a212c96c08a265ef1093113be66a09f06..a0dfe61f7df1b041304bd3d0ea697d93b5d7805a 100644 (file)
@@ -75,7 +75,6 @@
  *  debugf        - Debug file name.
  *  append_log    - If True, then the output file will be opened in append
  *                  mode.
- *  timestamp_log - 
  *  DEBUGLEVEL    - System-wide debug message limit.  Messages with message-
  *                  levels higher than DEBUGLEVEL will not be processed.
  */
@@ -83,7 +82,6 @@
 FILE   *dbf        = NULL;
 pstring debugf     = "";
 BOOL    append_log = False;
-BOOL    timestamp_log = True;
 int     DEBUGLEVEL = 1;
 
 
@@ -114,51 +112,40 @@ static int     debug_count    = 0;
 static int     syslog_level   = 0;
 #endif
 static pstring format_bufr    = { '\0' };
-static int     format_pos     = 0;
+static size_t     format_pos     = 0;
 
 
 /* -------------------------------------------------------------------------- **
  * Functions...
  */
 
-/* ************************************************************************** **
- * tells us if interactive logging was requested
- * ************************************************************************** **
- */
-BOOL dbg_interactive(void)
-{
-       return stdout_logging;
-}
-
-#if defined(SIGUSR2) && !defined(MEM_MAN)
+#if defined(SIGUSR2)
 /* ************************************************************************** **
  * catch a sigusr2 - decrease the debug log level.
  * ************************************************************************** **
  */
 void sig_usr2( int sig )
   {
-  BlockSignals( True, SIGUSR2 );
-
   DEBUGLEVEL--;
   if( DEBUGLEVEL < 0 )
     DEBUGLEVEL = 0;
 
   DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) );
 
-  BlockSignals( False, SIGUSR2 );
+#if !defined(HAVE_SIGACTION)
   CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
+#endif
 
   } /* sig_usr2 */
 #endif /* SIGUSR2 */
 
-#if defined(SIGUSR1) && !defined(MEM_MAN)
+#if defined(SIGUSR1)
 /* ************************************************************************** **
  * catch a sigusr1 - increase the debug log level. 
  * ************************************************************************** **
  */
 void sig_usr1( int sig )
   {
-  BlockSignals( True, SIGUSR1 );
 
   DEBUGLEVEL++;
 
@@ -167,8 +154,9 @@ void sig_usr1( int sig )
 
   DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
 
-  BlockSignals( False, SIGUSR1 );
+#if !defined(HAVE_SIGACTION)
   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
+#endif
 
   } /* sig_usr1 */
 #endif /* SIGUSR1 */
@@ -260,11 +248,11 @@ void force_check_log_size( void )
  * ************************************************************************** **
  */
 static void check_log_size( void )
-  {
+{
   int         maxlog;
   SMB_STRUCT_STAT st;
 
-  if( debug_count++ < 100 || getuid() != 0 )
+  if( debug_count++ < 100 || geteuid() != 0 )
     return;
 
   maxlog = lp_max_log_size() * 1024;
@@ -276,7 +264,7 @@ static void check_log_size( void )
     (void)fclose( dbf );
     dbf = NULL;
     reopen_logs();
-    if( dbf && file_size( debugf ) > maxlog )
+    if( dbf && get_file_size( debugf ) > maxlog )
       {
       pstring name;
 
@@ -287,8 +275,23 @@ static void check_log_size( void )
       reopen_logs();
       }
     }
+  /*
+   * Here's where we need to panic if dbf == NULL..
+   */
+  if(dbf == NULL) {
+    dbf = sys_fopen( "/dev/console", "w" );
+    if(dbf) {
+      DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
+            debugf ));
+    } else {
+      /*
+       * We cannot continue without a debug file handle.
+       */
+      abort();
+    }
+  }
   debug_count = 0;
-  } /* check_log_size */
+} /* check_log_size */
 
 /* ************************************************************************** **
  * Write an debug message on the debugfile.
@@ -382,6 +385,8 @@ va_dcl
     }
 #endif
   
+  check_log_size();
+
 #ifdef WITH_SYSLOG
   if( !lp_syslog_only() )
 #endif
@@ -397,8 +402,6 @@ va_dcl
     (void)fflush( dbf );
     }
 
-  check_log_size();
-
   errno = old_errno;
 
   return( 0 );
@@ -439,8 +442,8 @@ static void bufr_print( void )
  */
 static void format_debug_text( char *msg )
   {
-  int i;
-  BOOL timestamp = (timestamp_log && !stdout_logging && (lp_timestamp_logs() || 
+  size_t i;
+  BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() || 
                                        !(lp_loaded())));
 
   for( i = 0; msg[i]; i++ )
@@ -510,10 +513,13 @@ void dbgflush( void )
  *
  * ************************************************************************** **
  */
+
 BOOL dbghdr( int level, char *file, char *func, int line )
-  {
-  if( format_pos )
-    {
+{
+  /* Ensure we don't lose any real errno value. */
+  int old_errno = errno;
+
+  if( format_pos ) {
     /* This is a fudge.  If there is stuff sitting in the format_bufr, then
      * the *right* thing to do is to call
      *   format_debug_text( "\n" );
@@ -524,7 +530,7 @@ BOOL dbghdr( int level, char *file, char *func, int line )
      * that a new header is *not* desired.
      */
     return( True );
-    }
+  }
 
 #ifdef WITH_SYSLOG
   /* Set syslog_level. */
@@ -538,15 +544,32 @@ BOOL dbghdr( int level, char *file, char *func, int line )
   /* Print the header if timestamps are turned on.  If parameters are
    * not yet loaded, then default to timestamps on.
    */
-  if( timestamp_log && (lp_timestamp_logs() || !(lp_loaded()) ))
-    {
+  if( lp_timestamp_logs() || !(lp_loaded()) ) {
+    char header_str[200];
+
+       header_str[0] = '\0';
+
+       if( lp_debug_pid())
+         slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)getpid());
+
+       if( lp_debug_uid()) {
+      size_t hs_len = strlen(header_str);
+         slprintf(header_str + hs_len,
+               sizeof(header_str) - 1 - hs_len,
+                          ", effective(%u, %u), real(%u, %u)",
+               (unsigned int)geteuid(), (unsigned int)getegid(),
+                          (unsigned int)getuid(), (unsigned int)getgid()); 
+       }
+  
     /* Print it all out at once to prevent split syslog output. */
-    (void)Debug1( "[%s, %d] %s:%s(%d)\n",
-                  timestring(), level, file, func, line );
-    }
+    (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
+                  timestring(lp_debug_hires_timestamp()), level,
+                                 header_str, file, func, line );
+  }
 
+  errno = old_errno;
   return( True );
-  } /* dbghdr */
+}
 
 /* ************************************************************************** **
  * Add text to the body of the "current" debug message via the format buffer.
@@ -596,163 +619,4 @@ BOOL dbghdr( int level, char *file, char *func, int line )
 
 #endif
 
-dbg_Token dbg_char2token( dbg_Token *state, int c )
-  /* ************************************************************************ **
-   * Parse input one character at a time.
-   *
-   *  Input:  state - A pointer to a token variable.  This is used to
-   *                  maintain the parser state between calls.  For
-   *                  each input stream, you should set up a separate
-   *                  state variable and initialize it to dbg_null.
-   *                  Pass a pointer to it into this function with each
-   *                  character in the input stream.  See dbg_test()
-   *                  for an example.
-   *          c     - The "current" character in the input stream.
-   *
-   *  Output: A token.
-   *          The token value will change when delimiters are found,
-   *          which indicate a transition between syntactical objects.
-   *          Possible return values are:
-   *
-   *          dbg_null        - The input character was an end-of-line.
-   *                            This resets the parser to its initial state
-   *                            in preparation for parsing the next line.
-   *          dbg_eof         - Same as dbg_null, except that the character
-   *                            was an end-of-file.
-   *          dbg_ignore      - Returned for whitespace and delimiters.
-   *                            These lexical tokens are only of interest
-   *                            to the parser.
-   *          dbg_header      - Indicates the start of a header line.  The
-   *                            input character was '[' and was the first on
-   *                            the line.
-   *          dbg_timestamp   - Indicates that the input character was part
-   *                            of a header timestamp.
-   *          dbg_level       - Indicates that the input character was part
-   *                            of the debug-level value in the header.
-   *          dbg_sourcefile  - Indicates that the input character was part
-   *                            of the sourcefile name in the header.
-   *          dbg_function    - Indicates that the input character was part
-   *                            of the function name in the header.
-   *          dbg_lineno      - Indicates that the input character was part
-   *                            of the DEBUG call line number in the header.
-   *          dbg_message     - Indicates that the input character was part
-   *                            of the DEBUG message text.
-   *
-   * ************************************************************************ **
-   */
-  {
-  /* The terminating characters that we see will greatly depend upon
-   * how they are read.  For example, if gets() is used instead of
-   * fgets(), then we will not see newline characters.  A lot also
-   * depends on the calling function, which may handle terminators
-   * itself.
-   *
-   * '\n', '\0', and EOF are all considered line terminators.  The
-   * dbg_eof token is sent back if an EOF is encountered.
-   *
-   * Warning:  only allow the '\0' character to be sent if you are
-   *           using gets() to read whole lines (thus replacing '\n'
-   *           with '\0').  Sending '\0' at the wrong time will mess
-   *           up the parsing.
-   */
-  switch( c )
-    {
-    case EOF:
-      *state = dbg_null;   /* Set state to null (initial state) so */
-      return( dbg_eof );   /* that we can restart with new input.  */
-    case '\n':
-    case '\0':
-      *state = dbg_null;   /* A newline or eoln resets to the null state. */
-      return( dbg_null );
-    }
-
-  /* When within the body of the message, only a line terminator
-   * can cause a change of state.  We've already checked for line
-   * terminators, so if the current state is dbg_msgtxt, simply
-   * return that as our current token.
-   */
-  if( dbg_message == *state )
-    return( dbg_message );
-
-  /* If we are at the start of a new line, and the input character 
-   * is an opening bracket, then the line is a header line, otherwise
-   * it's a message body line.
-   */
-  if( dbg_null == *state )
-    {
-    if( '[' == c )
-      {
-      *state = dbg_timestamp;
-      return( dbg_header );
-      }
-    *state = dbg_message;
-    return( dbg_message );
-    }
-
-  /* We've taken care of terminators, text blocks and new lines.
-   * The remaining possibilities are all within the header line
-   * itself.
-   */
-
-  /* Within the header line, whitespace can be ignored *except*
-   * within the timestamp.
-   */
-  if( isspace( c ) )
-    {
-    /* Fudge.  The timestamp may contain space characters. */
-    if( (' ' == c) && (dbg_timestamp == *state) )
-      return( dbg_timestamp );
-    /* Otherwise, ignore whitespace. */
-    return( dbg_ignore );
-    }
-
-  /* Okay, at this point we know we're somewhere in the header.
-   * Valid header *states* are: dbg_timestamp, dbg_level,
-   * dbg_sourcefile, dbg_function, and dbg_lineno.
-   */
-  switch( c )
-    {
-    case ',':
-      if( dbg_timestamp == *state )
-        {
-        *state = dbg_level;
-        return( dbg_ignore );
-        }
-      break;
-    case ']':
-      if( dbg_level == *state )
-        {
-        *state = dbg_sourcefile;
-        return( dbg_ignore );
-        }
-      break;
-    case ':':
-      if( dbg_sourcefile == *state )
-        {
-        *state = dbg_function;
-        return( dbg_ignore );
-        }
-      break;
-    case '(':
-      if( dbg_function == *state )
-        {
-        *state = dbg_lineno;
-        return( dbg_ignore );
-        }
-      break;
-    case ')':
-      if( dbg_lineno == *state )
-        {
-        *state = dbg_null;
-        return( dbg_ignore );
-        }
-      break;
-    }
-
-  /* If the previous block did not result in a state change, then
-   * return the current state as the current token.
-   */
-  return( *state );
-  } /* dbg_char2token */
-
 /* ************************************************************************** */
index 2098b5e3508cc40cd7818d1be033c3ace5e8d159..e6f9d19879ee5f6c33159433bc538d5193c672e3 100644 (file)
@@ -52,23 +52,18 @@ int dos_open(char *fname,int flags,mode_t mode)
 }
 
 /*******************************************************************
- Opendir() wrapper that calls dos_to_unix.  Should use the 
- vfs_ops->opendir() function instead.
+ Opendir() wrapper that calls dos_to_unix.
 ********************************************************************/
 
-#if 0
 DIR *dos_opendir(char *dname)
 {
   return(opendir(dos_to_unix(dname,False)));
 }
-#endif
 
 /*******************************************************************
- Readdirname() wrapper that calls unix_to_dos.  Should use the 
- vfs_readdirname() function instead.
+ Readdirname() wrapper that calls unix_to_dos.
 ********************************************************************/
 
-#if 0
 char *dos_readdirname(DIR *p)
 {
   char *dname = readdirname(p);
@@ -79,7 +74,15 @@ char *dos_readdirname(DIR *p)
   unix_to_dos(dname, True);
   return(dname);
 }
-#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 +103,18 @@ 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.
 ********************************************************************/
 
 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;
 }
 
 /*******************************************************************
@@ -151,7 +158,7 @@ int dos_utime(char *fname,struct utimbuf *times)
  <warrenb@hpcvscdp.cv.hp.com>
 **********************************************************/
 
-int copy_reg(char *source, const char *dest)
+static int copy_reg(char *source, const char *dest)
 {
   SMB_STRUCT_STAT source_stats;
   int ifd;
@@ -243,11 +250,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;
 }
 
 /*******************************************************************
@@ -274,15 +289,13 @@ char *dos_getwd(char *unix_path)
 }
 
 /*******************************************************************
- Check if a DOS file exists.  Use vfs_file_exist function instead.
+ Check if a DOS file exists.
 ********************************************************************/
 
-#if 0
 BOOL dos_file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
 {
   return file_exist(dos_to_unix(fname, False), sbuf);
 }
-#endif
 
 /*******************************************************************
  Check if a DOS directory exists.
@@ -308,7 +321,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));
 }
 
 /*******************************************************************
@@ -404,7 +417,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 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 65d276021ce2be2c709cd04b80fe394a90d33c8a..926642795994493e1e3adaef5cf819f1a7c5a693 100644 (file)
 
 #include "includes.h"
 
+#define MAX_INTERFACES 128
+
+static struct iface_struct *probed_ifaces;
+static int total_probed;
+
 extern int DEBUGLEVEL;
 
 struct in_addr ipzero;
 struct in_addr allones_ip;
 struct in_addr loopback_ip;
-static struct in_addr default_ip;
-static struct in_addr default_bcast;
-static struct in_addr default_nmask;
-static BOOL got_ip=False;
-static BOOL got_bcast=False;
-static BOOL got_nmask=False;
 
 static struct interface *local_interfaces  = NULL;
 
-struct interface *last_iface;
-
 #define ALLONES  ((uint32)0xFFFFFFFF)
 #define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
+#define MKNETADDR(_IP, _NM) (_IP & _NM)
+
 /****************************************************************************
-calculate the default netmask for an address
-****************************************************************************/
-static void default_netmask(struct in_addr *inm, struct in_addr *iad)
+Try and find an interface that matches an ip. If we cannot, return NULL
+  **************************************************************************/
+static struct interface *iface_find(struct in_addr ip)
 {
-       /*
-       ** Guess a netmask based on the class of the IP address given.
-       */
-       switch((ntohl(iad->s_addr) & 0xE0000000)) {
-        case 0x00000000:     /* Class A addr */
-        case 0x20000000:
-        case 0x40000000:
-        case 0x60000000:
-               inm->s_addr = htonl(0xFF000000);
-               break;
-               
-       case 0x80000000:        /* Class B addr */
-        case 0xA0000000:
-               inm->s_addr = htonl(0xFFFF0000);
-               break;
-               
-       case 0xC0000000:        /* Class C addr */
-               inm->s_addr = htonl(0xFFFFFF00);
-               break;
-               
-       default:                /* ??? */
-               inm->s_addr = htonl(0xFFFFFFF0);
-        }
+       struct interface *i;
+       if (zero_ip(ip)) return local_interfaces;
+
+       for (i=local_interfaces;i;i=i->next)
+               if (same_net(i->ip,ip,i->nmask)) return i;
+
+       return NULL;
 }
 
 
 /****************************************************************************
-  get the broadcast address for our address 
-(troyer@saifr00.ateng.az.honeywell.com)
+add an interface to the linked list of interfaces
 ****************************************************************************/
-static void get_broadcast(struct in_addr *if_ipaddr,
-                         struct in_addr *if_bcast,
-                         struct in_addr *if_nmask)
-{  
-       uint32 nm;
-       short onbc;
-       short offbc;
-
-       /* get a default netmask and broadcast */
-       default_netmask(if_nmask, if_ipaddr);
-
-       get_netmask(if_ipaddr, if_nmask);
-
-       /* sanity check on the netmask */
-       nm = ntohl(if_nmask->s_addr);
-       onbc = 0;
-       offbc = 0;
-       while((onbc + offbc) < 32) {
-               if(nm & 0x80000000) {
-                       onbc++;
-                       if(offbc) {
-                               /* already found an off bit, so mask
-                                   is wrong */
-                               onbc = 34;
-                       }
-               } else {
-                       offbc++;
-               }
-               nm <<= 1;
+static void add_interface(struct in_addr ip, struct in_addr nmask)
+{
+       struct interface *iface;
+       if (iface_find(ip)) {
+               DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
+               return;
        }
-       if ((onbc < 8)||(onbc == 34)) {
-               DEBUG(0,("Impossible netmask %s - using defaults\n",
-                        inet_ntoa(*if_nmask)));
-               default_netmask(if_nmask, if_ipaddr);      
+
+       if (ip_equal(nmask, allones_ip)) {
+               DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
+               return;
        }
 
-       /* derive the broadcast assuming a 1's broadcast, as this is what
-          all MS operating systems do, we have to comply even if the unix
-          box is setup differently */
-       if_bcast->s_addr = MKBCADDR(if_ipaddr->s_addr, if_nmask->s_addr);
-  
-       DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
+       iface = (struct interface *)malloc(sizeof(*iface));
+       if (!iface) return;
+       
+       ZERO_STRUCTPN(iface);
+
+       iface->ip = ip;
+       iface->nmask = nmask;
+       iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+
+       DLIST_ADD(local_interfaces, iface);
+
+       DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
+       DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
+       DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));             
 }
 
 
 
 /****************************************************************************
-load a list of network interfaces
+interpret a single element from a interfaces= config line 
+
+This handles the following different forms:
+
+1) wildcard interface name
+2) DNS name
+3) IP/masklen
+4) ip/mask
+5) bcast/mask
 ****************************************************************************/
-static void interpret_interfaces(char *s, struct interface **interfaces,
-               char *description)
+static void interpret_interface(char *token)
 {
-  char *ptr;
-  fstring token;
-  struct interface *iface;
-  struct in_addr ip;
-
-  ptr = s;
-  ipzero = *interpret_addr2("0.0.0.0");
-  allones_ip = *interpret_addr2("255.255.255.255");
-  loopback_ip = *interpret_addr2("127.0.0.1");
-
-  while (next_token(&ptr,token,NULL,sizeof(token))) {
-    /* parse it into an IP address/netmasklength pair */
-    char *p = strchr(token,'/');
-    if (p) *p++ = 0;
-
-    ip = *interpret_addr2(token);
-
-    /* maybe we already have it listed */
-    {
-      struct interface *i;
-      for (i=(*interfaces);i;i=i->next)
-       if (ip_equal(ip,i->ip)) break;
-      if (i) continue;
-    }
-
-    iface = (struct interface *)malloc(sizeof(*iface));
-    if (!iface) return;
-
-    iface->ip = ip;
-
-    if (p) {
-      if (strlen(p) > 2)
-       iface->nmask = *interpret_addr2(p);
-      else
-       iface->nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
-    } else {
-      default_netmask(&iface->nmask,&iface->ip);
-    }
-    iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
-    iface->next = NULL;
-
-    if (!(*interfaces)) {
-      (*interfaces) = iface;
-    } else {
-      last_iface->next = iface;
-    }
-    last_iface = iface;
-    DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
-    DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
-    DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));        
-  }
-
-  if (*interfaces) return;
-
-  /* setup a default interface */
-  iface = (struct interface *)malloc(sizeof(*iface));
-  if (!iface) return;
-
-  iface->next = NULL;
-
-  if (got_ip) {
-    iface->ip = default_ip;
-  } else {
-    get_myname(NULL,&iface->ip);
-  }
-
-  if (got_bcast) {
-    iface->bcast = default_bcast;
-  } else {
-    get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
-  }
-
-  if (got_nmask) {
-    iface->nmask = default_nmask;
-    iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
-  }
-
-  if (iface->bcast.s_addr != MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr)) {
-    DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
-  }
-
-  iface->next = NULL;
-  (*interfaces) = last_iface = iface;
-
-  DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
-  DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
-  DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));          
+       struct in_addr ip, nmask;
+       char *p;
+       int i, added=0;
+
+       ip = ipzero;
+       nmask = ipzero;
+       
+       /* first check if it is an interface name */
+       for (i=0;i<total_probed;i++) {
+               if (fnmatch(token, probed_ifaces[i].name, 0) == 0) {
+                       add_interface(probed_ifaces[i].ip,
+                                     probed_ifaces[i].netmask);
+                       added = 1;
+               }
+       }
+       if (added) return;
+
+       /* maybe it is a DNS name */
+       p = strchr(token,'/');
+       if (!p) {
+               ip = *interpret_addr2(token);
+               for (i=0;i<total_probed;i++) {
+                       if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
+                           !ip_equal(allones_ip, probed_ifaces[i].netmask)) {
+                               add_interface(probed_ifaces[i].ip,
+                                             probed_ifaces[i].netmask);
+                               return;
+                       }
+               }
+               DEBUG(2,("can't determine netmask for %s\n", token));
+               return;
+       }
+
+       /* parse it into an IP address/netmasklength pair */
+       *p++ = 0;
+
+       ip = *interpret_addr2(token);
+
+       if (strlen(p) > 2) {
+               nmask = *interpret_addr2(p);
+       } else {
+               nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
+       }
+
+       /* maybe the first component was a broadcast address */
+       if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
+           ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
+               for (i=0;i<total_probed;i++) {
+                       if (same_net(ip, probed_ifaces[i].ip, nmask)) {
+                               add_interface(probed_ifaces[i].ip, nmask);
+                               return;
+                       }
+               }
+               DEBUG(2,("Can't determine ip for broadcast address %s\n", token));
+               return;
+       }
+
+       add_interface(ip, nmask);
 }
 
 
 /****************************************************************************
-load the remote and local interfaces
+load the list of network interfaces
 ****************************************************************************/
 void load_interfaces(void)
 {
-  /* add the machine's interfaces to local interface structure*/
-  interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
+       char *ptr;
+       fstring token;
+       int i;
+       struct iface_struct ifaces[MAX_INTERFACES];
+
+       ptr = lp_interfaces();
+
+       ipzero = *interpret_addr2("0.0.0.0");
+       allones_ip = *interpret_addr2("255.255.255.255");
+       loopback_ip = *interpret_addr2("127.0.0.1");
+
+       if (probed_ifaces) {
+               free(probed_ifaces);
+               probed_ifaces = NULL;
+       }
+
+       /* dump the current interfaces if any */
+       while (local_interfaces) {
+               struct interface *iface = local_interfaces;
+               DLIST_REMOVE(local_interfaces, local_interfaces);
+               ZERO_STRUCTPN(iface);
+               free(iface);
+       }
+
+       /* probe the kernel for interfaces */
+       total_probed = get_interfaces(ifaces, MAX_INTERFACES);
+
+       if (total_probed > 0) {
+               probed_ifaces = memdup(ifaces, sizeof(ifaces[0])*total_probed);
+       }
+
+       /* if we don't have a interfaces line then use all broadcast capable 
+          interfaces except loopback */
+       if (!ptr || !*ptr) {
+               if (total_probed <= 0) {
+                       DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
+                       exit(1);
+               }
+               for (i=0;i<total_probed;i++) {
+                       if (probed_ifaces[i].netmask.s_addr != allones_ip.s_addr &&
+                           probed_ifaces[i].ip.s_addr != loopback_ip.s_addr) {
+                               add_interface(probed_ifaces[i].ip, 
+                                             probed_ifaces[i].netmask);
+                       }
+               }
+               return;
+       }
+
+       while (next_token(&ptr,token,NULL,sizeof(token))) {
+               interpret_interface(token);
+       }
+
+       if (!local_interfaces) {
+               DEBUG(0,("WARNING: no network interfaces found\n"));
+       }
 }
 
 
 /****************************************************************************
-  override the defaults
-  **************************************************************************/
-void iface_set_default(char *ip,char *bcast,char *nmask)
+return True if the list of probed interfaces has changed
+****************************************************************************/
+BOOL interfaces_changed(void)
 {
-  if (ip) {
-    got_ip = True;
-    default_ip = *interpret_addr2(ip);
-  }
-
-  if (bcast) {
-    got_bcast = True;
-    default_bcast = *interpret_addr2(bcast);
-  }
-
-  if (nmask) {
-    got_nmask = True;
-    default_nmask = *interpret_addr2(nmask);
-  }
+       int n;
+       struct iface_struct ifaces[MAX_INTERFACES];
+
+       n = get_interfaces(ifaces, MAX_INTERFACES);
+
+       if (n != total_probed ||
+           memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n)) {
+               return True;
+       }
+       
+       return False;
 }
 
 
@@ -253,10 +248,10 @@ void iface_set_default(char *ip,char *bcast,char *nmask)
   **************************************************************************/
 BOOL ismyip(struct in_addr ip)
 {
-  struct interface *i;
-  for (i=local_interfaces;i;i=i->next)
-    if (ip_equal(i->ip,ip)) return True;
-  return False;
+       struct interface *i;
+       for (i=local_interfaces;i;i=i->next)
+               if (ip_equal(i->ip,ip)) return True;
+       return False;
 }
 
 /****************************************************************************
@@ -264,11 +259,13 @@ BOOL ismyip(struct in_addr ip)
   **************************************************************************/
 BOOL is_local_net(struct in_addr from)
 {
-  struct interface *i;
-  for (i=local_interfaces;i;i=i->next)
-    if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
-      return True;
-  return False;
+       struct interface *i;
+       for (i=local_interfaces;i;i=i->next) {
+               if((from.s_addr & i->nmask.s_addr) == 
+                  (i->ip.s_addr & i->nmask.s_addr))
+                       return True;
+       }
+       return False;
 }
 
 /****************************************************************************
@@ -276,12 +273,12 @@ BOOL is_local_net(struct in_addr from)
   **************************************************************************/
 int iface_count(void)
 {
-  int ret = 0;
-  struct interface *i;
+       int ret = 0;
+       struct interface *i;
 
-  for (i=local_interfaces;i;i=i->next)
-    ret++;
-  return ret;
+       for (i=local_interfaces;i;i=i->next)
+               ret++;
+       return ret;
 }
 
 /****************************************************************************
@@ -289,12 +286,12 @@ int iface_count(void)
   **************************************************************************/
 BOOL we_are_multihomed(void)
 {
-  static int multi = -1;
+       static int multi = -1;
 
-  if(multi == -1)
-    multi = (iface_count() > 1 ? True : False);
-
-  return multi;
+       if(multi == -1)
+               multi = (iface_count() > 1 ? True : False);
+       
+       return multi;
 }
 
 /****************************************************************************
@@ -302,13 +299,13 @@ BOOL we_are_multihomed(void)
   **************************************************************************/
 struct interface *get_interface(int n)
 { 
-  struct interface *i;
+       struct interface *i;
   
-  for (i=local_interfaces;i && n;i=i->next)
-    n--;
+       for (i=local_interfaces;i && n;i=i->next)
+               n--;
 
-  if (i) return i;
-  return NULL;
+       if (i) return i;
+       return NULL;
 }
 
 /****************************************************************************
@@ -316,27 +313,27 @@ struct interface *get_interface(int n)
   **************************************************************************/
 struct in_addr *iface_n_ip(int n)
 {
-  struct interface *i;
+       struct interface *i;
   
-  for (i=local_interfaces;i && n;i=i->next)
-    n--;
+       for (i=local_interfaces;i && n;i=i->next)
+               n--;
 
-  if (i) return &i->ip;
-  return NULL;
+       if (i) return &i->ip;
+       return NULL;
 }
 
 /****************************************************************************
-Try and find an interface that matches an ip. If we cannot, return NULL
+  return bcast of the Nth interface
   **************************************************************************/
-static struct interface *iface_find(struct in_addr ip)
+struct in_addr *iface_n_bcast(int n)
 {
-  struct interface *i;
-  if (zero_ip(ip)) return local_interfaces;
-
-  for (i=local_interfaces;i;i=i->next)
-    if (same_net(i->ip,ip,i->nmask)) return i;
+       struct interface *i;
+  
+       for (i=local_interfaces;i && n;i=i->next)
+               n--;
 
-  return NULL;
+       if (i) return &i->bcast;
+       return NULL;
 }
 
 
@@ -368,15 +365,12 @@ unsigned iface_hash(void)
 
 struct in_addr *iface_bcast(struct in_addr ip)
 {
-  struct interface *i = iface_find(ip);
-  return(i ? &i->bcast : &local_interfaces->bcast);
+       struct interface *i = iface_find(ip);
+       return(i ? &i->bcast : &local_interfaces->bcast);
 }
 
 struct in_addr *iface_ip(struct in_addr ip)
 {
-  struct interface *i = iface_find(ip);
-  return(i ? &i->ip : &local_interfaces->ip);
+       struct interface *i = iface_find(ip);
+       return(i ? &i->ip : &local_interfaces->ip);
 }
-
-
-
index 871a4a059c897a707ce13495c5e98b843b16ae1d..1983bb11619a452766cf4998dc30ad663b7bc64e 100644 (file)
@@ -377,7 +377,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 +412,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 +445,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 +496,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 +550,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 +613,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 +672,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 +740,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 +749,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 +805,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 +872,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 +897,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 +934,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 +965,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);
index 56c9e02ffbef0c63e10f5eb97a899801e68acd78..30f2b6b8c6b6848f354b4a8458d1537da60010b3 100644 (file)
@@ -101,7 +101,7 @@ static void mdfour64(uint32 *M)
                X[j] = 0;
 }
 
-static void copy64(uint32 *M, const unsigned char *in)
+static void copy64(uint32 *M, unsigned char *in)
 {
        int i;
 
@@ -119,7 +119,7 @@ static void copy4(unsigned char *out,uint32 x)
 }
 
 /* produce a md4 message digest from data of length n bytes */
-void mdfour(unsigned char *out, const unsigned char *in, int n)
+void mdfour(unsigned char *out, unsigned char *in, int n)
 {
        unsigned char buf[128];
        uint32 M[16];
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..6a492f977c3b1044aaea0e570661123cb9413930 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++) {
@@ -168,7 +168,6 @@ Corrections by richard.kettlewell@kewill.com
        struct group *g;
        char   *gr;
        
-       setgrent();
        grouplst[0] = id;
        i = 1;
        while (i < NGROUPS_MAX && 
@@ -188,7 +187,7 @@ Corrections by richard.kettlewell@kewill.com
                }
        }
        endgrent();
-       return(setgroups(i,grouplst));
+       return(sys_setgroups(i,grouplst));
 #endif /* HAVE_SETGROUPS */
 }
 #endif /* HAVE_INITGROUPS */
index bb1c6fe189b5d98ea3d9bb554b16b6370593b494..5651e942d78db1cd06407bde92e676f6ea9782f3 100644 (file)
 
 #include "includes.h"
 
-
 /****************************************************************************
-catch child exits
+ Catch child exits and reap the child zombie status.
 ****************************************************************************/
+
 static void sig_cld(int signum)
 {
-       while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0) ;
+       while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0)
+               ;
+
+       /*
+        * Turns out it's *really* important not to
+        * restore the signal handler here if we have real POSIX
+        * signal handling. If we do, then we get the signal re-delivered
+        * immediately - hey presto - instant loop ! JRA.
+        */
 
+#if !defined(HAVE_SIGACTION)
        CatchSignal(SIGCLD, sig_cld);
+#endif
 }
 
+/****************************************************************************
+catch child exits - leave status;
+****************************************************************************/
 
+static void sig_cld_leave_status(int signum)
+{
+       /*
+        * Turns out it's *really* important not to
+        * restore the signal handler here if we have real POSIX
+        * signal handling. If we do, then we get the signal re-delivered
+        * immediately - hey presto - instant loop ! JRA.
+        */
+
+#if !defined(HAVE_SIGACTION)
+       CatchSignal(SIGCLD, sig_cld_leave_status);
+#else
+       ;
+#endif
+}
 
 /*******************************************************************
-block sigs
+ Block sigs.
 ********************************************************************/
+
 void BlockSignals(BOOL block,int signum)
 {
 #ifdef HAVE_SIGPROCMASK
@@ -63,14 +92,13 @@ void BlockSignals(BOOL block,int signum)
 #endif
 }
 
-
-
 /*******************************************************************
-catch a signal. This should implement the following semantics:
+ Catch a signal. This should implement the following semantics:
 
-1) the handler remains installed after being called
-2) the signal should be blocked during handler execution
+ 1) The handler remains installed after being called.
+ 2) The signal should be blocked during handler execution.
 ********************************************************************/
+
 void CatchSignal(int signum,void (*handler)(int ))
 {
 #ifdef HAVE_SIGACTION
@@ -80,23 +108,35 @@ void CatchSignal(int signum,void (*handler)(int ))
 
        act.sa_handler = handler;
 #ifdef SA_RESTART
-       act.sa_flags = SA_RESTART;
+       /*
+        * We *want* SIGALRM to interrupt a system call.
+        */
+       if(signum != SIGALRM)
+               act.sa_flags = SA_RESTART;
 #endif
        sigemptyset(&act.sa_mask);
        sigaddset(&act.sa_mask,signum);
        sigaction(signum,&act,NULL);
-#else
+#else /* !HAVE_SIGACTION */
        /* FIXME: need to handle sigvec and systems with broken signal() */
        signal(signum, handler);
 #endif
 }
 
-
-
 /*******************************************************************
-ignore SIGCLD via whatever means is necessary for this OS
+ Ignore SIGCLD via whatever means is necessary for this OS.
 ********************************************************************/
+
 void CatchChild(void)
 {
        CatchSignal(SIGCLD, sig_cld);
 }
+
+/*******************************************************************
+ Catch SIGCLD but leave the child around so it's status can be reaped.
+********************************************************************/
+
+void CatchChildLeaveStatus(void)
+{
+       CatchSignal(SIGCLD, sig_cld_leave_status);
+}
index da7632a67a9d66461b5911499dd394615334d171..5a016cd5cd8bc38ba85b843f0e554f58aacfacb2 100644 (file)
@@ -28,7 +28,7 @@ extern int DEBUGLEVEL;
 
 /****************************************************************************
 This is a utility function of smbrun(). It must be called only from
-the child as it may leave the caller in a privilaged state.
+the child as it may leave the caller in a privileged state.
 ****************************************************************************/
 static BOOL setup_stdout_file(char *outfile,BOOL shared)
 {  
@@ -40,14 +40,9 @@ static BOOL setup_stdout_file(char *outfile,BOOL shared)
   close(1);
 
   if (shared) {
-         /* become root - unprivilaged users can't delete these files */
-#ifdef HAVE_SETRESUID
-         setresgid(0,0,0);
-         setresuid(0,0,0);
-#else      
-         setuid(0);
-         seteuid(0);
-#endif
+       /* become root - unprivileged users can't delete these files */
+       gain_root_privilege();
+       gain_root_group_privilege();
   }
 
   if(sys_stat(outfile, &st) == 0) {
@@ -85,9 +80,10 @@ if shared is not set then open the file with O_EXCL set
 ****************************************************************************/
 int smbrun(char *cmd,char *outfile,BOOL shared)
 {
-       int fd,pid;
-       int uid = current_user.uid;
-       int gid = current_user.gid;
+       int fd;
+       pid_t pid;
+       uid_t uid = current_user.uid;
+       gid_t gid = current_user.gid;
 
     /*
      * Lose any kernel oplock capabilities we may have.
@@ -110,7 +106,7 @@ int smbrun(char *cmd,char *outfile,BOOL shared)
        }
 
        slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"",
-                path,uid,gid,cmd,
+                path,(int)uid,(int)gid,cmd,
                 outfile?outfile:"/dev/null");
        
        DEBUG(5,("smbrun - running %s ",syscmd));
@@ -120,17 +116,52 @@ int smbrun(char *cmd,char *outfile,BOOL shared)
 #else
        /* in this newer method we will exec /bin/sh with the correct
           arguments, after first setting stdout to point at the file */
-       
-       if ((pid=fork())) {
+
+       /*
+        * 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(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
+               CatchChild(); 
+               return errno;
+    }
+
+       if (pid) {
+               /*
+                * Parent.
+                */
                int status=0;
+               pid_t wpid;
+
+               
                /* the parent just waits for the child to exit */
-               if (sys_waitpid(pid,&status,0) != pid) {
-                       DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno)));
+               while((wpid = sys_waitpid(pid,&status,0)) < 0) {
+                       if(errno == EINTR) {
+                               errno = 0;
+                               continue;
+                       }
+                       break;
+               }
+
+               CatchChild(); 
+
+               if (wpid != pid) {
+                       DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
                        return -1;
                }
+#if defined(WIFEXITED) && defined(WEXITSTATUS)
+               if (WIFEXITED(status)) {
+                       return WEXITSTATUS(status);
+               }
+#endif
                return status;
        }
        
+       CatchChild(); 
        
        /* we are in the child. we exec /bin/sh to do the work for us. we
           don't directly exec the command we want because it may be a
@@ -141,25 +172,14 @@ int smbrun(char *cmd,char *outfile,BOOL shared)
                exit(80);
        }
        
-       /* now completely lose our privilages. This is a fairly paranoid
+       /* now completely lose our privileges. This is a fairly paranoid
           way of doing it, but it does work on all systems that I know of */
-#ifdef HAVE_SETRESUID
-       setresgid(0,0,0);
-       setresuid(0,0,0);
-       setresgid(gid,gid,gid);
-       setresuid(uid,uid,uid);      
-#else      
-       setuid(0);
-       seteuid(0);
-       setgid(gid);
-       setegid(gid);
-       setuid(uid);
-       seteuid(uid);
-#endif
-       
+
+       become_user_permanently(uid, gid);
+
        if (getuid() != uid || geteuid() != uid ||
            getgid() != gid || getegid() != gid) {
-               /* we failed to lose our privilages - do not execute
+               /* we failed to lose our privileges - do not execute
                    the command */
                exit(81); /* we can't print stuff at this stage,
                             instead use exit codes for debugging */
index 579873264371efda99520c6f63fd7dc301e2b56d..f149d3e6673ad48c7368b4b823f89a22a22e8246 100644 (file)
@@ -581,8 +581,21 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
 {
   int signvalue = 0;
   LDOUBLE ufvalue;
+#ifndef HAVE_FCVT
   char iconvert[20];
   char fconvert[20];
+#else
+  char iconvert[311];
+  char fconvert[311];
+  char *result;
+  int dec_pt, sig;
+  int r_length;
+# ifdef HAVE_FCVTL
+  extern char *fcvtl(long double value, int ndigit, int *decpt, int *sign);
+# else
+  extern char *fcvt(double value, int ndigit, int *decpt, int *sign);
+# endif
+#endif
   int iplace = 0;
   int fplace = 0;
   int padlen = 0; /* amount to pad */
@@ -613,6 +626,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
   if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 #endif
 
+#ifndef HAVE_FCVT
   intpart = (long)ufvalue;
 
   /* 
@@ -655,7 +669,53 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
   } while(fracpart && (fplace < 20));
   if (fplace == 20) fplace--;
   fconvert[fplace] = 0;
+#else  /* use fcvt() */
+  if (max > 310)
+    max = 310;
+# ifdef HAVE_FCVTL
+  result = fcvtl(ufvalue, max, &dec_pt, &sig);
+# else
+  result = fcvt(ufvalue, max, &dec_pt, &sig);
+# endif
+
+  r_length = strlen(result);
+
+  if (r_length == 0)
+    {
+      result[0] = '0';
+      result[1] = '\0';
+      r_length = 1;
+    }
+  
+  if (dec_pt <= 0)
+    {
+    iplace = 1;
+    iconvert[0] = '0';
+    iconvert[1] = '\0';
+
+    fplace = 0;
+
+    while(r_length)
+      fconvert[fplace++] = result[--r_length];
 
+    while(dec_pt < 0)
+      fconvert[fplace++] = '0';
+    }
+  else
+    {
+    int c;
+
+    iplace=0;
+    for(c=dec_pt; c; iconvert[iplace++] = result[--c]);
+    iconvert[iplace] = '\0';
+
+    result += dec_pt;
+    fplace = 0;
+    
+    for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c]);
+    }
+#endif /* fcvt */
+  
   /* -1 for decimal point, another -1 if we are printing a sign */
   padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
   zpadlen = max - fplace;
@@ -791,7 +851,7 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
     NULL
   };
   double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
-    0.9996, 1.996, 4.136, 0};
+    0.9996, 1.996, 4.136, 6442452944.1234, 0};
   char *int_fmt[] = {
     "%-1.5d",
     "%1.5d",
index f9de800bd3d4c6ca5fd8d9ef436f1b51f2264cf9..a59f94a6a962d0507f63c22c3d7a4f64b45663bf 100644 (file)
@@ -60,7 +60,7 @@ static int pollfd(int fd)
   return(r);
 }
 
-int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval)
+int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
 {
   fd_set fds2;
   int counter=0;
@@ -90,7 +90,7 @@ int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval)
 }
 
 #else /* !NO_SELECT */
-int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
+int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
 {
 #ifdef USE_POLL
   struct pollfd pfd[256];
@@ -131,8 +131,7 @@ int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
   do {
     if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
     errno = 0;
-    selrtn = select(maxfd,SELECT_CAST r_fds,SELECT_CAST w_fds,
-                    NULL,tval?&t2:NULL);
+    selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
   } while (selrtn<0 && errno == EINTR);
 
   return(selrtn);
@@ -140,17 +139,55 @@ int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
 #endif /* USE_POLL */
 #endif /* NO_SELECT */
 
+/*******************************************************************
+ A wrapper for usleep in case we don't have one.
+********************************************************************/
+
+int sys_usleep(long usecs)
+{
+#ifndef HAVE_USLEEP
+  struct timeval tval;
+#endif
+
+  /*
+   * We need this braindamage as the glibc usleep
+   * is not SPEC1170 complient... grumble... JRA.
+   */
+
+  if(usecs < 0 || usecs > 1000000) {
+    errno = EINVAL;
+    return -1;
+  }
+
+#if HAVE_USLEEP
+  usleep(usecs);
+  return 0;
+#else /* HAVE_USLEEP */
+  /*
+   * Fake it with select...
+   */
+  tval.tv_sec = 0;
+  tval.tv_usec = usecs/1000;
+  select(0,NULL,NULL,NULL,&tval);
+  return 0;
+#endif /* HAVE_USLEEP */
+}
+
 /*******************************************************************
 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;
 }
 
 /*******************************************************************
@@ -159,11 +196,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;
 }
 
 /*******************************************************************
@@ -172,11 +213,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;
 }
 
 /*******************************************************************
@@ -185,7 +230,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);
@@ -198,7 +243,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);
@@ -211,8 +256,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
@@ -224,8 +271,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
@@ -237,7 +286,7 @@ SMB_OFF_T sys_ftell(FILE *fp)
 
 int sys_creat(const char *path, mode_t mode)
 {
-#if defined(HAVE_CREAT64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
   return creat64(path, mode);
 #else
   /*
@@ -254,7 +303,7 @@ int sys_creat(const char *path, mode_t mode)
 
 int sys_open(const char *path, int oflag, mode_t mode)
 {
-#if defined(HAVE_OPEN64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
   return open64(path, oflag, mode);
 #else
   return open(path, oflag, mode);
@@ -267,26 +316,43 @@ int sys_open(const char *path, int oflag, mode_t mode)
 
 FILE *sys_fopen(const char *path, const char *type)
 {
-#if defined(HAVE_FOPEN64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
   return fopen64(path, type);
 #else
   return fopen(path, 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
 ********************************************************************/
@@ -305,18 +371,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
@@ -413,9 +480,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
@@ -447,9 +517,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
@@ -516,7 +589,8 @@ int sys_getgroups(int setlen, gid_t *gidset)
     return -1;
   } 
 
-  if (setlen == 0) setlen = 1;
+  if (setlen == 0)
+    setlen = 1;
 
   if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
     DEBUG(0,("sys_getgroups: Malloc fail.\n"));
@@ -538,6 +612,62 @@ 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 ;
+
+#ifdef NGROUPS_MAX
+  if (setlen > NGROUPS_MAX) {
+    errno = EINVAL; 
+    return -1;   
+  }
+#endif
+
+  /*
+   * Broken case. We need to allocate a
+   * GID_T array of size setlen.
+   */
+
+  if (setlen == 0)
+    setlen = 1;
+
+  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.
@@ -547,7 +677,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;
@@ -558,25 +688,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);
        }
@@ -590,7 +711,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));
 }
 
 /**************************************************************************
@@ -599,5 +720,5 @@ 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));
 }
index c332b906a0c6b18ca3278d3ed3f8a6e5d6749f5b..5fd260e5c90c0ed03276708f483c6e7447b0a8a6 100644 (file)
@@ -247,7 +247,7 @@ its the GMT you get by taking a localtime and adding the
 serverzone. This is NOT the same as GMT in some cases. This routine
 converts this to real GMT.
 ****************************************************************************/
-time_t nt_time_to_unix(const NTTIME *nt)
+time_t nt_time_to_unix(NTTIME *nt)
 {
   double d;
   time_t ret;
@@ -298,6 +298,13 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
 {
        double d;
 
+       if (t==0)
+       {
+               nt->low = 0;
+               nt->high = 0;
+               return;
+       }
+
        /* this converts GMT to kludge-GMT */
        t -= LocTimeDiff(t) - serverzone; 
 
@@ -309,15 +316,6 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
        nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
 }
 
-/****************************************************************************
-initialise an NTTIME to -1, which means "unknown" or "don't expire"
-****************************************************************************/
-
-void init_nt_time(NTTIME *nt)
-{
-       nt->high = 0x7FFFFFFF;
-       nt->low = 0xFFFFFFFF;
-}
 
 /****************************************************************************
 take an NTTIME structure, containing high / low time.  convert to unix time.
@@ -506,21 +504,57 @@ char *http_timestring(time_t t)
 
 
 /****************************************************************************
 return the date and time as a string
Return the date and time as a string
 ****************************************************************************/
-char *timestring(void )
+
+char *timestring(BOOL hires)
 {
        static fstring TimeBuf;
-       time_t t = time(NULL);
-       struct tm *tm = LocalTime(&t);
+       struct timeval tp;
+       time_t t;
+       struct tm *tm;
 
+       if (hires) {
+               GetTimeOfDay(&tp);
+               t = (time_t)tp.tv_sec;
+       } else {
+               t = time(NULL);
+       }
+       tm = LocalTime(&t);
        if (!tm) {
-               slprintf(TimeBuf,sizeof(TimeBuf)-1,"%ld seconds since the Epoch",(long)t);
+               if (hires) {
+                       slprintf(TimeBuf,
+                                sizeof(TimeBuf)-1,
+                                "%ld.%06ld seconds since the Epoch",
+                                (long)tp.tv_sec, 
+                                (long)tp.tv_usec);
+               } else {
+                       slprintf(TimeBuf,
+                                sizeof(TimeBuf)-1,
+                                "%ld seconds since the Epoch",
+                                (long)t);
+               }
        } else {
 #ifdef HAVE_STRFTIME
-               strftime(TimeBuf,100,"%Y/%m/%d %T",tm);
+               if (hires) {
+                       strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
+                       slprintf(TimeBuf+strlen(TimeBuf),
+                                sizeof(TimeBuf)-1 - strlen(TimeBuf), 
+                                ".%06ld", 
+                                (long)tp.tv_usec);
+               } else {
+                       strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm);
+               }
 #else
-               fstrcpy(TimeBuf, asctime(tm));
+               if (hires)() {
+                       slprintf(TimeBuf, 
+                                sizeof(TimeBuf)-1, 
+                                "%s.%06ld", 
+                                asctime(tm), 
+                                (long)tp.tv_usec);
+               } else {
+                       fstrcpy(TimeBuf, asctime(tm));
+               }
 #endif
        }
        return(TimeBuf);
index 23bdb54faf29a4479068caf9e678723d0e95e1bc..9a189980d5d0f896454043859e13fa6c284c200e 100644 (file)
@@ -27,306 +27,31 @@ static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (
 static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
 
 /****************************************************************************
-  Since getpwnam() makes samba really slow with the NT-domain code
-  (reading /etc/passwd again and again and again), here is an implementation
-  of very simple passwd cache
+ Get a users home directory.
 ****************************************************************************/
-#define PASSWD_HASH_SIZE 1009
-/* The hashtable is rebuild every 15 seconds */
-#define PASSWD_HASH_AGE 15
-struct passwd_hash_entry {
-  int entry;
-  int next;
-};
-
-struct passwd_hash_table_s {
-  struct passwd *passwds;
-  int passwds_size;  
-  int *names;
-  int *uids;
-  struct passwd_hash_entry *entries;
-  int entries_size;
-  struct timeval build_time;
-} passwd_hash_table = {
-  NULL,0,NULL,NULL,NULL,0,{0,0}
-};
-
-static int name_hash_function(const char *name) 
-{
-  /* I guess that there must be better hash functions. This one was the
-   * first to come into mind :) */
-  unsigned int value=0;
-  while (*name) {
-    value=(value<<8)|(unsigned char)(*name);
-    if (value>1048576) value=value%PASSWD_HASH_SIZE;
-    name++;
-  }
-  value=value%PASSWD_HASH_SIZE;
-  return value;
-}
-    
-static int uid_hash_function(uid_t uid) 
-{
-  return uid%PASSWD_HASH_SIZE;
-}
-
 
-static BOOL build_passwd_hash_table(void) 
+char *get_user_home_dir(char *user)
 {
-  struct passwd_hash_table_s *pht=&passwd_hash_table; /* Convenience */
-  int num_passwds=0;
-  int num_entries=0;
-  struct passwd *pass;
-  int i;
-  int name_i,uid_i;
-
-  DEBUG(3,("Building passwd hash table\n"));
-  /* Free the allocated strings in old hash table */
-  for (i=0;i<pht->passwds_size;i++) {
-    free(pht->passwds[i].pw_name); 
-    free(pht->passwds[i].pw_passwd);
-    free(pht->passwds[i].pw_gecos);
-    free(pht->passwds[i].pw_dir);
-    free(pht->passwds[i].pw_shell);    
-  }
-
-  /* Initialize hash table if first table build */
-  if (pht->passwds_size==0) {
-    DEBUG(3,("Building passwd hash table for the first time\n"));
-    pht->passwds=malloc(sizeof(struct passwd)*64); /* A reasonable default */
-    pht->passwds_size=64;
-  }
-  if (pht->names==NULL) {
-    pht->names=malloc(sizeof(struct passwd_hash_entry *)*PASSWD_HASH_SIZE);
-  }
-  if (pht->uids==NULL) {
-    pht->uids=malloc(sizeof(struct passwd_hash_entry *)*PASSWD_HASH_SIZE);
-  }
-  if (pht->entries==NULL) {
-    pht->entries=malloc(sizeof(struct passwd_hash_entry)*128);
-    pht->entries_size=128;
-  }
-  if (pht->passwds==NULL || pht->names==NULL || 
-      pht->uids==NULL || pht->entries==NULL) {
-    goto fail;
-  }
-  
-  /* Clear out the hash table */
-  for(i=0;i<PASSWD_HASH_SIZE;i++) pht->uids[i]=-1;
-  for(i=0;i<PASSWD_HASH_SIZE;i++) pht->names[i]=-1;
-
-  /* Now do the build */
-  setpwent();
-
-  while((pass=getpwent())) {
-
-    /* Check that we have enough space */
-    if (num_passwds==pht->passwds_size) {
-      struct passwd *new_passwds=NULL;
-      pht->passwds_size+=pht->passwds_size/2;
-      new_passwds=realloc(pht->passwds,
-                          sizeof(struct passwd)*pht->passwds_size);
-      if (new_passwds==NULL) goto fail;
-      pht->passwds=new_passwds;
-    }
-    if (num_entries+1>=pht->entries_size) {
-      pht->entries_size+=pht->entries_size/2;
-      pht->entries=realloc(pht->entries,
-                          sizeof(struct passwd_hash_entry)*pht->entries_size);
-      if (pht->entries==NULL) goto fail;
-    }
+  static struct passwd *pass;
 
-    /* Copy the passwd struct */
-    memset(&pht->passwds[num_passwds],0,sizeof(struct passwd));
-    pht->passwds[num_passwds].pw_uid=pass->pw_uid;
-    pht->passwds[num_passwds].pw_gid=pass->pw_gid;  
-    if (
-       (pht->passwds[num_passwds].pw_name=strdup(pass->pw_name))==NULL ||
-       (pht->passwds[num_passwds].pw_passwd=strdup(pass->pw_passwd))==NULL ||
-       (pht->passwds[num_passwds].pw_gecos=strdup(pass->pw_gecos))==NULL ||
-       (pht->passwds[num_passwds].pw_dir=strdup(pass->pw_dir))==NULL ||
-       (pht->passwds[num_passwds].pw_shell=strdup(pass->pw_shell))==NULL ) {
-      num_passwds++;
-      goto fail;
-    }
-    
-    /* Add to the hash table */
-    /* Add the name */
-    pht->entries[num_entries].entry=num_passwds;
-    name_i=name_hash_function(pass->pw_name);
-    pht->entries[num_entries].next=pht->names[name_i];
-    pht->names[name_i]=num_entries;
-    num_entries++;
-    /* Add the uid */
-    pht->entries[num_entries].entry=num_passwds;
-    uid_i=uid_hash_function(pass->pw_uid);
-    pht->entries[num_entries].next=pht->uids[uid_i];
-    pht->uids[uid_i]=num_entries;
-    num_entries++;
-
-    /* This entry has been done */
-    num_passwds++;
-  }    
-  endpwent();
-  
-  if (pht->passwds_size>num_passwds) {
-    struct passwd *passwds;
-    passwds=realloc(pht->passwds,sizeof(pht->passwds[0])*num_passwds);
-    if (passwds==NULL) goto fail;
-    pht->passwds=passwds;
-    pht->passwds_size=num_passwds;
-  }
-  if (pht->entries_size>num_entries) {
-    struct passwd_hash_entry *entries;
-    entries=realloc(pht->entries,sizeof(pht->entries[0])*num_entries);
-    if (entries==NULL) goto fail;
-    pht->entries=entries;
-    pht->entries_size=num_entries;
-  }
+  pass = Get_Pwnam(user, False);
 
-  /* Mark the creation time */
-  GetTimeOfDay(&pht->build_time);
-  /* Everything went smoothly. */
-  return True;
-
- fail:
-  DEBUG(0,("Failed to create passwd hash table: %s",strerror(errno)));
-  /* OK: now the untested part. Normally this should never happen:
-   * Only running out of memory could cause this and even then
-   * we have enough trouble already. */
-  while (num_passwds>0) {
-    num_passwds--;
-    free(pht->passwds[num_passwds].pw_name);
-    free(pht->passwds[num_passwds].pw_passwd);
-    free(pht->passwds[num_passwds].pw_gecos);
-    free(pht->passwds[num_passwds].pw_dir);
-    free(pht->passwds[num_passwds].pw_shell);    
-  }
-  free(pht->entries);
-  free(pht->uids);
-  free(pht->names);
-  free(pht->passwds);
-  pht->passwds_size=0;
-  pht->entries_size=0;    
-  /* Also mark fail time, so that retry will happen after PASSWD_HASH_AGE */
-  GetTimeOfDay(&pht->build_time);
-  return False;
+  if (!pass) return(NULL);
+  return(pass->pw_dir);      
 }
 
-static BOOL have_passwd_hash(void)
-{
-  struct passwd_hash_table_s *pht=&passwd_hash_table;
-  struct timeval tv;
-  GetTimeOfDay(&tv);
-  /* I'm ignoring microseconds. If you think they matter, go ahead
-   * and implement them */
-  if (tv.tv_sec - pht->build_time.tv_sec > PASSWD_HASH_AGE) {
-    return build_passwd_hash_table();
-  }
-  return pht->passwds_size>0;
-}
-
-struct passwd *hashed_getpwnam(const char *name)
-{
-  struct passwd_hash_table_s *pht=&passwd_hash_table;
-
-  DEBUG(5,("getpwnam(%s)\n", name));
-
-  if (have_passwd_hash())
-  {
-    int name_i=name_hash_function(name);
-    int hash_index=pht->names[name_i];
-    while(hash_index!=-1) {
-      struct passwd *pass=&pht->passwds[pht->entries[hash_index].entry];
-      if (strcmp(name,pass->pw_name)==0) {
-       DEBUG(5,("Found: %s:%s:%d:%d:%s:%s:%s\n",
-                pass->pw_name,
-                pass->pw_passwd,
-                pass->pw_uid,
-                pass->pw_gid,
-                pass->pw_gecos,
-                pass->pw_dir,
-                pass->pw_shell));
-       return copy_passwd_struct(pass);      
-      }
-      hash_index=pht->entries[hash_index].next;
-    }
-
-    /* Not found */
-    DEBUG(5,("%s not found\n",name));
-    return NULL;
-  } 
-
-  /* Fall back to real getpwnam() */
-  return sys_getpwnam(name);
-}
 
 /*******************************************************************
-turn a uid into a user name
+ Map a username from a dos name to a unix name by looking in the username
+ map. Note that this modifies the name in place.
+ This is the main function that should be called *once* on
+ any incoming or new username - in order to canonicalize the name.
+ This is being done to de-couple the case conversions from the user mapping
+ function. Previously, the map_username was being called
+ every time Get_Pwnam was called.
+ Returns True if username was changed, false otherwise.
 ********************************************************************/
-char *uidtoname(uid_t uid)
-{
-  static char name[40];
-  struct passwd_hash_table_s *pht=&passwd_hash_table;
-  struct passwd *pass=NULL;
-
-  DEBUG(5,("uidtoname(%d)\n",uid));
-  if (have_passwd_hash()) {
-    int hash_index=pht->uids[uid_hash_function(uid)];
-    while(hash_index!=-1) {
-      pass=&pht->passwds[pht->entries[hash_index].entry];
-      if (pass->pw_uid==uid) {
-       DEBUG(5,("Found: %s:%s:%d:%d:%s:%s:%s\n",
-                pass->pw_name,
-                pass->pw_passwd,
-                pass->pw_uid,
-                pass->pw_gid,
-                pass->pw_gecos,
-                pass->pw_dir,
-                pass->pw_shell));
-       return pass->pw_name;      
-      }
-      hash_index=pht->entries[hash_index].next;
-    }
-    DEBUG(5,("Hash miss"));
-    pass=NULL;
-  } else {
-    /* No hash table, fall back to getpwuid */
-    pass = getpwuid(uid);
-  }
-  if (pass) return(pass->pw_name);
-  slprintf(name, sizeof(name) - 1, "%d",(int)uid);
-  return(name);
-}
-
-/****************************************************************************
-get a users home directory.
-****************************************************************************/
-char *get_unixhome_dir(char *user)
-{
-       const struct passwd *pass;
-       static pstring home_dir;
 
-       pass = Get_Pwnam(user, False);
-
-       if (pass == NULL || pass->pw_dir == NULL) return(NULL);
-
-       pstrcpy(home_dir, pass->pw_dir);
-       DEBUG(10,("get_smbhome_dir: returning %s for user %s\n", home_dir, user));
-       return home_dir;
-}
-
-
-/*******************************************************************
-map a username from a dos name to a unix name by looking in the username
-map. Note that this modifies the name in place.
-This is the main function that should be called *once* on
-any incoming or new username - in order to canonicalize the name.
-This is being done to de-couple the case conversions from the user mapping
-function. Previously, the map_username was being called
-every time Get_Pwnam was called.
-Returns True if username was changed, false otherwise.
-********************************************************************/
 BOOL map_username(char *user)
 {
   static BOOL initialised=False;
@@ -420,38 +145,36 @@ BOOL map_username(char *user)
   return mapped_user;
 }
 
-
 /****************************************************************************
  Get_Pwnam wrapper
 ****************************************************************************/
+
 static struct passwd *_Get_Pwnam(char *s)
 {
-       struct passwd *ret;
+  struct passwd *ret;
 
-       ret = hashed_getpwnam(s);
+  ret = sys_getpwnam(s);
+  if (ret) {
 #ifdef HAVE_GETPWANAM
-       if (ret)
-       {
-               struct passwd_adjunct *pwret;
-               pwret = getpwanam(s);
-               if (pwret != NULL && pwret->pwa_passwd != NULL)
-               {
-                       pstrcpy(ret->pw_passwd, pwret->pwa_passwd);
-               }
-       }
+    struct passwd_adjunct *pwret;
+    pwret = getpwanam(s);
+    if (pwret && pwret->pwa_passwd) {
+      pstrcpy(ret->pw_passwd,pwret->pwa_passwd);
+    }
 #endif
+  }
 
-       return ret;
+  return(ret);
 }
 
+
 /****************************************************************************
-a wrapper for getpwnam() that tries with all lower and all upper case 
-if the initial name fails. Also tried with first letter capitalised
-Note that this can change user!  Function returns const to emphasise
-the fact that most of the members of the struct passwd * returned are
-dynamically allocated.
+ A wrapper for getpwnam() that tries with all lower and all upper case 
+ if the initial name fails. Also tried with first letter capitalised
+ Note that this can change user!
 ****************************************************************************/
-const struct passwd *Get_Pwnam(char *user,BOOL allow_change)
+
+struct passwd *Get_Pwnam(char *user,BOOL allow_change)
 {
   fstring user2;
   int last_char;
@@ -469,33 +192,39 @@ const struct passwd *Get_Pwnam(char *user,BOOL allow_change)
   }
 
   ret = _Get_Pwnam(user);
-  if (ret) return(ret);
+  if (ret)
+    return(ret);
 
   strlower(user);
   ret = _Get_Pwnam(user);
-  if (ret)  return(ret);
+  if (ret)
+    return(ret);
 
   strupper(user);
   ret = _Get_Pwnam(user);
-  if (ret) return(ret);
+  if (ret)
+    return(ret);
 
-  /* try with first letter capitalised */
+  /* Try with first letter capitalised. */
   if (strlen(user) > 1)
     strlower(user+1);  
   ret = _Get_Pwnam(user);
-  if (ret) return(ret);
+  if (ret)
+    return(ret);
 
   /* try with last letter capitalised */
   strlower(user);
   last_char = strlen(user)-1;
   user[last_char] = toupper(user[last_char]);
   ret = _Get_Pwnam(user);
-  if (ret) return(ret);
+  if (ret)
+    return(ret);
 
-  /* try all combinations up to usernamelevel */
+  /* Try all combinations up to usernamelevel. */
   strlower(user);
   ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
-  if (ret) return(ret);
+  if (ret)
+    return(ret);
 
   if (allow_change)
     fstrcpy(user,user2);
@@ -504,8 +233,9 @@ const struct passwd *Get_Pwnam(char *user,BOOL allow_change)
 }
 
 /****************************************************************************
-check if a user is in a netgroup user list
+ Check if a user is in a netgroup user list.
 ****************************************************************************/
+
 static BOOL user_in_netgroup_list(char *user,char *ngname)
 {
 #ifdef HAVE_NETGROUP
@@ -513,12 +243,9 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
   if (mydomain == NULL)
     yp_get_default_domain(&mydomain);
 
-  if(mydomain == NULL)
-  {
+  if(mydomain == NULL) {
     DEBUG(5,("Unable to get default yp domain\n"));
-  }
-  else
-  {
+  } else {
     DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
           user, mydomain, ngname));
     DEBUG(5,("innetgr is %s\n",
@@ -533,78 +260,51 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
 }
 
 /****************************************************************************
-check if a user is in a UNIX user list
+ Check if a user is in a UNIX user list.
 ****************************************************************************/
+
 static BOOL user_in_group_list(char *user,char *gname)
 {
-#ifdef HAVE_GETGRNAM 
-  struct group *gptr;
-  char **member;  
-  const struct passwd *pass = Get_Pwnam(user,False);
-
-  if (pass)
-  { 
-    gptr = getgrgid(pass->pw_gid);
-    if (gptr && strequal(gptr->gr_name,gname))
-      return(True); 
-  } 
-
-  gptr = (struct group *)getgrnam(gname);
-
-  if (gptr)
-  {
-    member = gptr->gr_mem;
-    while (member && *member)
-    {
-      if (strequal(*member,user))
-        return(True);
-      member++;
-    }
-  }
+#ifdef HAVE_GETGRENT
+       struct group *gptr;
+       char **member;  
+       struct passwd *pass = Get_Pwnam(user,False);
+
+       if (pass) { 
+               gptr = getgrgid(pass->pw_gid);
+               if (gptr && strequal(gptr->gr_name,gname))
+                       return(True); 
+       } 
+
+       while ((gptr = (struct group *)getgrent())) {
+               if (!strequal(gptr->gr_name,gname))
+                       continue;
+               member = gptr->gr_mem;
+               while (member && *member) {
+                       if (strequal(*member,user)) {
+                               endgrent();
+                               return(True);
+                       }
+                       member++;
+               }
+       }
+
+       endgrent();
 #endif /* HAVE_GETGRNAM */
-  return False;
+       return False;
 }            
 
 /****************************************************************************
-check if a username is valid
+ Check if a user is in a user list - can check combinations of UNIX
+ and netgroup lists.
 ****************************************************************************/
-BOOL user_ok(char *user,int snum)
-{
-       pstring valid, invalid;
-       BOOL ret;
-
-       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));
-       
-       ret = !user_in_list(user,invalid);
-       
-       if (ret && valid && *valid) {
-               ret = user_in_list(user,valid);
-       }
-
-       if (ret && lp_onlyuser(snum)) {
-               char *user_list = lp_username(snum);
-               string_sub(user_list,"%S",lp_servicename(snum));
-               ret = user_in_list(user,user_list);
-       }
 
-       return(ret);
-}
-
-/****************************************************************************
-check if a user is in a user list - can check combinations of UNIX
-and netgroup lists.
-****************************************************************************/
 BOOL user_in_list(char *user,char *list)
 {
   pstring tok;
   char *p=list;
 
-  while (next_token(&p,tok,LIST_SEP, sizeof(tok)))
-  {
+  while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
     /*
      * Check raw username.
      */
@@ -616,8 +316,7 @@ BOOL user_in_list(char *user,char *list)
      * of UNIX and netgroups has been specified.
      */
 
-    if(*tok == '@')
-    {
+    if(*tok == '@') {
       /*
        * Old behaviour. Check netgroup list
        * followed by UNIX list.
@@ -626,11 +325,9 @@ BOOL user_in_list(char *user,char *list)
         return True;
       if(user_in_group_list(user,&tok[1]))
         return True;
-    }
-    else if (*tok == '+')
-    {
-      if(tok[1] == '&')
-      {
+    } else if (*tok == '+') {
+
+      if(tok[1] == '&') {
         /*
          * Search UNIX list followed by netgroup.
          */
@@ -638,20 +335,20 @@ BOOL user_in_list(char *user,char *list)
           return True;
         if(user_in_netgroup_list(user,&tok[2]))
           return True;
-      }
-      else
-      {
+
+      } else {
+
         /*
          * Just search UNIX list.
          */
+
         if(user_in_group_list(user,&tok[1]))
           return True;
       }
-    }
-    else if (*tok == '&')
-    {
-      if(tok[1] == '&')
-      {
+
+    } else if (*tok == '&') {
+
+      if(tok[1] == '+') {
         /*
          * Search netgroup list followed by UNIX list.
          */
@@ -659,9 +356,7 @@ BOOL user_in_list(char *user,char *list)
           return True;
         if(user_in_group_list(user,&tok[2]))
           return True;
-      }
-      else
-      {
+      } else {
         /*
          * Just search netgroup list.
          */
@@ -675,15 +370,16 @@ BOOL user_in_list(char *user,char *list)
 
 /* The functions below have been taken from password.c and slightly modified */
 /****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
+ Apply a function to upper/lower case combinations
+ of a string and return true if one of them returns true.
+ Try all combinations with N uppercase letters.
+ offset is the first char to try and change (start with 0)
+ it assumes the string starts lowercased
 ****************************************************************************/
+
 static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(char *),int N)
 {
-  int len = strlen(s);
+  ssize_t len = (ssize_t)strlen(s);
   int i;
   struct passwd *ret;
 
@@ -694,36 +390,36 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
   if (N <= 0 || offset >= len)
     return(fn(s));
 
-
-  for (i=offset;i<(len-(N-1));i++)
-
-    {
-      char c = s[i];
-      if (!islower(c)) continue;
-      s[i] = toupper(c);
-      ret = uname_string_combinations2(s,i+1,fn,N-1);
-      if(ret) return(ret);
-      s[i] = c;
-    }
+  for (i=offset;i<(len-(N-1));i++) {
+    char c = s[i];
+    if (!islower(c))
+      continue;
+    s[i] = toupper(c);
+    ret = uname_string_combinations2(s,i+1,fn,N-1);
+    if(ret)
+      return(ret);
+    s[i] = c;
+  }
   return(NULL);
 }
 
 /****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with up to N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
+ Apply a function to upper/lower case combinations
+ of a string and return true if one of them returns true.
+ Try all combinations with up to N uppercase letters.
+ offset is the first char to try and change (start with 0)
+ it assumes the string starts lowercased
 ****************************************************************************/
+
 static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(char *),int N)
 {
   int n;
   struct passwd *ret;
 
-  for (n=1;n<=N;n++)
-  {
+  for (n=1;n<=N;n++) {
     ret = uname_string_combinations2(s,0,fn,n);
-    if(ret) return(ret);
+    if(ret)
+      return(ret);
   }
   return(NULL);
 }
index 25769298be446b917e35c9211c94aa26b55c63b9..8f904d486da005483b6a7de67763ce5e81f90828 100644 (file)
 
 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
 #ifdef WITH_NISPLUS_HOME
-#include <rpcsvc/nis.h>
-#else
-#include "rpcsvc/ypclnt.h"
+#ifdef BROKEN_NISPLUS_INCLUDE_FILES
+/*
+ * The following lines are needed due to buggy include files
+ * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
+ * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
+ * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
+ * an enum in /usr/include/rpcsvc/nis.h.
+ */
+
+#if defined(GROUP)
+#undef GROUP
 #endif
+
+#if defined(GROUP_OBJ)
+#undef GROUP_OBJ
 #endif
 
+#endif /* BROKEN_NISPLUS_INCLUDE_FILES */
+
+#include <rpcsvc/nis.h>
+
+#else /* !WITH_NISPLUS_HOME */
+
+#include "rpcsvc/ypclnt.h"
+
+#endif /* WITH_NISPLUS_HOME */
+#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
+
 #ifdef WITH_SSL
 #include <ssl.h>
 #undef Realloc  /* SSLeay defines this and samba has a function of this name */
@@ -71,8 +93,7 @@ fstring local_machine="";
 fstring remote_arch="UNKNOWN";
 static enum remote_arch_types ra_type = RA_UNKNOWN;
 fstring remote_proto="UNKNOWN";
-pstring myhostname="";
-pstring user_socket_options="";   
+pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;   
 
 pstring sesssetup_user="";
 pstring samlogon_user="";
@@ -85,23 +106,7 @@ char **my_netbios_names;
 
 static char *filename_dos(char *path,char *buf);
 
-char *daynames[] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
-char *daynames_short[] = {"M", "Tu", "W", "Th", "F", "Sa", "Su"};
-
-/*************************************************************
- initialise password databases, domain names, domain sid.
-**************************************************************/
-BOOL init_myworkgroup(void)
-{
-       fstrcpy(global_myworkgroup, lp_workgroup());
 
-       if (strequal(global_myworkgroup,"*"))
-       {
-               DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
-               return False;
-       }
-       return True;
-}
 
 /****************************************************************************
   find a suitable temporary directory. The result should be copied immediately
@@ -134,40 +139,20 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
 }
 
 
-/****************************************************************************
-gets either a hex number (0xNNN) or decimal integer (NNN).
-****************************************************************************/
-uint32 get_number(const char *tmp)
-{
-       if (strnequal(tmp, "0x", 2))
-       {
-               return strtoul(tmp, (char**)NULL, 16);
-       }
-       else
-       {
-               return strtoul(tmp, (char**)NULL, 10);
-       }
-}
-
 /****************************************************************************
 like atoi but gets the value up to the separater character
 ****************************************************************************/
 char *Atoic(char *p, int *n, char *c)
 {
-       if (!isdigit(*p))
+       if (!isdigit((int)*p))
        {
                DEBUG(5, ("Atoic: malformed number\n"));
                return NULL;
        }
 
-       (*n) = (int)get_number(p);
+       (*n) = atoi(p);
 
-       if (strnequal(p, "0x", 2))
-       {
-               p += 2;
-       }
-
-       while ((*p) && isdigit(*p))
+       while ((*p) && isdigit((int)*p))
        {
                p++;
        }
@@ -181,19 +166,6 @@ char *Atoic(char *p, int *n, char *c)
        return p;
 }
 
-uint32 *add_num_to_list(uint32 **num, int *count, int val)
-{
-       (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
-       if ((*num) == NULL)
-       {
-               return NULL;
-       }
-       (*num)[(*count)] = val;
-       (*count)++;
-
-       return (*num);
-}
-
 /*************************************************************************
  reads a list of numbers
  *************************************************************************/
@@ -211,10 +183,13 @@ char *get_numlist(char *p, uint32 **num, int *count)
 
        while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
        {
-               if (add_num_to_list(num, count, val) == NULL)
+               (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
+               if ((*num) == NULL)
                {
                        return NULL;
                }
+               (*num)[(*count)] = val;
+               (*count)++;
                p++;
        }
 
@@ -357,7 +332,7 @@ int name_mangle( char *In, char *Out, char name_type )
       case '.':
         p[0] = len;
         p   += (len + 1);
-        len  = 0;
+        len  = -1;
         break;
       default:
         p[len+1] = scope[i];
@@ -382,21 +357,6 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
   return(S_ISREG(sbuf->st_mode));
 }
 
-/*******************************************************************
-  rename a unix file
-********************************************************************/
-int file_rename(char *from, char *to)
-{
-       int rcode = rename (from, to);
-
-       if (errno == EXDEV) 
-       {
-               /* Rename across filesystems needed. */
-               rcode = copy_reg (from, to);        
-       }
-       return rcode;
-}
-
 /*******************************************************************
 check a files mod time
 ********************************************************************/
@@ -432,7 +392,7 @@ BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
 /*******************************************************************
 returns the size in bytes of the named file
 ********************************************************************/
-SMB_OFF_T file_size(char *file_name)
+SMB_OFF_T get_file_size(char *file_name)
 {
   SMB_STRUCT_STAT buf;
   buf.st_size = 0;
@@ -460,6 +420,8 @@ char *attrib_string(uint16 mode)
   return(attrstr);
 }
 
+
+
 /****************************************************************************
   make a file into unix format
 ****************************************************************************/
@@ -558,7 +520,7 @@ void smb_setlen(char *buf,int len)
 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
 {
   if (zero)
-    bzero(buf + smb_size,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);
@@ -605,8 +567,6 @@ int smb_offset(char *p,char *buf)
   return(PTR_DIFF(p,buf+4) + chain_size);
 }
 
-
-
 /*******************************************************************
 reduce a file name, removing .. elements.
 ********************************************************************/
@@ -617,7 +577,7 @@ void dos_clean_name(char *s)
   DEBUG(3,("dos_clean_name [%s]\n",s));
 
   /* remove any double slashes */
-  string_sub(s, "\\\\", "\\");
+  all_string_sub(s, "\\\\", "\\", 0);
 
   while ((p = strstr(s,"\\..\\")) != NULL)
     {
@@ -635,7 +595,7 @@ void dos_clean_name(char *s)
 
   trim_string(s,NULL,"\\..");
 
-  string_sub(s, "\\.\\", "\\");
+  all_string_sub(s, "\\.\\", "\\", 0);
 }
 
 /*******************************************************************
@@ -648,7 +608,7 @@ void unix_clean_name(char *s)
   DEBUG(3,("unix_clean_name [%s]\n",s));
 
   /* remove any double slashes */
-  string_sub(s, "//","/");
+  all_string_sub(s, "//","/", 0);
 
   /* Remove leading ./ characters */
   if(strncmp(s, "./", 2) == 0) {
@@ -676,7 +636,7 @@ void unix_clean_name(char *s)
 
 /*******************************************************************
 reduce a file name, removing .. elements and checking that 
-it is below dir in the heirachy. This uses GetWd() and so must be run
+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
@@ -697,25 +657,25 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
   *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]=='/'))
     {
-      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);
-       }
+      DEBUG(3,("Illegal file name? (%s)\n",s));
+      return(False);
+    }
 
-      if (strlen(s) == 0)
-        pstrcpy(s,"./");
+    if (strlen(s) == 0)
+      pstrcpy(s,"./");
 
-      return(True);
-    }
+    return(True);
+  }
   
   DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
 
   /* remove any double slashes */
-  string_sub(s,"//","/");
+  all_string_sub(s,"//","/",0);
 
   pstrcpy(base_name,s);
   p = strrchr(base_name,'/');
@@ -724,53 +684,52 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
     return(True);
 
   if (!dos_GetWd(wd))
-    {
-      DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
-      return(False);
-    }
+  {
+    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);
-    }
+  {
+    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);
-    }
-
+  {
+    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 (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);
-    }
+  {
+    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);
-    }
+  {
+    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);
-    }
+  {
+    pstrcat(newname,"/");
+    pstrcat(newname,p+1);
+  }
 
   {
     size_t l = strlen(dir2);    
@@ -778,19 +737,19 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
       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);
-      }
+    {
+      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);
-      }
+    {
+      if (newname[l] == '/')
+        pstrcpy(s,newname + l + 1);
+      else
+        pstrcpy(s,newname+l);
+    }
     else
       pstrcpy(s,newname);
   }
@@ -918,7 +877,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
   else
     memcpy(buf+1,mask2,MIN(strlen(mask2),11));
 
-  bzero(buf+21,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);
@@ -1083,11 +1042,7 @@ static char *name_ptr(char *buf,int ofs)
 
   if ((c & 0xC0) == 0xC0)
     {
-      uint16 l;
-      char p[2];
-      memcpy(p,buf+ofs,2);
-      p[0] &= ~0xC0;
-      l = RSVAL(p,0);
+      uint16 l = RSVAL(buf, ofs) & 0x3FFF;
       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
       return(buf + l);
     }
@@ -1148,7 +1103,7 @@ void msleep(int t)
  
     FD_ZERO(&fds);
     errno = 0;
-    sys_select(0,&fds,NULL, &tval);
+    sys_select(0,&fds,&tval);
 
     GetTimeOfDay(&t2);
     tdiff = TvalDiff(&t1,&t2);
@@ -1161,7 +1116,8 @@ void msleep(int t)
 * 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;
 
@@ -1226,7 +1182,7 @@ 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, BOOL trans2)
 {
   char *p;
   pstring p1, p2;
@@ -1286,9 +1242,14 @@ static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
 * 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, char *regexp, int case_sig)
+static BOOL do_match(char *str, char *regexp, int case_sig, BOOL win9x_semantics)
 {
   char *p;
 
@@ -1312,7 +1273,7 @@ BOOL do_match(char *str, char *regexp, int case_sig)
         while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
           str++;
         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;
         }
         if(!*str) {
@@ -1345,10 +1306,12 @@ BOOL do_match(char *str, char *regexp, int case_sig)
     return(True);
   }
   
-  if (!*str && *p == '?') {
-    while (*p == '?')
-      p++;
-    return(!*p);
+  if (!win9x_semantics) {
+    if (!*str && *p == '?') {
+      while (*p == '?')
+        p++;
+      return(!*p);
+    }
   }
 
   if(!*str && (*p == '*' && p[1] == '\0')) {
@@ -1358,6 +1321,15 @@ BOOL do_match(char *str, char *regexp, int case_sig)
   return False;
 }
 
+/*********************************************************
+* Routine to check if a given string matches exactly.
+* Case can be significant or not.
+**********************************************************/
+
+BOOL exact_match(char *str, char *regexp, BOOL case_sig)
+{
+  return ((case_sig?strcmp(str,regexp):strcasecmp(str,regexp)) == 0);
+}
 
 /*********************************************************
 * Routine to match a given string with a regexp - uses
@@ -1367,18 +1339,37 @@ BOOL do_match(char *str, 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.
@@ -1394,8 +1385,8 @@ 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, "**", "*");
+  pstring_sub(t_pattern, "*?", "*");
+  pstring_sub(t_pattern, "**", "*");
 
   if (strequal(t_pattern,"*"))
     return(True);
@@ -1416,7 +1407,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, '.');
 
@@ -1424,7 +1415,7 @@ 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;) {
         fp = strchr(cp2, '.');
@@ -1434,14 +1425,24 @@ 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 : "";
 
@@ -1454,7 +1455,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
             if(fp)
               *fp = '\0';
 
-            if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
+            if((cp1 != NULL) && do_match( cp2, cp1, case_sig, win9x_semantics)) {
               cp2 = fp ? fp + 1 : "";
               break;
             }
@@ -1475,19 +1476,21 @@ 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, "????????.???") ||
+         strequal(t_pattern, "?.") || strequal(t_pattern, "?")) 
         matched = True;
     } 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;
     } else {
@@ -1531,12 +1534,12 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
         fstrcpy (sbase, t_filename);
         fstrcpy (sext, p + 1);
         if (*eext) {
-          matched = do_match(sbase, ebase, case_sig)
-                    && do_match(sext, eext, case_sig);
+          matched = do_match(sbase, ebase, case_sig, False)
+                    && do_match(sext, eext, 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);
+          matched = do_match(str, ebase, case_sig, False);
         }
       } else {
         /* 
@@ -1546,10 +1549,11 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
         fstrcpy (sext, "");
         if (*eext) {
           /* pattern has extension */
-          matched = do_match(sbase, ebase, case_sig)
-                    && do_match(sext, eext, case_sig);
+          matched = do_match(sbase, ebase, case_sig, False)
+                    && do_match(sext, eext, case_sig, False);
+
         } else {
-          matched = do_match(sbase, ebase, case_sig);
+          matched = do_match(sbase, ebase, case_sig, False);
 #ifdef EMULATE_WEIRD_W95_MATCHING
           /*
            * Even Microsoft has some problems
@@ -1560,7 +1564,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
           if (!matched) {
             /* a? matches aa and a in w95 */
             fstrcat (sbase, ".");
-            matched = do_match(sbase, ebase, case_sig);
+            matched = do_match(sbase, ebase, case_sig, False);
           }
 #endif
         }
@@ -1617,12 +1621,11 @@ BOOL yesno(char *p)
   return(False);
 }
 
-
-
 /****************************************************************************
 set the length of a file from a filedescriptor.
 Returns 0 on success, -1 on failure.
 ****************************************************************************/
+
 int set_filelen(int fd, SMB_OFF_T len)
 {
 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
@@ -1646,7 +1649,8 @@ int set_filelen(int fd, SMB_OFF_T len)
     return -1;
 
 #ifdef S_ISFIFO
-  if (S_ISFIFO(st.st_mode)) return 0;
+  if (S_ISFIFO(st.st_mode))
+    return 0;
 #endif
 
   if(st.st_size == len)
@@ -1720,7 +1724,7 @@ void *Realloc(void *p,size_t size)
 #endif
 
   if (!ret)
-    DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
+    DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
 
   return(ret);
 }
@@ -1729,40 +1733,30 @@ void *Realloc(void *p,size_t size)
 /****************************************************************************
 get my own name and IP
 ****************************************************************************/
-BOOL get_myname(char *my_name,struct in_addr *ip)
+BOOL get_myname(char *my_name)
 {
-  struct hostent *hp;
-  pstring hostname;
-
-  *hostname = 0;
-
-  /* get my host name */
-  if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
-    {
-      DEBUG(0,("gethostname failed\n"));
-      return False;
-    } 
-
-  /* get host info */
-  if ((hp = Get_Hostbyname(hostname)) == 0) 
-    {
-      DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
-      return False;
-    }
+       pstring hostname;
 
-  if (my_name)
-    {
-      /* split off any parts after an initial . */
-      char *p = strchr(hostname,'.');
-      if (p) *p = 0;
+       *hostname = 0;
 
-      fstrcpy(my_name,hostname);
-    }
+       /* get my host name */
+       if (gethostname(hostname, sizeof(hostname)) == -1) {
+               DEBUG(0,("gethostname failed\n"));
+               return False;
+       } 
 
-  if (ip)
-    putip((char *)ip,(char *)hp->h_addr);
+       /* Ensure null termination. */
+       hostname[sizeof(hostname)-1] = '\0';
 
-  return(True);
+       if (my_name) {
+               /* split off any parts after an initial . */
+               char *p = strchr(hostname,'.');
+               if (p) *p = 0;
+               
+               fstrcpy(my_name,hostname);
+       }
+       
+       return(True);
 }
 
 
@@ -1771,10 +1765,7 @@ 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);
+       return ip1.s_addr == ip2.s_addr;
 }
 
 
@@ -1801,26 +1792,39 @@ int interpret_protocol(char *str,int def)
   return(def);
 }
 
+/****************************************************************************
+ Return true if a string could be a pure IP address.
+****************************************************************************/
+
+BOOL is_ipaddress(const char *str)
+{
+  BOOL pure_address = True;
+  int i;
+  
+  for (i=0; pure_address && str[i]; i++)
+    if (!(isdigit((int)str[i]) || str[i] == '.'))
+      pure_address = False;
+
+  /* Check that a pure number is not misinterpreted as an IP */
+  pure_address = pure_address && (strchr(str, '.') != NULL);
+
+  return pure_address;
+}
 
 /****************************************************************************
 interpret an internet address or name into an IP address in 4 byte form
 ****************************************************************************/
+
 uint32 interpret_addr(char *str)
 {
   struct hostent *hp;
   uint32 res;
-  int i;
-  BOOL pure_address = True;
 
   if (strcmp(str,"0.0.0.0") == 0) return(0);
   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
 
-  for (i=0; pure_address && str[i]; i++)
-    if (!(isdigit((int)str[i]) || str[i] == '.')) 
-      pure_address = False;
-
   /* if it's in the form of an IP address then get the lib to interpret it */
-  if (pure_address) {
+  if (is_ipaddress(str)) {
     res = inet_addr(str);
   } else {
     /* otherwise assume it's a network name of some sort and use 
@@ -1872,7 +1876,7 @@ BOOL matchname(char *remotehost,struct in_addr  addr)
   int     i;
   
   if ((hp = Get_Hostbyname(remotehost)) == 0) {
-    DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
+    DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost));
     return False;
   } 
 
@@ -1886,7 +1890,7 @@ BOOL matchname(char *remotehost,struct in_addr  addr)
   
   if (strcasecmp(remotehost, hp->h_name)
       && strcasecmp(remotehost, "localhost")) {
-    DEBUG(0,("host name/name mismatch: %s != %s",
+    DEBUG(0,("host name/name mismatch: %s != %s\n",
             remotehost, hp->h_name));
     return False;
   }
@@ -1903,7 +1907,7 @@ BOOL matchname(char *remotehost,struct in_addr  addr)
    * it, but that could be dangerous, too.
    */
   
-  DEBUG(0,("host name/address mismatch: %s != %s",
+  DEBUG(0,("host name/address mismatch: %s != %s\n",
           inet_ntoa(addr), hp->h_name));
   return False;
 }
@@ -1981,7 +1985,7 @@ static char *automount_lookup(char *user_name)
            DEBUG(3, ("NIS+ result: %s\n", 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);
         }
       }
@@ -2091,8 +2095,8 @@ static char *automount_path(char *user_name)
 
        /* use the passwd entry as the default */
        /* this will be the default if WITH_AUTOMOUNT is not used or fails */
-       /* pstrcpy() copes with get_unixhome_dir() returning NULL */
-       pstrcpy(server_path, get_unixhome_dir(user_name));
+       /* pstrcpy() copes with get_user_home_dir() returning NULL */
+       pstrcpy(server_path, get_user_home_dir(user_name));
 
 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
 
@@ -2115,92 +2119,114 @@ static char *automount_path(char *user_name)
        return server_path;
 }
 
+/*******************************************************************
+ Given a pointer to a %$(NAME) expand it as an environment variable.
+ Return the number of characters by which the pointer should be advanced.
+ Based on code by Branko Cibej <branko.cibej@hermes.si>
+ When this is called p points at the '%' character.
+********************************************************************/
+
+static size_t expand_env_var(char *p, int len)
+{
+       fstring envname;
+       char *envval;
+       char *q, *r;
+       int copylen;
+
+       if (p[1] != '$')
+               return 1;
+
+       if (p[2] != '(')
+               return 2;
+
+       /*
+        * Look for the terminating ')'.
+        */
+
+       if ((q = strchr(p,')')) == NULL) {
+               DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
+               return 2;
+       }
+
+       /*
+        * Extract the name from within the %$(NAME) string.
+        */
+
+       r = p+3;
+       copylen = MIN((q-r),(sizeof(envname)-1));
+       strncpy(envname,r,copylen);
+       envname[copylen] = '\0';
+
+       if ((envval = getenv(envname)) == NULL) {
+               DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
+               return 2;
+       }
+
+       /*
+        * Copy the full %$(NAME) into envname so it
+        * can be replaced.
+        */
+
+       copylen = MIN((q+1-p),(sizeof(envname)-1));
+       strncpy(envname,p,copylen);
+       envname[copylen] = '\0';
+       string_sub(p,envname,envval,len);
+       return 0; /* Allow the environment contents to be parsed. */
+}
 
 /*******************************************************************
-sub strings with useful parameters
-Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
-Paul Rippin <pr3245@nopc.eurostat.cec.be>
+ Substitute strings with useful parameters.
+ Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
+ Paul Rippin <pr3245@nopc.eurostat.cec.be>.
 ********************************************************************/
+
 void standard_sub_basic(char *str)
 {
        char *s, *p;
        char pidstr[10];
-       const struct passwd *pass;
+       struct passwd *pass;
        char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
 
        for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
        {
+               int l = sizeof(pstring) - (int)(p-str);
+
+               if (l < 0) {
+                       DEBUG(0,("ERROR: string overflow by %d in standard_sub_basic(%.50s)\n", 
+                                -l, str));
+                       
+                       return;
+               }
+
                switch (*(p+1))
                {
                        case 'G' :
                        {
-                               if ((pass = Get_Pwnam(username,False))!=NULL)
-                               {
-                                       string_sub(p,"%G",gidtoname(pass->pw_gid));
-                               }
-                               else
-                               {
+                               if ((pass = Get_Pwnam(username,False))!=NULL) {
+                                       string_sub(p,"%G",gidtoname(pass->pw_gid),l);
+                               } else {
                                        p += 2;
                                }
                                break;
                        }
-                       case 'N' : string_sub(p,"%N", automount_server(username)); break;
-                       case 'I' : string_sub(p,"%I", client_addr(Client)); break;
-                       case 'L' : string_sub(p,"%L", local_machine); break;
-                       case 'M' : string_sub(p,"%M", client_name(Client)); break;
-                       case 'R' : string_sub(p,"%R", remote_proto); break;
-                       case 'T' : string_sub(p,"%T", timestring()); break;
-                       case 'U' : string_sub(p,"%U", username); break;
-                       case 'a' : string_sub(p,"%a", remote_arch); break;
+                       case 'N' : string_sub(p,"%N", automount_server(username),l); break;
+                       case 'I' : string_sub(p,"%I", client_addr(Client),l); break;
+                       case 'L' : string_sub(p,"%L", local_machine,l); break;
+                       case 'M' : string_sub(p,"%M", client_name(Client),l); break;
+                       case 'R' : string_sub(p,"%R", remote_proto,l); break;
+                       case 'T' : string_sub(p,"%T", timestring(False),l); break;
+                       case 'U' : string_sub(p,"%U", username,l); break;
+                       case 'a' : string_sub(p,"%a", remote_arch,l); break;
                        case 'd' :
                        {
                                slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
-                               string_sub(p,"%d", pidstr);
-                               break;
-                       }
-                       case 'h' : string_sub(p,"%h", myhostname); break;
-                       case 'm' : string_sub(p,"%m", remote_machine); break;
-                       case 'v' : string_sub(p,"%v", VERSION); break;
-                       case '$' : /* Expand environment variables */
-                       {
-                               /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
-                               fstring envname;
-                               char *envval;
-                               char *q, *r;
-                               int copylen;
-
-                               if (*(p+2) != '(')
-                               {
-                                       p+=2;
-                                       break;
-                               }
-                               if ((q = strchr(p,')')) == NULL)
-                               {
-                                       DEBUG(0,("standard_sub_basic: Unterminated environment \
-                                       variable [%s]\n", p));
-                                       p+=2;
-                                       break;
-                               }
-
-                               r = p+3;
-                               copylen = MIN((q-r),(sizeof(envname)-1));
-                               strncpy(envname,r,copylen);
-                               envname[copylen] = '\0';
-
-                               if ((envval = getenv(envname)) == NULL)
-                               {
-                                       DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
-                                       envname));
-                                       p+=2;
-                                       break;
-                               }
-
-                               copylen = MIN((q+1-p),(sizeof(envname)-1));
-                               strncpy(envname,p,copylen);
-                               envname[copylen] = '\0';
-                               string_sub(p,envname,envval);
+                               string_sub(p,"%d", pidstr,l);
                                break;
                        }
+                       case 'h' : string_sub(p,"%h", myhostname(),l); break;
+                       case 'm' : string_sub(p,"%m", remote_machine,l); break;
+                       case 'v' : string_sub(p,"%v", VERSION,l); break;
+                       case '$' : p += expand_env_var(p,l); break; /* Expand environment variables */
                        case '\0': p++; break; /* don't run off end if last character is % */
                        default  : p+=2; break;
                }
@@ -2210,24 +2236,42 @@ void standard_sub_basic(char *str)
 
 
 /****************************************************************************
-do some standard substitutions in a string
+ Do some standard substitutions in a string.
 ****************************************************************************/
+
 void standard_sub(connection_struct *conn,char *str)
 {
        char *p, *s, *home;
 
-       for (s=str; (p=strchr(s, '%'));s=p)
-       {
-               switch (*(p+1))
-               {
-                       case 'H': 
-                               if ((home = get_unixhome_dir(conn->user)) != NULL) {
-                                       string_sub(p,"%H",home);
-                               } else {
-                                       p += 2;
-                               }
-                               break;
-                               
+       for (s=str; (p=strchr(s, '%'));s=p) {
+               int l = sizeof(pstring) - (int)(p-str);
+
+               switch (*(p+1)) {
+               case 'H': 
+                       if ((home = get_user_home_dir(conn->user))) {
+                               string_sub(p,"%H",home,l);
+                       } else {
+                               p += 2;
+                       }
+                       break;
+                       
+               case 'P': 
+                       string_sub(p,"%P",conn->connectpath,l); 
+                       break;
+                       
+               case 'S': 
+                       string_sub(p,"%S",
+                                  lp_servicename(SNUM(conn)),l); 
+                       break;
+                       
+               case 'g': 
+                       string_sub(p,"%g",
+                                  gidtoname(conn->gid),l); 
+                       break;
+               case 'u': 
+                       string_sub(p,"%u",conn->user,l); 
+                       break;
+                       
                        /* Patch from jkf@soton.ac.uk Left the %N (NIS
                         * server name) in standard_sub_basic as it is
                         * a feature for logon servers, hence uses the
@@ -2235,14 +2279,17 @@ void standard_sub(connection_struct *conn,char *str)
                         * here as it is used instead of the default
                         * "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)))); break;
-                       case 'P': string_sub(p,"%P",conn->connectpath); break; 
-                       case 'S': string_sub(p,"%S", lp_servicename(SNUM(conn))); break; 
-                       case 'g': string_sub(p,"%g", gidtoname(conn->gid)); break;
-                       case 'u': string_sub(p,"%u", conn->user); break;
-                               
-                       case '\0': p++; break; /* don't run off the end of the string */ 
-                       default  : p+=2; break;
+               case 'p': 
+                       string_sub(p,"%p",
+                                  automount_path(lp_servicename(SNUM(conn))),l); 
+                       break;
+               case '\0': 
+                       p++; 
+                       break; /* don't run off the end of the string 
+                               */
+                       
+               default: p+=2; 
+                       break;
                }
        }
        
@@ -2331,131 +2378,24 @@ struct hostent *Get_Hostbyname(const char *name)
 check if a process exists. Does this work on all unixes?
 ****************************************************************************/
 
-BOOL process_exists(int pid)
+BOOL process_exists(pid_t pid)
 {
        return(kill(pid,0) == 0 || errno != ESRCH);
 }
 
 
-/****************************************************************************
-Setup the groups a user belongs to.
-****************************************************************************/
-int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
+/*******************************************************************
+turn a uid into a user name
+********************************************************************/
+char *uidtoname(uid_t uid)
 {
-       int i,ngroups;
-       gid_t grp = 0;
-       gid_t *groups = NULL;
+  static char name[40];
+  struct passwd *pass = sys_getpwuid(uid);
+  if (pass) return(pass->pw_name);
+  slprintf(name, sizeof(name) - 1, "%d",(int)uid);
+  return(name);
+}
 
-       if (-1 == initgroups(user,gid))
-       {
-               if (getuid() == 0)
-               {
-                       DEBUG(0,("Unable to initgroups!\n"));
-                       if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
-                       {
-                               DEBUG(0,("This is probably a problem with the account %s\n", user));
-                       }
-               }
-               return -1;
-       }
-
-       ngroups = sys_getgroups(0,&grp);
-       if (ngroups <= 0)
-       {
-               ngroups = 32;
-       }
-
-       if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
-       {
-               DEBUG(0,("get_unixgroups malloc fail !\n"));
-               return -1;
-       }
-
-       ngroups = sys_getgroups(ngroups,groups);
-
-       (*p_ngroups) = ngroups;
-       (*p_groups) = groups;
-
-       DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
-       for (i = 0; i < ngroups; i++ )
-       {
-               DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
-       }
-       DEBUG( 3, ( "\n" ) );
-
-       return 0;
-}
-
-/****************************************************************************
-get all unix groups.  copying group members is hideous on memory, so it's
-NOT done here.  however, names of unix groups _are_ string-allocated so
-free_unix_grps() must be called.
-****************************************************************************/
-BOOL get_unix_grps(int *p_ngroups, struct group **p_groups)
-{
-       struct group *grp;
-
-       DEBUG(10,("get_unix_grps\n"));
-
-       if (p_ngroups == NULL || p_groups == NULL)
-       {
-               return False;
-       }
-
-       (*p_ngroups) = 0;
-       (*p_groups) = NULL;
-
-       setgrent();
-
-       while ((grp = getgrent()) != NULL)
-       {
-               struct group *copy_grp;
-               
-               (*p_groups) = (struct group*)Realloc((*p_groups), (size_t)((*p_ngroups)+1) * sizeof(struct group));
-               if ((*p_groups) == NULL)
-               {
-                       (*p_ngroups) = 0;
-                       endgrent();
-                       
-                       return False;
-               }
-
-               copy_grp = &(*p_groups)[*p_ngroups];
-               memcpy(copy_grp, grp, sizeof(*grp));
-               copy_grp->gr_name = strdup(copy_grp->gr_name);
-               copy_grp->gr_mem  = NULL;
-
-               (*p_ngroups)++;
-       }
-
-       endgrent();
-
-       DEBUG(10,("get_unix_grps: %d groups\n", (*p_ngroups)));
-       return True;
-}
-
-/****************************************************************************
-free memory associated with unix groups.
-****************************************************************************/
-void free_unix_grps(int ngroups, struct group *p_groups)
-{
-       int i;
-
-       if (p_groups == NULL)
-       {
-               return;
-       }
-
-       for (i = 0; i < ngroups; i++)
-       {
-               if (p_groups[i].gr_name != NULL)
-               {
-                       free(p_groups[i].gr_name);
-               }
-       }
-
-       free(p_groups);
-}
 
 /*******************************************************************
 turn a gid into a group name
@@ -2471,48 +2411,37 @@ char *gidtoname(gid_t gid)
 }
 
 /*******************************************************************
-turn a group name into a gid
+turn a user name into a uid
 ********************************************************************/
-
-BOOL nametogid(const char *name, gid_t *gid)
+uid_t nametouid(const char *name)
 {
-       struct group *grp = getgrnam(name);
-       if (grp)
-       {
-               *gid = grp->gr_gid;
-               return True;
-       }
-       else if (isdigit(name[0]))
-       {
-               *gid = (gid_t)get_number(name);
-               return True;
-       }
-       else
-       {
-               return False;
-       }
+       struct passwd *pass;
+       char *p;
+       uid_t u;
+
+       u = strtol(name, &p, 0);
+       if (p != name) return u;
+
+       pass = sys_getpwnam(name);
+       if (pass) return(pass->pw_uid);
+       return (uid_t)-1;
 }
 
 /*******************************************************************
-turn a user name into a uid
+turn a group name into a gid
 ********************************************************************/
-BOOL nametouid(const char *name, uid_t *uid)
+gid_t nametogid(const char *name)
 {
-       const struct passwd *pass = Get_Pwnam(name, False);
-       if (pass)
-       {
-               *uid = pass->pw_uid;
-               return True;
-       }
-       else if (isdigit(name[0]))
-       {
-               *uid = (uid_t)get_number(name);
-               return True;
-       }
-       else
-       {
-               return False;
-       }
+       struct group *grp;
+       char *p;
+       gid_t g;
+
+       g = strtol(name, &p, 0);
+       if (p != name) return g;
+
+       grp = getgrnam(name);
+       if (grp) return(grp->gr_gid);
+       return (gid_t)-1;
 }
 
 /*******************************************************************
@@ -2535,12 +2464,12 @@ 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);
 
        dname = ptr->d_name;
@@ -2730,14 +2659,56 @@ void free_namearray(name_compare_entry *name_array)
   free((char *)name_array);
 }
 
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+
+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);
+}
+
 /****************************************************************************
 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 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 */
 
   if(lp_ole_locking_compat()) {
     SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
@@ -2794,7 +2765,7 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
     }
     /* 32 bit NFS file system, retry with smaller offset */
     errno = 0;
-    lock.l_len = count & 0xffffffff;
+    lock.l_len = count & 0x7fffffff;
     ret = fcntl(fd,op,&lock);
   }
 
@@ -2826,8 +2797,38 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
     /* perhaps it doesn't support this sort of locking?? */
     if (errno == EINVAL)
     {
+
+#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(False);
@@ -2879,6 +2880,9 @@ void set_remote_arch(enum remote_arch_types type)
   case RA_WINNT:
     fstrcpy(remote_arch, "WinNT");
     return;
+  case RA_WIN2K:
+    fstrcpy(remote_arch, "Win2K");
+    return;
   case RA_SAMBA:
     fstrcpy(remote_arch,"Samba");
     return;
@@ -2898,31 +2902,19 @@ enum remote_arch_types get_remote_arch(void)
 }
 
 
-/*******************************************************************
- align a pointer to a multiple of 4 bytes.  
- ********************************************************************/
-char *align4(char *q, char *base)
-{
-       int mod = PTR_DIFF(q, base) & 3;
-       if (mod != 0)
-       {
-               q += mod;
-       }
-       return q;
-}
 /*******************************************************************
 align a pointer to a multiple of 2 bytes
 ********************************************************************/
 char *align2(char *q, char *base)
 {
-       if (PTR_DIFF(q, base) & 1)
+       if ((q - base) & 1)
        {
                q++;
        }
        return q;
 }
 
-void out_ascii(FILE *f, const unsigned char *buf,int len)
+void out_ascii(FILE *f, unsigned char *buf,int len)
 {
        int i;
        for (i=0;i<len;i++)
@@ -2931,36 +2923,9 @@ void out_ascii(FILE *f, const unsigned char *buf,int len)
        }
 }
 
-void out_struct(FILE *f, const char *buf1,int len, int per_line)
-{
-       const unsigned char *buf = (const unsigned char *)buf1;
-       int i;
-
-       if (len<=0)
-       {
-               return;
-       }
-
-       fprintf(f, "{\n\t");
-       for (i=0;i<len;)
-       {
-               fprintf(f, "0x%02X",(int)buf[i]);
-               i++;
-               if (i != len)
-               {
-                       fprintf(f, ", ");
-               }
-               if (i%per_line == 0 && i != len)
-               {      
-                       fprintf(f, "\n\t");
-               }
-       }
-       fprintf(f, "\n};\n");    
-}
-
-void out_data(FILE *f, const char *buf1,int len, int per_line)
+void out_data(FILE *f,char *buf1,int len, int per_line)
 {
-       const unsigned char *buf = (const unsigned char *)buf1;
+       unsigned char *buf = (unsigned char *)buf1;
        int i=0;
        if (len<=0)
        {
@@ -2999,55 +2964,44 @@ void out_data(FILE *f, const char *buf1,int len, int per_line)
        }
 }
 
-void print_asc(int level, unsigned char const *buf,int len)
+void print_asc(int level, unsigned char *buf,int len)
 {
        int i;
        for (i=0;i<len;i++)
-       {
-               DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
-       }
+               DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
 }
 
-void dump_data(int level, const char *buf1, int len)
+void dump_data(int level,char *buf1,int len)
 {
-       unsigned char const *buf = (unsigned char const *)buf1;
-       int i=0;
-       if (len<0) return;
-       if (len == 0)
-       {
-               DEBUG(level,("\n"));
-               return;
-       }
+  unsigned char *buf = (unsigned char *)buf1;
+  int i=0;
+  if (len<=0) return;
 
-       DEBUG(level,("[%03X] ",i));
-       for (i=0;i<len;)
-       {
-               DEBUGADD(level,("%02X ",(int)buf[i]));
-               i++;
-               if (i%8 == 0) DEBUGADD(level,(" "));
-               if (i%16 == 0)
-               {      
-                       print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
-                       print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
-                       if (i<len) DEBUGADD(level,("[%03X] ",i));
-               }
-       }
-
-       if (i%16 != 0) /* finish off a non-16-char-length row */
-       {
-               int n;
-
-               n = 16 - (i%16);
-               DEBUGADD(level,(" "));
-               if (n>8) DEBUGADD(level,(" "));
-               while (n--) DEBUGADD(level,("   "));
-
-               n = MIN(8,i%16);
-               print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,(" "));
-               n = (i%16) - n;
-               if (n>0) print_asc(level,&buf[i-n],n); 
-               DEBUGADD(level,("\n"));    
-       }
+  DEBUG(level,("[%03X] ",i));
+  for (i=0;i<len;) {
+    DEBUG(level,("%02X ",(int)buf[i]));
+    i++;
+    if (i%8 == 0) DEBUG(level,(" "));
+    if (i%16 == 0) {      
+      print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
+      print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
+      if (i<len) DEBUG(level,("[%03X] ",i));
+    }
+  }
+  if (i%16) {
+    int n;
+
+    n = 16 - (i%16);
+    DEBUG(level,(" "));
+    if (n>8) DEBUG(level,(" "));
+    while (n--) DEBUG(level,("   "));
+
+    n = MIN(8,i%16);
+    print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
+    n = (i%16) - n;
+    if (n>0) print_asc(level,&buf[i-n],n); 
+    DEBUG(level,("\n"));    
+  }
 }
 
 char *tab_depth(int depth)
@@ -3102,16 +3056,50 @@ 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
+       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.  */
-       rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
-       setrlimit(RLIMIT_NOFILE, &rlp);
-       getrlimit(RLIMIT_NOFILE, &rlp);
+        * 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...
         */
@@ -3131,11 +3119,11 @@ 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(char *full_keyname, uint32 *reg_type, char *key_name)
 {
        pstring tmp;
 
-       if (!next_token((char**)(&full_keyname), tmp, "\\", sizeof(tmp)))
+       if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
        {
                return False;
        }
@@ -3144,15 +3132,7 @@ BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
 
        DEBUG(10, ("reg_split_key: hive %s\n", tmp));
 
-       if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT"))
-       {
-               (*reg_type) = HKEY_CLASSES_ROOT;
-       }
-       else if (strequal(tmp, "HKCU") || strequal(tmp, "HKEY_CURRENT_USER"))
-       {
-               (*reg_type) = HKEY_CURRENT_USER;
-       }
-       else if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
+       if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
        {
                (*reg_type) = HKEY_LOCAL_MACHINE;
        }
@@ -3180,326 +3160,56 @@ BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
        return True;
 }
 
-/****************************************************************************
-  become the specified uid - permanently !
-****************************************************************************/
-BOOL become_user_permanently(uid_t uid, gid_t gid)
-{
-       /* now completely lose our privilages. This is a fairly paranoid
-          way of doing it, but it does work on all systems that I know of */
-
-#ifdef HAVE_SETRESUID
-       /*
-        * Firstly ensure all our uids are set to root.
-        */
-       setresgid(0,0,0);
-       setresuid(0,0,0);
 
-       /*
-        * Now ensure we change all our gids.
-        */
-       setresgid(gid,gid,gid);
-       
-       /*
-        * Now ensure all the uids are the user.
-        */
-       setresuid(uid,uid,uid);
-#else
-       /*
-        * Firstly ensure all our uids are set to root.
-        */
-       setuid(0);
-       seteuid(0);
-       
-       /*
-        * Now ensure we change all our gids.
-        */
-       setgid(gid);
-       setegid(gid);
-       
-       /*
-        * Now ensure all the uids are the user.
-        */
-       setuid(uid);
-       seteuid(uid);
-#endif
-       
-       if (getuid() != uid || geteuid() != uid ||
-           getgid() != gid || getegid() != gid) {
-               /* We failed to lose our privilages. */
-               return False;
-       }
-       
-       return(True);
-}
-
-char *get_trusted_serverlist(const char* domain)
+/*****************************************************************
+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)
 {
-       pstring tmp;
-       static char *server_list = NULL;
-       static pstring srv_list;
-       char *trusted_list = lp_trusted_domains();
+       char *p = mktemp(template);
+       char *p2;
+       SMB_STRUCT_STAT st;
 
-       if (strequal(lp_workgroup(), domain))
-       {
-               DEBUG(10,("local domain server list: %s\n", server_list));
-               pstrcpy(srv_list, lp_passwordserver());
-               return srv_list;
-       }
-
-       if (!next_token(&trusted_list, tmp, NULL, sizeof(tmp)))
-       {
-               return NULL;
-       }
-
-       do
-       {
-               fstring trust_dom;
-               split_at_first_component(tmp, trust_dom, '=', srv_list);
+       if (!p) return NULL;
 
-               if (strequal(domain, trust_dom))
-               {
-                       return srv_list;
-                       DEBUG(10,("trusted: %s\n", server_list));
+       while ((p2=strchr(p,'%'))) {
+               p2[0] = 'A';
+               while (sys_stat(p,&st) == 0 && p2[0] < 'Z') {
+                       /* damn, it exists */
+                       p2[0]++;
                }
-
-       } while (next_token(NULL, tmp, NULL, sizeof(tmp)));
-
-       return NULL;
-}
-
-/**********************************************************
- Encode the account control bits into a string.
- length = length of string to encode into (including terminating
- null). length *MUST BE MORE THAN 2* !
- **********************************************************/
-
-char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
-{
-       static fstring acct_str;
-       size_t i = 0;
-
-       acct_str[i++] = '[';
-
-       if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
-       if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
-       if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
-       if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
-       if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
-       if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
-       if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
-       if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
-       if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
-       if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
-       if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
-       if (acct_ctrl & ACB_PWLOCK   ) acct_str[i++] = 'P';
-
-       for ( ; i < length - 2 ; i++ )
-       {
-               acct_str[i] = ' ';
-       }
-
-       i = length - 2;
-       acct_str[i++] = ']';
-       acct_str[i++] = '\0';
-
-       return acct_str;
-}     
-
-/**********************************************************
- Decode the account control bits from a string.
-
- this function breaks coding standards minimum line width of 80 chars.
- reason: vertical line-up code clarity - all case statements fit into
- 15 lines, which is more important.
- **********************************************************/
-
-uint16 pwdb_decode_acct_ctrl(const char *p)
-{
-       uint16 acct_ctrl = 0;
-       BOOL finished = False;
-
-       /*
-        * Check if the account type bits have been encoded after the
-        * NT password (in the form [NDHTUWSLXI]).
-        */
-
-       if (*p != '[') return 0;
-
-       for (p++; *p && !finished; p++)
-       {
-               switch (*p)
-               {
-                       case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
-                       case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
-                       case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
-                       case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
-                       case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
-                       case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
-                       case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
-                       case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
-                       case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
-                       case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
-                       case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
-                       case 'P': { acct_ctrl |= ACB_PWLOCK   ; break; /* 'P'assword cannot be changed remotely */ } 
-                       case ' ': { break; }
-                       case ':':
-                       case '\n':
-                       case '\0': 
-                       case ']':
-                       default:  { finished = True; }
-               }
-       }
-
-       return acct_ctrl;
-}
-
-/*******************************************************************
- gets password-database-format time from a string.
- ********************************************************************/
-
-static time_t get_time_from_string(const char *p)
-{
-       int i;
-
-       for (i = 0; i < 8; i++)
-       {
-               if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
-               {
-                       break;
+               if (p2[0] == 'Z') {
+                       /* oh well ... better return something */
+                       p2[0] = '%';
+                       return p;
                }
        }
-       if (i == 8)
-       {
-               /*
-                * p points at 8 characters of hex digits - 
-                * read into a time_t as the seconds since
-                * 1970 that the password was last changed.
-                */
-               return (time_t)strtol(p, NULL, 16);
-       }
-       return (time_t)-1;
-}
-
-/*******************************************************************
- gets password last set time
- ********************************************************************/
-
-time_t pwdb_get_last_set_time(const char *p)
-{
-       if (*p && !StrnCaseCmp(p, "LCT-", 4))
-       {
-               return get_time_from_string(p + 4);
-       }
-       return (time_t)-1;
-}
-
-
-/*******************************************************************
- sets password-database-format time in a string.
- ********************************************************************/
-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);
-}
-
-/*******************************************************************
- sets logon time
- ********************************************************************/
-void pwdb_set_logon_time(char *p, int max_len, time_t t)
-{
-       set_time_in_string(p, max_len, "LNT", t);
-}
-
-/*******************************************************************
- sets logoff time
- ********************************************************************/
-void pwdb_set_logoff_time(char *p, int max_len, time_t t)
-{
-       set_time_in_string(p, max_len, "LOT", t);
-}
-
-/*******************************************************************
- sets kickoff time
- ********************************************************************/
-void pwdb_set_kickoff_time(char *p, int max_len, time_t t)
-{
-       set_time_in_string(p, max_len, "KOT", t);
-}
 
-/*******************************************************************
- sets password can change time
- ********************************************************************/
-void pwdb_set_can_change_time(char *p, int max_len, time_t t)
-{
-       set_time_in_string(p, max_len, "CCT", t);
+       return p;
 }
 
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pwdb_set_must_change_time(char *p, int max_len, time_t t)
-{
-       set_time_in_string(p, max_len, "MCT", t);
-}
 
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pwdb_set_last_set_time(char *p, int max_len, time_t t)
+/*****************************************************************
+like strdup but for memory
+ *****************************************************************/  
+void *memdup(void *p, size_t size)
 {
-       set_time_in_string(p, max_len, "LCT", t);
+       void *p2;
+       p2 = malloc(size);
+       if (!p2) return NULL;
+       memcpy(p2, p, size);
+       return p2;
 }
 
-
-/*************************************************************
- Routine to set 32 hex password characters from a 16 byte array.
-**************************************************************/
-void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl)
-{
-       if (pwd != NULL)
-       {
-               int i;
-               for (i = 0; i < 16; i++)
-               {
-                       slprintf(&p[i*2], 33, "%02X", pwd[i]);
-               }
-       }
-       else
-       {
-               if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
-               {
-                       safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
-               }
-               else
-               {
-                       safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
-               }
-       }
-}
-
-/*************************************************************
- 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)
+/*****************************************************************
+get local hostname and cache result
+ *****************************************************************/  
+char *myhostname(void)
 {
-       if (strnequal(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32))
-       {
-               if (acct_ctrl != NULL)
-               {
-                       *acct_ctrl |= ACB_PWNOTREQ;
-               }
-               pwd[0] = 0;
-               return True;
-       }
-       else if (strnequal(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32))
-       {
-               pwd[0] = 0;
-               return True;
-       }
-       else
-       {
-               return strhex_to_str(pwd, 32, p) == 16;
+       static pstring ret;
+       if (ret[0] == 0) {
+               get_myname(ret);
        }
+       return ret;
 }
index f4325b813bb76ccbb69b73f9c565585bb001df06..9eb38460d92380f3133dbcdd227831483bcd2ec6 100644 (file)
@@ -51,7 +51,7 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
   lock.l_len = 1;
   lock.l_pid = 0;
 
-  alarm(5);
+  alarm(waitsecs);
   ret = fcntl(fd, SMB_F_SETLKW, &lock);
   alarm(0);
   CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
@@ -113,22 +113,22 @@ BOOL file_unlock(int fd, int *plock_depth)
  update to be set = True if modification is required.
 ****************************************************************/
 
-void *startfileent(char *pfile, char *s_readbuf, int bufsize,
+void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
                                int *file_lock_depth, BOOL update)
 {
   FILE *fp = NULL;
 
   if (!*pfile)
  {
-    DEBUG(0, ("startfileent: No file set\n"));
+    DEBUG(0, ("startfilepwent: No file set\n"));
     return (NULL);
   }
-  DEBUG(10, ("startfileent: opening file %s\n", pfile));
+  DEBUG(10, ("startfilepwent: opening file %s\n", pfile));
 
   fp = sys_fopen(pfile, update ? "r+b" : "rb");
 
   if (fp == NULL) {
-    DEBUG(0, ("startfileent: unable to open file %s\n", pfile));
+    DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile));
     return NULL;
   }
 
@@ -137,7 +137,7 @@ void *startfileent(char *pfile, char *s_readbuf, int bufsize,
 
   if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
   {
-    DEBUG(0, ("startfileent: unable to lock file %s\n", pfile));
+    DEBUG(0, ("startfilepwent: unable to lock file %s\n", pfile));
     fclose(fp);
     return NULL;
   }
@@ -152,13 +152,13 @@ void *startfileent(char *pfile, char *s_readbuf, int bufsize,
 /***************************************************************
  End enumeration of the file.
 ****************************************************************/
-void endfileent(void *vp, int *file_lock_depth)
+void endfilepwent(void *vp, int *file_lock_depth)
 {
   FILE *fp = (FILE *)vp;
 
   file_unlock(fileno(fp), file_lock_depth);
   fclose(fp);
-  DEBUG(7, ("endfileent: closed file.\n"));
+  DEBUG(7, ("endfilepwent: closed file.\n"));
 }
 
 /*************************************************************************
@@ -181,6 +181,7 @@ BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok)
 
 /*************************************************************************
  gets a line out of a file.
+ line is of format "xxxx:xxxxxx:xxxxx:".
  lines with "#" at the front are ignored.
 *************************************************************************/
 int getfileline(void *vp, char *linebuf, int linebuf_size)
@@ -188,6 +189,7 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
        /* Static buffers we will return. */
        FILE *fp = (FILE *)vp;
        unsigned char   c;
+       unsigned char  *p;
        size_t            linebuf_len;
 
        if (fp == NULL)
@@ -247,6 +249,12 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
                        continue;
                }
 
+               p = (unsigned char *) strchr(linebuf, ':');
+               if (p == NULL)
+               {
+                       DEBUG(0, ("getfileline: malformed line entry (no :)\n"));
+                       continue;
+               }
                return linebuf_len;
        }
        return -1;
@@ -319,49 +327,3 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
   return(s);
 }
 
-/****************************************************************************
-checks if a file has changed since last read
-****************************************************************************/
-BOOL file_modified(const char *filename, time_t *lastmodified)
-{
-       SMB_STRUCT_STAT st;
-
-       if (sys_stat(filename, &st) != 0)
-       {
-               DEBUG(0, ("file_changed: Unable to stat file %s. Error was %s\n",
-                         filename, strerror(errno) ));
-               return False;
-       }
-
-       if(st.st_mtime <= *lastmodified)
-       {
-               DEBUG(20, ("file_modified: %s not modified\n", filename));
-               return False;
-       }
-
-       DEBUG(20, ("file_modified: %s modified\n", filename));
-       *lastmodified = st.st_mtime;
-       return True;
-}
-
-/***************************************************************************
-opens a file if modified otherwise returns NULL
-***************************************************************************/
-void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified)
-{
-       FILE *f;
-
-       if (!file_modified(filename, lastmodified))
-       {
-               return NULL;
-       }
-
-       if( (f = fopen(filename, mode)) == NULL)
-       {
-               DEBUG(0, ("open_file_if_modified: can't open file %s. Error was %s\n",
-                         filename, strerror(errno)));
-               return NULL;
-       }
-
-       return (void *)f;
-}
index a96648448419dbbcf0e1df29b9f97a96369e1de5..9e5154d259e5374a43851f541712193c0484cd22 100644 (file)
@@ -3,6 +3,8 @@
    Version 1.9.
    Samba utility functions
    Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
+   Copyright (C) Jeremy Allison  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
 
 
 extern int DEBUGLEVEL;
+DOM_SID global_sam_sid;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
+/*
+ * Some useful sids
+ */
+
+DOM_SID global_sid_S_1_5_0x20; /* local well-known domain */
+DOM_SID global_sid_World_Domain;    /* everyone */
+DOM_SID global_sid_World;    /* everyone */
+DOM_SID global_sid_Creator_Owner_Domain;    /* Creator Owner */
+DOM_SID global_sid_Creator_Owner;    /* Creator Owner */
+DOM_SID global_sid_NT_Authority;    /* NT Authority */
+
+typedef struct _known_sid_users {
+       uint32 rid;
+       uint8 sid_name_use;
+       char *known_user_name;
+} known_sid_users;
+
+/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
+static known_sid_users everyone_users[] = {{ 0, SID_NAME_WKN_GRP, "Everyone" }, {0, 0, NULL}};
+static known_sid_users creator_owner_users[] = {{ 0, SID_NAME_ALIAS, "Creator Owner" }, {0, 0, NULL}};
+static known_sid_users nt_authority_users[] = {{ 1, SID_NAME_ALIAS, "Dialup" },
+                                                                                          { 2, SID_NAME_ALIAS, "Network"},
+                                                                                          { 3, SID_NAME_ALIAS, "Batch"},
+                                                                                          { 4, SID_NAME_ALIAS, "Interactive"},
+                                                                                          { 6, SID_NAME_ALIAS, "Service"},
+                                                                                          { 7, SID_NAME_ALIAS, "AnonymousLogon"},
+                                                                                          { 8, SID_NAME_ALIAS, "Proxy"},
+                                                                                          { 9, SID_NAME_ALIAS, "ServerLogon"},
+                                                                                          {0, 0, NULL}};
+
+static struct sid_name_map_info
+{
+       DOM_SID *sid;
+       char *name;
+       known_sid_users *known_users;
+}
+sid_name_map[] =
+{
+       { &global_sam_sid, global_myname, NULL},
+       { &global_sam_sid, global_myworkgroup, NULL},
+       { &global_sid_S_1_5_0x20, "BUILTIN", NULL},
+       { &global_sid_World_Domain, "", &everyone_users[0] },
+       { &global_sid_Creator_Owner_Domain, "", &creator_owner_users[0] },
+       { &global_sid_NT_Authority, "NT Authority", &nt_authority_users[0] },
+       { NULL, NULL, NULL}
+};
+
+/****************************************************************************
+ Creates some useful well known sids
+****************************************************************************/
+
+void generate_wellknown_sids(void)
+{
+       string_to_sid(&global_sid_S_1_5_0x20, "S-1-5-32");
+       string_to_sid(&global_sid_World_Domain, "S-1-1");
+       string_to_sid(&global_sid_World, "S-1-1-0");
+       string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
+       string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
+       string_to_sid(&global_sid_NT_Authority, "S-1-5");
+}
+
+/**************************************************************************
+ Turns a domain SID into a name, returned in the nt_domain argument.
+***************************************************************************/
+
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain)
+{
+       fstring sid_str;
+       int i = 0;
+       sid_to_string(sid_str, sid);
+
+       DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
+
+       if (nt_domain == NULL)
+               return False;
+
+       while (sid_name_map[i].sid != NULL) {
+               sid_to_string(sid_str, sid_name_map[i].sid);
+               DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str));
+               if (sid_equal(sid_name_map[i].sid, sid)) {
+                       fstrcpy(nt_domain, sid_name_map[i].name);
+                       DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain));
+                       return True;
+               }
+               i++;
+       }
+
+       DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str));
+
+    return False;
+}
+
+/**************************************************************************
+ Looks up a known username from one of the known domains.
+***************************************************************************/
+
+BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use)
+{
+       int i = 0;
+       struct sid_name_map_info *psnm;
+
+       for(i = 0; sid_name_map[i].sid != NULL; i++) {
+               psnm = &sid_name_map[i];
+               if(sid_equal(psnm->sid, sid)) {
+                       int j;
+                       for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) {
+                               if(rid == psnm->known_users[j].rid) {
+                                       DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n",
+                                               (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name ));
+                                       fstrcpy( name, psnm->known_users[j].known_user_name);
+                                       *psid_name_use = psnm->known_users[j].sid_name_use;
+                                       return True;
+                               }
+                       }
+               }
+       }
+
+       return False;
+}
+
+/**************************************************************************
+ Turns a domain name into a SID.
+ *** side-effect: if the domain name is NULL, it is set to our domain ***
+***************************************************************************/
+
+BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain)
+{
+       int i = 0;
+
+       if (nt_domain == NULL) {
+               DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n"));
+               sid_copy(sid, &global_sam_sid);
+               return True;
+       }
+
+       if (nt_domain[0] == 0) {
+               fstrcpy(nt_domain, global_myname);
+               DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain));
+               sid_copy(sid, &global_sam_sid);
+               return True;
+    }
+
+       DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain));
+
+       while (sid_name_map[i].name != NULL) {
+               DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name));
+               if (strequal(sid_name_map[i].name, nt_domain)) {
+                       fstring sid_str;
+                       sid_copy(sid, sid_name_map[i].sid);
+                       sid_to_string(sid_str, sid_name_map[i].sid);
+                       DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str));
+                       return True;
+               }
+               i++;
+       }
+
+       DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain));
+       return False;
+}
+
+/**************************************************************************
+ Splits a name of format \DOMAIN\name or name into its two components.
+ Sets the DOMAIN name to global_myname if it has not been specified.
+***************************************************************************/
+
+void split_domain_name(const char *fullname, char *domain, char *name)
+{
+       pstring full_name;
+       char *p;
+
+       *domain = *name = '\0';
 
+       if (fullname[0] == '\\')
+               fullname++;
+
+       pstrcpy(full_name, fullname);
+       p = strchr(full_name+1, '\\');
+
+       if (p != NULL) {
+               *p = 0;
+               fstrcpy(domain, full_name);
+               fstrcpy(name, p+1);
+       } else {
+               fstrcpy(domain, global_myname);
+               fstrcpy(name, full_name);
+       }
+
+       DEBUG(10,("split_domain_name:name '%s' split into domain :'%s' and user :'%s'\n",
+                       fullname, domain, name));
+}
 
 /*****************************************************************
  Convert a SID to an ascii string.
 *****************************************************************/
 
-char *sid_to_string(pstring sidstr_out, const DOM_SID *sid)
+char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
 {
   char subauth[16];
   int i;
@@ -39,12 +234,11 @@ char *sid_to_string(pstring sidstr_out, const DOM_SID *sid)
               (sid->id_auth[3] << 16) +
               (sid->id_auth[2] << 24);
 
-  slprintf(sidstr_out, sizeof(pstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
+  slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
 
-  for (i = 0; i < sid->num_auths; i++)
-  {
+  for (i = 0; i < sid->num_auths; i++) {
     slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
-    pstrcat(sidstr_out, subauth);
+    fstrcat(sidstr_out, subauth);
   }
 
   DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
@@ -55,72 +249,68 @@ char *sid_to_string(pstring sidstr_out, const DOM_SID *sid)
  Convert a string to a SID. Returns True on success, False on fail.
 *****************************************************************/  
    
-BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
+BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
 {
-       const char *p = sidstr;
-       /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-       uint32 ia;
+  pstring tok;
+  char *p = sidstr;
+  /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+  uint32 ia;
 
-       memset((char *)sidout, '\0', sizeof(DOM_SID));
+  memset((char *)sidout, '\0', sizeof(DOM_SID));
 
-       if (StrnCaseCmp( sidstr, "S-", 2))
-       {
-               DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
-               return False;
-       }
+  if (StrnCaseCmp( sidstr, "S-", 2)) {
+    DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+    return False;
+  }
 
-       if ((p = strchr(p, '-')) == NULL)
-       {
-               DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-               return False;
-       }
+  p += 2;
+  if (!next_token(&p, tok, "-", sizeof(tok))) {
+    DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+    return False;
+  }
 
-       p++;
+  /* Get the revision number. */
+  sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);
 
-       /* Get the revision number. */
-       sidout->sid_rev_num = (uint8)strtoul(p,NULL,10);
+  if (!next_token(&p, tok, "-", sizeof(tok))) {
+    DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+    return False;
+  }
 
-       if ((p = strchr(p, '-')) == NULL)
-       {
-               DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
-               return False;
-       }
+  /* identauth in decimal should be <  2^32 */
+  ia = (uint32)strtoul(tok, NULL, 10);
+
+  /* NOTE - the ia value is in big-endian format. */
+  sidout->id_auth[0] = 0;
+  sidout->id_auth[1] = 0;
+  sidout->id_auth[2] = (ia & 0xff000000) >> 24;
+  sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
+  sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
+  sidout->id_auth[5] = (ia & 0x000000ff);
+
+  sidout->num_auths = 0;
+
+  while(next_token(&p, tok, "-", sizeof(tok)) && 
+       sidout->num_auths < MAXSUBAUTHS) {
+    /* 
+     * NOTE - the subauths are in native machine-endian format. They
+     * are converted to little-endian when linearized onto the wire.
+     */
+       sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
+  }
 
-       p++;
-
-       /* identauth in decimal should be <  2^32 */
-       ia = (uint32)strtoul(p,NULL,10);
-
-       /* NOTE - the ia value is in big-endian format. */
-       sidout->id_auth[0] = 0;
-       sidout->id_auth[1] = 0;
-       sidout->id_auth[2] = (ia & 0xff000000) >> 24;
-       sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
-       sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
-       sidout->id_auth[5] = (ia & 0x000000ff);
-
-       sidout->num_auths = 0;
-
-       while (((p = strchr(p, '-')) != NULL) && sidout->num_auths < MAXSUBAUTHS)
-       {
-               p++;
-               /*
-                * NOTE - the subauths are in native machine-endian format. They
-                * are converted to little-endian when linearized onto the wire.
-                */
-               sid_append_rid(sidout, (uint32)strtoul(p, NULL, 10));
-       }
+  DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
 
-       return True;
+  return True;
 }
 
 /*****************************************************************
add a rid to the end of a sid
Add a rid to the end of a sid
 *****************************************************************/  
+
 BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
 {
-       if (sid->num_auths < MAXSUBAUTHS)
-       {
+       if (sid->num_auths < MAXSUBAUTHS) {
                sid->sub_auths[sid->num_auths++] = rid;
                return True;
        }
@@ -128,413 +318,109 @@ BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
 }
 
 /*****************************************************************
removes the last rid from the end of a sid
Removes the last rid from the end of a sid
 *****************************************************************/  
+
 BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
 {
-       if (sid->num_auths > 0)
-       {
+       if (sid->num_auths > 0) {
                sid->num_auths--;
-               if (rid != NULL)
-               {
-                       (*rid) = sid->sub_auths[sid->num_auths];
-               }
+               *rid = sid->sub_auths[sid->num_auths];
                return True;
        }
        return False;
 }
 
 /*****************************************************************
copies a sid
Copies a sid
 *****************************************************************/  
-void sid_copy(DOM_SID *sid1, const DOM_SID *sid2)
-{
-       int i;
-
-       for (i = 0; i < 6; i++)
-       {
-               sid1->id_auth[i] = sid2->id_auth[i];
-       }
-
-       for (i = 0; i < sid2->num_auths; i++)
-       {
-               sid1->sub_auths[i] = sid2->sub_auths[i];
-       }
 
-       sid1->num_auths   = sid2->num_auths;
-       sid1->sid_rev_num = sid2->sid_rev_num;
-}
-
-/*****************************************************************
- compare two sids up to the auths of the first sid
-*****************************************************************/  
-BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2)
+void sid_copy(DOM_SID *dst, DOM_SID *src)
 {
        int i;
 
-       /* compare most likely different rids, first: i.e start at end */
-       for (i = sid1->num_auths-1; i >= 0; --i)
-       {
-               if (sid1->sub_auths[i] != sid2->sub_auths[i]) return False;
-       }
-
-       if (sid1->num_auths   >  sid2->num_auths  ) return False;
-       if (sid1->sid_rev_num != sid2->sid_rev_num) return False;
+       dst->sid_rev_num = src->sid_rev_num;
+       dst->num_auths = src->num_auths;
 
-       for (i = 0; i < 6; i++)
-       {
-               if (sid1->id_auth[i] != sid2->id_auth[i]) return False;
-       }
+       memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
 
-       return True;
+       for (i = 0; i < src->num_auths; i++)
+               dst->sub_auths[i] = src->sub_auths[i];
 }
 
-/*****************************************************************
- compare two sids
-*****************************************************************/  
-BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
-{
-       int i;
-
-       /* compare most likely different rids, first: i.e start at end */
-       for (i = sid1->num_auths-1; i >= 0; --i)
-       {
-               if (sid1->sub_auths[i] != sid2->sub_auths[i]) return False;
-       }
-
-       if (sid1->num_auths   != sid2->num_auths  ) return False;
-       if (sid1->sid_rev_num != sid2->sid_rev_num) return False;
-
-       for (i = 0; i < 6; i++)
-       {
-               if (sid1->id_auth[i] != sid2->id_auth[i]) return False;
-       }
-
-       return True;
-}
-
-
-/*****************************************************************
- calculates size of a sid
-*****************************************************************/  
-int sid_size(const DOM_SID *sid)
-{
-       if (sid == NULL)
-       {
-               return 0;
-       }
-       return sid->num_auths * sizeof(uint32) + 8;
-}
-
-
 /*****************************************************************
  Duplicates a sid - mallocs the target.
 *****************************************************************/
 
-DOM_SID *sid_dup(const DOM_SID *src)
+DOM_SID *sid_dup(DOM_SID *src)
 {
   DOM_SID *dst;
 
   if(!src)
     return NULL;
 
-  if((dst = (DOM_SID*)malloc(sizeof(DOM_SID))) != NULL) {
-       memset(dst, '\0', sizeof(DOM_SID));
-       sid_copy( dst, src);
+  if((dst = malloc(sizeof(DOM_SID))) != NULL) {
+       memset(dst, '\0', sizeof(DOM_SID));
+       sid_copy( dst, src);
   }
 
   return dst;
 }
 
+/*****************************************************************
+ Write a sid out into on-the-wire format.
+*****************************************************************/  
 
-/****************************************************************************
- Read a SID from a file.
-****************************************************************************/
-
-static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
-{   
-  fstring fline;
-       fstring sid_str;
-    
-  memset(fline, '\0', sizeof(fline));
-
-  if (read(fd, fline, sizeof(fline) -1 ) < 0) {
-    DEBUG(0,("unable to read file %s. Error was %s\n",
-           sid_file, strerror(errno) ));
-    return False;
-  }
-
-  /*
-   * Convert to the machine SID.
-   */
-
-  fline[sizeof(fline)-1] = '\0';
-  if (!string_to_sid(sid, fline)) {
-    DEBUG(0,("unable to read sid.\n"));
-    return False;
-  }
-
-       sid_to_string(sid_str, sid);
-       DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
-
-  return True;
-}
-
-/****************************************************************************
- Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
- not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
-****************************************************************************/
-BOOL read_sid(char *domain_name, DOM_SID *sid)
+BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
 {
-       int fd;
-       char *p;
-       pstring sid_file;
-       fstring file_name;
-       SMB_STRUCT_STAT st;
-
-       pstrcpy(sid_file, lp_smb_passwd_file());
-
-       DEBUG(10,("read_sid: Domain: %s\n", domain_name));
+       size_t i;
 
-       if (sid_file[0] == 0)
-       {
-               DEBUG(0,("cannot find smb passwd file\n"));
+       if(len < sid_size(sid))
                return False;
-       }
-
-       p = strrchr(sid_file, '/');
-       if (p != NULL)
-       {
-               *++p = '\0';
-       }
 
-       if (!directory_exist(sid_file, NULL))
-       {
-               if (mkdir(sid_file, 0700) != 0)
-               {
-                       DEBUG(0,("can't create private directory %s : %s\n",
-                                sid_file, strerror(errno)));
-                       return False;
-               }
-       }
+       SCVAL(outbuf,0,sid->sid_rev_num);
+       SCVAL(outbuf,1,sid->num_auths);
+       memcpy(&outbuf[2], sid->id_auth, 6);
+       for(i = 0; i < sid->num_auths; i++)
+               SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]);
 
-       slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
-       strupper(file_name);
-       pstrcat(sid_file, file_name);
-    
-       if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
-               DEBUG(0,("unable to open or create file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               return False;
-       } 
-  
-       /*
-        * Check if the file contains data.
-        */
-       
-       if (sys_fstat(fd, &st) < 0) {
-               DEBUG(0,("unable to stat file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-  
-       if (st.st_size == 0)
-       {
-               close(fd);
-               return False;
-       }
-
-       /*
-        * We have a valid SID - read it.
-        */
-
-       if (!read_sid_from_file(fd, sid_file, sid))
-       {
-               DEBUG(0,("unable to read file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       }
-       close(fd);
        return True;
-}   
+}
 
+/*****************************************************************
+ Compare two sids.
+*****************************************************************/  
 
-/****************************************************************************
- Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
- not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
-****************************************************************************/
-BOOL write_sid(char *domain_name, DOM_SID *sid)
+BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2)
 {
-       int fd;
-       char *p;
-       pstring sid_file;
-       fstring sid_string;
-       fstring file_name;
-       SMB_STRUCT_STAT st;
-
-       pstrcpy(sid_file, lp_smb_passwd_file());
-       sid_to_string(sid_string, sid);
+       int i;
 
-       DEBUG(10,("write_sid: Domain: %s SID: %s\n", domain_name, sid_string));
-       fstrcat(sid_string, "\n");
+       /* compare most likely different rids, first: i.e start at end */
+       for (i = sid1->num_auths-1; i >= 0; --i)
+               if (sid1->sub_auths[i] != sid2->sub_auths[i])
+                       return False;
 
-       if (sid_file[0] == 0)
-       {
-               DEBUG(0,("cannot find smb passwd file\n"));
+       if (sid1->num_auths != sid2->num_auths)
+               return False;
+       if (sid1->sid_rev_num != sid2->sid_rev_num)
                return False;
-       }
-
-       p = strrchr(sid_file, '/');
-       if (p != NULL)
-       {
-               *++p = '\0';
-       }
 
-       if (!directory_exist(sid_file, NULL)) {
-               if (mkdir(sid_file, 0700) != 0) {
-                       DEBUG(0,("can't create private directory %s : %s\n",
-                                sid_file, strerror(errno)));
+       for (i = 0; i < 6; i++)
+               if (sid1->id_auth[i] != sid2->id_auth[i])
                        return False;
-               }
-       }
 
-       slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
-       strupper(file_name);
-       pstrcat(sid_file, file_name);
-    
-       if ((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
-               DEBUG(0,("unable to open or create file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               return False;
-       } 
-  
-       /*
-        * Check if the file contains data.
-        */
-       
-       if (sys_fstat(fd, &st) < 0) {
-               DEBUG(0,("unable to stat file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-  
-       if (st.st_size > 0)
-       {
-               /*
-                * We have a valid SID already.
-                */
-               close(fd);
-               DEBUG(0,("SID file %s already exists\n", sid_file));
-               return False;
-       } 
-  
-       if (!do_file_lock(fd, 60, F_WRLCK))
-       {
-               DEBUG(0,("unable to lock file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-  
-       /*
-        * At this point we have a blocking lock on the SID
-        * file - check if in the meantime someone else wrote
-        * SID data into the file. If so - they were here first,
-        * use their data.
-        */
-       
-       if (sys_fstat(fd, &st) < 0)
-       {
-               DEBUG(0,("unable to stat file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-  
-       if (st.st_size > 0)
-       {
-               /*
-                * Unlock as soon as possible to reduce
-                * contention on the exclusive lock.
-                */ 
-               do_file_lock(fd, 60, F_UNLCK);
-               
-               /*
-                * We have a valid SID already.
-                */
-               
-               DEBUG(0,("SID file %s already exists\n", sid_file));
-               close(fd);
-               return False;
-       } 
-       
-       /*
-        * The file is still empty and we have an exlusive lock on it.
-        * Write out out SID data into the file.
-        */
-       
-       if (fchmod(fd, 0644) < 0)
-       {
-               DEBUG(0,("unable to set correct permissions on file %s. \
-Error was %s\n", sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-       
-       if (write(fd, sid_string, strlen(sid_string)) != strlen(sid_string))
-       {
-               DEBUG(0,("unable to write file %s. Error was %s\n",
-                        sid_file, strerror(errno) ));
-               close(fd);
-               return False;
-       } 
-       
-       /*
-        * Unlock & exit.
-        */
-       
-       do_file_lock(fd, 60, F_UNLCK);
-       close(fd);
        return True;
-}   
+}
 
-/****************************************************************************
-create a random SID.
-****************************************************************************/
-BOOL create_new_sid(DOM_SID *sid)
-{
-       uchar raw_sid_data[12];
-       fstring sid_string;
-       int i;
 
-       /*
-        * Generate the new sid data & turn it into a string.
-        */
-       generate_random_buffer(raw_sid_data, 12, True);
-               
-       fstrcpy(sid_string, "S-1-5-21");
-       for(i = 0; i < 3; i++)
-       {
-               fstring tmp_string;
-               slprintf(tmp_string, sizeof(tmp_string) - 1, "-%u", IVAL(raw_sid_data, i*4));
-               fstrcat(sid_string, tmp_string);
-       }
-       
-       fstrcat(sid_string, "\n");
-       
-       /*
-        * Ensure our new SID is valid.
-        */
-       
-       if (!string_to_sid(sid, sid_string))
-       {
-               DEBUG(0,("unable to generate machine SID.\n"));
-               return False;
-       } 
+/*****************************************************************
+ Calculates size of a sid.
+*****************************************************************/  
 
-       return True;
+size_t sid_size(DOM_SID *sid)
+{
+       if (sid == NULL)
+               return 0;
+
+       return sid->num_auths * sizeof(uint32) + 8;
 }
-  
index d9b0f972590bb4ab71e803a60dea6ab16496ef3c..77ba4a7f4c5bb2dae24026874c6d358a9300ed3a 100644 (file)
@@ -35,22 +35,18 @@ BOOL passive = False;
 /* the client file descriptor */
 int Client = -1;
 
-/* the port, where client connected */
-int ClientPort = 0;
-
 /* the last IP received from */
 struct in_addr lastip;
 
 /* the last port received from */
 int lastport=0;
 
-
 int smb_read_error = 0;
 
-
 /****************************************************************************
-determine if a file descriptor is in fact a socket
+ Determine if a file descriptor is in fact a socket.
 ****************************************************************************/
+
 BOOL is_a_socket(int fd)
 {
   int v,l;
@@ -58,7 +54,6 @@ BOOL is_a_socket(int fd)
   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
 }
 
-
 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
 
 struct
@@ -101,69 +96,63 @@ struct
 #endif
   {NULL,0,0,0,0}};
 
-       
-
 /****************************************************************************
-set user socket options
+ Set user socket options.
 ****************************************************************************/
+
 void set_socket_options(int fd, char *options)
 {
-  fstring tok;
-
-  while (next_token(&options,tok," \t,", sizeof(tok)))
-    {
-      int ret=0,i;
-      int value = 1;
-      char *p;
-      BOOL got_value = False;
-
-      if ((p = strchr(tok,'=')))
-       {
-         *p = 0;
-         value = atoi(p+1);
-         got_value = True;
-       }
+       fstring tok;
+
+       while (next_token(&options,tok," \t,", sizeof(tok))) {
+               int ret=0,i;
+               int value = 1;
+               char *p;
+               BOOL got_value = False;
+
+               if ((p = strchr(tok,'='))) {
+                       *p = 0;
+                       value = atoi(p+1);
+                       got_value = True;
+               }
 
-      for (i=0;socket_options[i].name;i++)
-       if (strequal(socket_options[i].name,tok))
-         break;
+               for (i=0;socket_options[i].name;i++)
+                       if (strequal(socket_options[i].name,tok))
+                               break;
 
-      if (!socket_options[i].name)
-       {
-         DEBUG(0,("Unknown socket option %s\n",tok));
-         continue;
-       }
+               if (!socket_options[i].name) {
+                       DEBUG(0,("Unknown socket option %s\n",tok));
+                       continue;
+               }
 
-      switch (socket_options[i].opttype)
-       {
-       case OPT_BOOL:
-       case OPT_INT:
-         ret = setsockopt(fd,socket_options[i].level,
-                          socket_options[i].option,(char *)&value,sizeof(int));
-         break;
-
-       case OPT_ON:
-         if (got_value)
-           DEBUG(0,("syntax error - %s does not take a value\n",tok));
-
-         {
-           int on = socket_options[i].value;
-           ret = setsockopt(fd,socket_options[i].level,
-                            socket_options[i].option,(char *)&on,sizeof(int));
-         }
-         break;          
-       }
+               switch (socket_options[i].opttype) {
+               case OPT_BOOL:
+               case OPT_INT:
+                       ret = setsockopt(fd,socket_options[i].level,
+                                               socket_options[i].option,(char *)&value,sizeof(int));
+                       break;
+
+               case OPT_ON:
+                       if (got_value)
+                               DEBUG(0,("syntax error - %s does not take a value\n",tok));
+
+                       {
+                               int on = socket_options[i].value;
+                               ret = setsockopt(fd,socket_options[i].level,
+                                                       socket_options[i].option,(char *)&on,sizeof(int));
+                       }
+                       break;    
+               }
       
-      if (ret != 0)
-       DEBUG(0,("Failed to set socket option %s\n",tok));
-    }
+               if (ret != 0)
+                       DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
+       }
 }
 
-
-
 /****************************************************************************
-  close the socket communication
+ Close the socket communication.
 ****************************************************************************/
+
 void close_sockets(void )
 {
 #ifdef WITH_SSL
@@ -174,31 +163,10 @@ void close_sockets(void )
   Client = -1;
 }
 
-
-
 /****************************************************************************
-write to a socket
+ Read from a socket.
 ****************************************************************************/
-ssize_t write_socket(int fd,char *buf,size_t len)
-{
-  ssize_t ret=0;
-
-  if (passive)
-    return(len);
-  DEBUG(6,("write_socket(%d,%d)\n",fd,len));
-  ret = write_data(fd,buf,len);
-      
-  DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
-  if(ret <= 0)
-    DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
-       len, fd, strerror(errno) ));
 
-  return(ret);
-}
-
-/****************************************************************************
-read from a socket
-****************************************************************************/
 ssize_t read_udp_socket(int fd,char *buf,size_t len)
 {
   ssize_t ret;
@@ -206,8 +174,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
   int socklen;
   
   socklen = sizeof(sock);
-  bzero((char *)&sock,socklen);
-  bzero((char *)&lastip,sizeof(lastip));
+  memset((char *)&sock,'\0',socklen);
+  memset((char *)&lastip,'\0',sizeof(lastip));
   ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
   if (ret <= 0) {
     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
@@ -224,13 +192,13 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
 }
 
 /****************************************************************************
-read data from a device with a timout in msec.
-mincount = if timeout, minimum to read before returning
-maxcount = number to be read.
-time_out = timeout in milliseconds
+ Read data from a socket with a timout in msec.
+ mincount = if timeout, minimum to read before returning
+ maxcount = number to be read.
+ time_out = timeout in milliseconds
 ****************************************************************************/
 
-ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
+static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
 {
   fd_set fds;
   int selrtn;
@@ -239,7 +207,8 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
   struct timeval timeout;
 
   /* just checking .... */
-  if (maxcnt <= 0) return(0);
+  if (maxcnt <= 0)
+    return(0);
 
   smb_read_error = 0;
 
@@ -259,11 +228,13 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
 #endif /* WITH_SSL */
 
       if (readret == 0) {
+        DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
         smb_read_error = READ_EOF;
         return -1;
       }
 
       if (readret == -1) {
+        DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
         smb_read_error = READ_ERROR;
         return -1;
       }
@@ -282,22 +253,23 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
   timeout.tv_sec = (time_t)(time_out / 1000);
   timeout.tv_usec = (long)(1000 * (time_out % 1000));
 
-  for (nread=0; nread < mincnt; ) 
-  {      
+  for (nread=0; nread < mincnt; ) {      
     FD_ZERO(&fds);
     FD_SET(fd,&fds);
       
-    selrtn = sys_select(fd+1,&fds,NULL, &timeout);
+    selrtn = sys_select(fd+1,&fds,&timeout);
 
     /* Check if error */
     if(selrtn == -1) {
       /* something is wrong. Maybe the socket is dead? */
+      DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
       smb_read_error = READ_ERROR;
       return -1;
     }
-      
+
     /* Did we timeout ? */
     if (selrtn == 0) {
+      DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
       smb_read_error = READ_TIMEOUT;
       return -1;
     }
@@ -314,12 +286,14 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
 
     if (readret == 0) {
       /* we got EOF on the file descriptor */
+      DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
       smb_read_error = READ_EOF;
       return -1;
     }
 
     if (readret == -1) {
       /* the descriptor is probably dead */
+      DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
       smb_read_error = READ_ERROR;
       return -1;
     }
@@ -331,10 +305,91 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
   return((ssize_t)nread);
 }
 
+/****************************************************************************
+ Read data from a fd with a timout in msec.
+ mincount = if timeout, minimum to read before returning
+ maxcount = number to be read.
+ time_out = timeout in milliseconds
+****************************************************************************/
+
+ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
+{
+  fd_set fds;
+  int selrtn;
+  ssize_t readret;
+  size_t nread = 0;
+  struct timeval timeout;
+
+  /* just checking .... */
+  if (maxcnt <= 0)
+    return(0);
+
+  /* Blocking read */
+  if (time_out <= 0) {
+    if (mincnt == 0) mincnt = maxcnt;
+
+    while (nread < mincnt) {
+#ifdef WITH_SSL
+      if(fd == sslFd){
+        readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+      }else{
+        readret = read(fd, buf + nread, maxcnt - nread);
+      }
+#else /* WITH_SSL */
+      readret = read(fd, buf + nread, maxcnt - nread);
+#endif /* WITH_SSL */
+
+      if (readret <= 0)
+       return readret;
+
+      nread += readret;
+    }
+    return((ssize_t)nread);
+  }
+  
+  /* Most difficult - timeout read */
+  /* If this is ever called on a disk file and 
+     mincnt is greater then the filesize then
+     system performance will suffer severely as 
+     select always returns true on disk files */
+
+  /* Set initial timeout */
+  timeout.tv_sec = (time_t)(time_out / 1000);
+  timeout.tv_usec = (long)(1000 * (time_out % 1000));
+
+  for (nread=0; nread < mincnt; ) {      
+    FD_ZERO(&fds);
+    FD_SET(fd,&fds);
+      
+    selrtn = sys_select(fd+1,&fds,&timeout);
+
+    if(selrtn <= 0)
+      return selrtn;
+      
+#ifdef WITH_SSL
+    if(fd == sslFd){
+      readret = SSL_read(ssl, buf + nread, maxcnt - nread);
+    }else{
+      readret = read(fd, buf + nread, maxcnt - nread);
+    }
+#else /* WITH_SSL */
+    readret = read(fd, buf+nread, maxcnt-nread);
+#endif /* WITH_SSL */
+
+    if (readret <= 0)
+      return readret;
+
+    nread += readret;
+  }
+
+  /* Return the number we got */
+  return((ssize_t)nread);
+}
 
 /****************************************************************************
 send a keepalive packet (rfc1002)
 ****************************************************************************/
+
 BOOL send_keepalive(int client)
 {
   unsigned char buf[4];
@@ -342,14 +397,13 @@ BOOL send_keepalive(int client)
   buf[0] = 0x85;
   buf[1] = buf[2] = buf[3] = 0;
 
-  return(write_data(client,(char *)buf,4) == 4);
+  return(write_socket_data(client,(char *)buf,4) == 4);
 }
 
-
-
 /****************************************************************************
   read data from the client, reading exactly N bytes. 
 ****************************************************************************/
+
 ssize_t read_data(int fd,char *buffer,size_t N)
 {
   ssize_t  ret;
@@ -371,11 +425,13 @@ ssize_t read_data(int fd,char *buffer,size_t N)
 
     if (ret == 0)
     {
+      DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
       smb_read_error = READ_EOF;
       return 0;
     }
     if (ret == -1)
     {
+      DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
       smb_read_error = READ_ERROR;
       return -1;
     }
@@ -384,10 +440,50 @@ ssize_t read_data(int fd,char *buffer,size_t N)
   return (ssize_t)total;
 }
 
+/****************************************************************************
+ Read data from a socket, reading exactly N bytes. 
+****************************************************************************/
+
+static ssize_t read_socket_data(int fd,char *buffer,size_t N)
+{
+  ssize_t  ret;
+  size_t total=0;  
+  smb_read_error = 0;
+
+  while (total < N)
+  {
+#ifdef WITH_SSL
+    if(fd == sslFd){
+      ret = SSL_read(ssl, buffer + total, N - total);
+    }else{
+      ret = read(fd,buffer + total,N - total);
+    }
+#else /* WITH_SSL */
+    ret = read(fd,buffer + total,N - total);
+#endif /* WITH_SSL */
+
+    if (ret == 0)
+    {
+      DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
+      smb_read_error = READ_EOF;
+      return 0;
+    }
+    if (ret == -1)
+    {
+      DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
+      smb_read_error = READ_ERROR;
+      return -1;
+    }
+    total += ret;
+  }
+  return (ssize_t)total;
+}
 
 /****************************************************************************
-  write data to a fd 
+ Write data to a fd.
 ****************************************************************************/
+
 ssize_t write_data(int fd,char *buffer,size_t N)
 {
   size_t total=0;
@@ -405,7 +501,42 @@ ssize_t write_data(int fd,char *buffer,size_t N)
     ret = write(fd,buffer + total,N - total);
 #endif /* WITH_SSL */
 
-    if (ret == -1) return -1;
+    if (ret == -1) {
+      DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
+      return -1;
+    }
+    if (ret == 0) return total;
+
+    total += ret;
+  }
+  return (ssize_t)total;
+}
+
+/****************************************************************************
+ Write data to a socket - use send rather than write.
+****************************************************************************/
+
+ssize_t write_socket_data(int fd,char *buffer,size_t N)
+{
+  size_t total=0;
+  ssize_t ret;
+
+  while (total < N)
+  {
+#ifdef WITH_SSL
+    if(fd == sslFd){
+      ret = SSL_write(ssl,buffer + total,N - total);
+    }else{
+      ret = send(fd,buffer + total,N - total, 0);
+    }
+#else /* WITH_SSL */
+    ret = send(fd,buffer + total,N - total,0);
+#endif /* WITH_SSL */
+
+    if (ret == -1) {
+      DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
+      return -1;
+    }
     if (ret == 0) return total;
 
     total += ret;
@@ -413,7 +544,26 @@ ssize_t write_data(int fd,char *buffer,size_t N)
   return (ssize_t)total;
 }
 
+/****************************************************************************
+write to a socket
+****************************************************************************/
 
+ssize_t write_socket(int fd,char *buf,size_t len)
+{
+  ssize_t ret=0;
+
+  if (passive)
+    return(len);
+  DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
+  ret = write_socket_data(fd,buf,len);
+      
+  DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
+  if(ret <= 0)
+    DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
+       (int)len, fd, strerror(errno) ));
+
+  return(ret);
+}
 
 /****************************************************************************
 read 4 bytes of a smb packet and return the smb length of the packet
@@ -422,6 +572,7 @@ This version of the function will return a length of zero on receiving
 a keepalive packet.
 timeout is in milliseconds.
 ****************************************************************************/
+
 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
 {
   ssize_t len=0;
@@ -431,9 +582,9 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
   while (!ok)
   {
     if (timeout > 0)
-      ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
+      ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
     else 
-      ok = (read_data(fd,inbuf,4) == 4);
+      ok = (read_socket_data(fd,inbuf,4) == 4);
 
     if (!ok)
       return(-1);
@@ -456,6 +607,7 @@ store the result in the buffer. This version of the function will
 never return a session keepalive (length of zero).
 timeout is in milliseconds.
 ****************************************************************************/
+
 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
 {
   ssize_t len;
@@ -472,6 +624,8 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
       break;
   }
 
+  DEBUG(10,("read_smb_length: got smb length of %d\n",len));
+
   return len;
 }
 
@@ -482,13 +636,14 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
   This function will return on a
   receipt of a session keepalive packet.
 ****************************************************************************/
+
 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
 {
   ssize_t len,ret;
 
   smb_read_error = 0;
 
-  bzero(buffer,smb_size + 100);
+  memset(buffer,'\0',smb_size + 100);
 
   len = read_smb_length_return_keepalive(fd,buffer,timeout);
   if (len < 0)
@@ -506,7 +661,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
   }
 
   if(len > 0) {
-    ret = read_data(fd,buffer+4,len);
+    ret = read_socket_data(fd,buffer+4,len);
     if (ret != len) {
       smb_read_error = READ_ERROR;
       return False;
@@ -529,7 +684,6 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
 {
   BOOL ret;
-  uint8 msg_type;
 
   for(;;)
   {
@@ -543,25 +697,45 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
     }
 
     /* Ignore session keepalive packets. */
-    msg_type = CVAL(buffer,0);
-    if (msg_type != 0x85)
+    if(CVAL(buffer,0) != 0x85)
       break;
   }
-       if (msg_type == 0)
-       {
-               show_msg(buffer);
-       }
-       else
-       {
-               dump_data(10, buffer, smb_len(buffer) + 4);
-       }
   show_msg(buffer);
   return ret;
 }
 
+/****************************************************************************
+  send an null session message to a fd
+****************************************************************************/
+
+BOOL send_null_session_msg(int fd)
+{
+  ssize_t ret;
+  uint32 blank = 0;
+  size_t len = 4;
+  size_t nwritten=0;
+  char *buffer = (char *)&blank;
+
+  while (nwritten < len)
+  {
+    ret = write_socket(fd,buffer+nwritten,len - nwritten);
+    if (ret <= 0)
+    {
+      DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
+      close_sockets();
+      exit(1);
+    }
+    nwritten += ret;
+  }
+
+  DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n"));
+  return True;
+}
+
 /****************************************************************************
   send an smb to a fd 
 ****************************************************************************/
+
 BOOL send_smb(int fd,char *buffer)
 {
   size_t len;
@@ -574,7 +748,7 @@ BOOL send_smb(int fd,char *buffer)
     ret = write_socket(fd,buffer+nwritten,len - nwritten);
     if (ret <= 0)
     {
-      DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
+      DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
       close_sockets();
       exit(1);
     }
@@ -584,11 +758,10 @@ BOOL send_smb(int fd,char *buffer)
   return True;
 }
 
-
-
 /****************************************************************************
 send a single packet to a port on another machine
 ****************************************************************************/
+
 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
 {
   BOOL ret;
@@ -607,7 +780,7 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
     }
 
   /* set the address and port */
-  bzero((char *)&sock_out,sizeof(sock_out));
+  memset((char *)&sock_out,'\0',sizeof(sock_out));
   putip((char *)&sock_out.sin_addr,(char *)&ip);
   sock_out.sin_port = htons( port );
   sock_out.sin_family = AF_INET;
@@ -627,11 +800,11 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
   return(ret);
 }
 
-
 /****************************************************************************
 open a socket of the specified type, port and address for incoming data
 ****************************************************************************/
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
+
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
 {
   struct hostent *hp;
   struct sockaddr_in sock;
@@ -649,7 +822,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
       return -1;
     }
   
-  bzero((char *)&sock,sizeof(sock));
+  memset((char *)&sock,'\0',sizeof(sock));
   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
 
 #ifdef HAVE_SOCK_SIN_LEN
@@ -663,8 +836,12 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
     { DEBUG(0,("socket failed\n")); return -1; }
 
   {
-    int one=1;
-    setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+    int val=1;
+       if(rebind)
+               val=1;
+       else
+               val=0;
+    setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
   }
 
   /* now we've got a socket - we need to bind it */
@@ -680,7 +857,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
          port = 7999;
 
        if (port >= 1000 && port < 9000)
-         return(open_socket_in(type,port+1,dlevel,socket_addr));
+         return(open_socket_in(type,port+1,dlevel,socket_addr,rebind));
       }
 
       return(-1); 
@@ -690,16 +867,16 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
   return res;
 }
 
-
 /****************************************************************************
-  create an outgoing socket
+  create an outgoing socket. timeout is in milliseconds.
   **************************************************************************/
+
 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
 {
   struct sockaddr_in sock_out;
   int res,ret;
   int connect_loop = 250; /* 250 milliseconds */
-  int loops = (timeout * 1000) / connect_loop;
+  int loops = (timeout) / connect_loop;
 
   /* create a socket to write to */
   res = socket(PF_INET, type, 0);
@@ -708,7 +885,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
 
   if (type != SOCK_STREAM) return(res);
   
-  bzero((char *)&sock_out,sizeof(sock_out));
+  memset((char *)&sock_out,'\0',sizeof(sock_out));
   putip((char *)&sock_out.sin_addr,(char *)addr);
   
   sock_out.sin_port = htons( port );
@@ -786,6 +963,7 @@ void reset_globals_after_fork(void)
 /*******************************************************************
  return the DNS name of the client 
  ******************************************************************/
+
 char *client_name(int fd)
 {
        struct sockaddr sa;
@@ -832,6 +1010,7 @@ char *client_name(int fd)
 /*******************************************************************
  return the IP addr of the client as a string 
  ******************************************************************/
+
 char *client_addr(int fd)
 {
        struct sockaddr sa;
@@ -862,101 +1041,3 @@ char *client_addr(int fd)
        global_client_addr_done = True;
        return addr_buf;
 }
-
-/*******************************************************************
- opens and connects to a unix pipe socket
- ******************************************************************/
-int open_pipe_sock(char *path)
-{
-       int sock;
-       struct sockaddr_un sa;
-
-       sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
-       if (sock < 0)
-       {
-               DEBUG(0, ("unix socket open failed\n"));
-               return sock;
-       }
-
-       ZERO_STRUCT(sa);
-       sa.sun_family = AF_UNIX;
-       safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
-
-       DEBUG(10, ("socket open succeeded.  file name: %s\n", sa.sun_path));
-
-       if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
-       {
-               DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
-               close(sock);
-               return -1;
-       }
-
-       return sock;
-}
-
-int create_pipe_socket(char *dir, int dir_perms,
-                               char *path, int path_perms)
-{
-       int s;
-       struct sockaddr_un sa;
-
-       DEBUG(10,("create_pipe_socket: %s %d %s %d\n",
-                  dir, dir_perms, path, path_perms));
-
-       mkdir(dir, dir_perms);
-
-       if (chmod(dir, dir_perms) < 0)
-       {
-               DEBUG(0, ("chmod on %s failed\n", dir));
-               return -1;
-       }
-
-       if (!remove(path))
-       {
-               DEBUG(0, ("remove on %s failed\n", path));
-       }
-               
-       /* start listening on unix socket */
-       s = socket(AF_UNIX, SOCK_STREAM, 0);
-
-       if (s < 0)
-       {
-               DEBUG(0, ("socket open failed\n"));
-               return -1;
-       }
-
-       ZERO_STRUCT(sa);
-       sa.sun_family = AF_UNIX;
-       safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
-
-       if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
-       {
-               DEBUG(0, ("socket bind to %s failed\n", sa.sun_path));
-               close(s);
-               remove(path);
-               return -1;
-       }
-
-       if (s == -1)
-       {
-               DEBUG(0,("bind failed\n"));
-               remove(path);
-               return -1;
-       }
-
-       if (path_perms != 0)
-       {
-               chmod(path, path_perms);
-       }
-
-       if (listen(s, 5) == -1)
-       {
-               DEBUG(0,("listen failed\n"));
-               return -1;
-       }
-
-       DEBUG(5,("unix socket opened: %s\n", path));
-
-       return s;
-}
index a25043df789105b09f1cd83f76cb97a6d989bd80..58718f395a3e97d4f4f68be0f5261b34ad7cdf1a 100644 (file)
@@ -462,7 +462,7 @@ char *skip_string(char *buf,size_t n)
 {
   while (n--)
     buf += strlen(buf) + 1;
-  return buf;
+  return(buf);
 }
 
 /*******************************************************************
@@ -733,21 +733,69 @@ 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 = skip_multibyte_char( *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
 include the terminating zero.
 ********************************************************************/
+
 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 +810,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;
     }
       
@@ -775,6 +823,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
 safe string cat into a string. maxlength does not
 include the terminating zero.
 ********************************************************************/
+
 char *safe_strcat(char *dest, const char *src, size_t maxlength)
 {
     size_t src_len, dest_len;
@@ -793,7 +842,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,28 +851,48 @@ 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);
-  }
-  while ((*d++ = *src++)) ;
-  return(dest);
+       if (!src) {
+               *dest = 0;
+               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)
 {
   char *d = dest;
@@ -837,12 +906,11 @@ char *StrnCpy(char *dest,const char *src,size_t n)
   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).
 ****************************************************************************/
-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;
@@ -1003,29 +1071,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,64 +1118,50 @@ 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. 
 Use with caution!
+if len==0 then no length check is performed
 ****************************************************************************/
-void all_string_sub(char *s,const char *pattern,const char *insert)
+void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
 {
        char *p;
-       size_t ls,lp,li;
+       ssize_t ls,lp,li;
 
        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 all_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);
+               }
                memcpy(p, insert, li);
                s = p + li;
                ls += (li-lp);
        }
 }
 
-/****************************************************************************
- splits out the front and back at a separator.
-****************************************************************************/
-void split_at_first_component(char *path, char *front, char sep, char *back)
-{
-       char *p = strchr(path, sep);
-
-       if (p != NULL)
-       {
-               *p = 0;
-       }
-       if (front != NULL)
-       {
-               pstrcpy(front, path);
-       }
-       if (p != NULL)
-       {
-               if (back != NULL)
-               {
-                       pstrcpy(back, p+1);
-               }
-               *p = sep;
-       }
-       else
-       {
-               if (back != NULL)
-               {
-                       back[0] = 0;
-               }
-       }
-}
-
 /****************************************************************************
  splits out the front and back at a separator.
 ****************************************************************************/
@@ -1116,7 +1183,7 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
                {
                        pstrcpy(back, p+1);
                }
-               *p = sep;
+               *p = '\\';
        }
        else
        {
@@ -1127,72 +1194,28 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
        }
 }
 
-/****************************************************************************
-convert a bit field to a string.  if you want multiple bits to be detected
-set them first, e.g SV_TYPE_ALL to be "All" or "Full Control" for ACB_INFOs.
-
-strings are expected to contain their own separators, although the code
-below only assumes that separators are spaces.
 
+/****************************************************************************
+write an octal as a string
 ****************************************************************************/
-char *bit_field_to_str(uint32 type, struct field_info *bs)
+char *octal_string(int i)
 {
-       static fstring typestr;
-       int i = 0;
-
-       typestr[0] = 0;
-
-       if (type == 0 || bs == NULL)
-       {
-               return NULL;
-       }
-
-       while (bs[i].str != NULL && type != 0)
-       {
-               if (IS_BITS_SET_ALL(bs[i].bits, type))
-               {
-                       fstrcat(typestr, bs[i].str);
-                       type &= ~bs[i].bits;
-               }
-               i++;
-       }
-       
-       i = strlen(typestr)-1;
-       if (i > 0 && typestr[i] == ' ')
-       {
-               typestr[i] = 0;
+       static char ret[64];
+       if (i == -1) {
+               return "-1";
        }
-
-       return typestr;
+       slprintf(ret, sizeof(ret), "0%o", i);
+       return ret;
 }
 
+
 /****************************************************************************
-convert an enumeration to a string.  first item is the default.
+truncate a string at a specified length
 ****************************************************************************/
-char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default)
+char *string_truncate(char *s, int length)
 {
-       int i = 0;
-
-       if (bs == NULL)
-       {
-               return NULL;
+       if (s && strlen(s) > length) {
+               s[length] = 0;
        }
-
-       while (bs[i].str != NULL && type != 0)
-       {
-               if (bs[i].bits == type)
-               {
-                       return bs[i].str;
-               }
-               i++;
-       }
-
-       /* oops - none found */
-
-       if (first_default)
-       {
-               return bs[0].str;
-       }
-
-       return NULL;
+       return s;
 }
index 6f90528bf43c0c8c9ebd484d56327a92a0f40d4b..aee2a21fc0addd9600b7f188d0502b3da9299db3 100644 (file)
 
 #include "includes.h"
 
-/*******************************************************************
- Put an ASCII string into a UNICODE buffer (little endian).
- ********************************************************************/
+extern int DEBUGLEVEL;
 
-char *ascii_to_unibuf(char *dest, const char *src, int maxlen)
-{
-       char *destend = dest + maxlen;
-       register char c;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               if (c == 0)
-               {
-                       break;
-               }
+/*
+ * The following are the codepage to ucs2 and vica versa maps.
+ * These are dynamically loaded from a unicode translation file.
+ */
 
-               *(dest++) = c;
-               *(dest++) = 0;
-       }
+static smb_ucs2_t *doscp_to_ucs2;
+static uint16 *ucs2_to_doscp;
 
-       *dest++ = 0;
-       *dest++ = 0;
-       return dest;
-}
+static smb_ucs2_t *unixcp_to_ucs2;
+static uint16 *ucs2_to_unixcp;
 
+#ifndef MAXUNI
+#define MAXUNI 1024
+#endif
 
 /*******************************************************************
- Pull an ASCII string out of a UNICODE buffer (little endian).
- ********************************************************************/
+ 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.
 
-const char* unibuf_to_ascii(char *dest, const char *src, int maxlen)
-{
-       char *destend = dest + maxlen;
-       register char c;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               if ((c == 0) && (*src == 0))
-               {
-                       break;
-               }
+ the return value is the length of the string *without* the trailing 
+ two bytes of zero
+********************************************************************/
 
-               *dest++ = c;
-               src++;
+int dos_PutUniCode(char *dst,const char *src, ssize_t len)
+{
+       int ret = 0;
+       while (*src && (len > 2)) {
+               size_t skip = skip_multibyte_char(*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]);
+
+               SSVAL(dst,ret,doscp_to_ucs2[val]);
+               ret += 2;
+               len -= 2;
+               if (skip)
+                       src += skip;
+               else
+                       src++;
        }
+       SSVAL(dst,ret,0);
+       return(ret);
+}
 
-       *dest = 0;
+/*******************************************************************
+ Skip past some unicode strings in a buffer.
+********************************************************************/
 
-       return src;
+char *skip_unicode_string(char *buf,int n)
+{
+       while (n--) {
+               while (*buf)
+                       buf += 2;
+               buf += 2;
+       }
+       return(buf);
 }
 
-
 /*******************************************************************
- Put an ASCII string into a UNICODE array (uint16's).
- ********************************************************************/
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
 
-void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
+char *dos_unistrn2(uint16 *src, int len)
 {
-       uint16 *destend = dest + maxlen;
-       register char c;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               if (c == 0)
-               {
-                       break;
+       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);
                }
-
-               *(dest++) = (uint16)c;
        }
 
-       *dest = 0;
+       *p = 0;
+       return lbuf;
 }
 
+static char lbufs[8][MAXUNI];
+static int nexti;
 
 /*******************************************************************
- Pull an ASCII string out of a UNICODE array (uint16's).
- ********************************************************************/
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
 
-void unistr_to_ascii(char *dest, const uint16 *src, int len)
+char *dos_unistr2(uint16 *src)
 {
-       char *destend = dest + len;
-       register uint16 c;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               if (c == 0)
-               {
-                       break;
-               }
+       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];
 
-               *(dest++) = (char)c;
+               if (cp_val < 256)
+                       *p++ = (char)cp_val;
+               else {
+                       *p++ = (cp_val >> 8) & 0xff;
+                       *p++ = (cp_val & 0xff);
+               }
        }
 
-       *dest = 0;
+       *p = 0;
+       return lbuf;
 }
 
-
 /*******************************************************************
- Convert a UNISTR2 structure to an ASCII string
- ********************************************************************/
+Return a DOS codepage version of a little-endian unicode string
+********************************************************************/
 
-void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
+char *dos_unistr2_to_str(UNISTR2 *str)
 {
-       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)
-       {
-               c = *(src++);
-               if (c == 0)
-               {
-                       break;
+       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);
                }
-
-               *(dest++) = (char)c;
        }
 
-       *dest = 0;
+       *p = 0;
+       return lbuf;
 }
 
-
 /*******************************************************************
- Skip a UNICODE string in a little endian buffer.
- ********************************************************************/
+Return a number stored in a buffer
+********************************************************************/
 
-char *skip_unibuf(char *srcbuf, int len)
+uint32 buffer2_to_uint32(BUFFER2 *str)
 {
-       uint16 *src = (uint16 *)srcbuf;
-       uint16 *srcend = src + len/2;
+       if (str->buf_len == 4)
+               return IVAL(str->buffer, 0);
+       else
+               return 0;
+}
 
-       while ((src < srcend) && (*(src++) != 0))
-       {
+/*******************************************************************
+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);
+               }
        }
 
-       return (char *)src;
+       *p = 0;
+       return lbuf;
 }
 
-
 /*******************************************************************
- UNICODE strcpy between buffers.
- ********************************************************************/
+ Return a dos codepage version of a NOTunicode string
+********************************************************************/
 
-char *uni_strncpy(char *destbuf, const char *srcbuf, int len)
+char *dos_buffer2_to_multistr(BUFFER2 *str)
 {
-       const uint16 *src = (const uint16 *)srcbuf;
-       uint16 *dest = (uint16 *)destbuf;
-       uint16 *destend = dest + len/2;
-       register uint16 c;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               if (c == 0)
-               {
-                       break;
+       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);
+                       }
                }
-
-               *(dest++) = c;
        }
 
-       *dest++ = 0;
-       return (char *)dest;
+       *p = 0;
+       return lbuf;
 }
 
-
 /*******************************************************************
- Return a number stored in a buffer
- ********************************************************************/
+ 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.
+********************************************************************/
 
-uint32 buffer2_to_uint32(const BUFFER2 *str)
+size_t dos_struni2(char *dst, const char *src, size_t max_len)
 {
-       if (str->buf_len == 4)
-       {
-               const uchar *src = str->buffer;
-               return IVAL(src, 0);
-       }
-       else
-       {
+       size_t len = 0;
+
+       if (dst == NULL)
                return 0;
+
+       if (src != NULL) {
+               for (; *src && len < max_len-2; len++, dst +=2) {
+                       size_t skip = skip_multibyte_char(*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]);
+
+                       SSVAL(dst,0,doscp_to_ucs2[val]);
+                       if (skip)
+                               src += skip;
+                       else
+                               src++;
+               }
        }
-}
 
+       SSVAL(dst,0,0);
+
+       return len;
+}
 
 /*******************************************************************
-  Convert a 'multi-string' buffer to space-separated ASCII.
- ********************************************************************/
-void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen)
+ Return a DOS codepage version of a little-endian unicode string.
+ Hack alert: uses fixed buffer(s).
+********************************************************************/
+
+char *dos_unistr(char *buf)
 {
-       char *destend;
-       const uchar *src;
-       size_t len;
-       register uint16 c;
-
-       src = str->buffer;
-       len = MIN(str->buf_len/2, maxlen);
-       destend = dest + len;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               *(dest++) = (c == 0) ? ' ' : (char)c;
-               src++;
+       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);
+               }
        }
 
-       *dest = 0;
+       *p = 0;
+       return lbuf;
 }
 
 /*******************************************************************
-  Convert a buffer4 to space-separated ASCII.
- ********************************************************************/
-void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen)
+ Strcpy for unicode strings.  returns length (in num of wide chars)
+********************************************************************/
+
+int unistrcpy(char *dst, char *src)
 {
-       char *destend;
-       const uchar *src;
-       size_t len;
-       register uint16 c;
-
-       src = str->buffer;
-       len = MIN(str->buf_len, maxlen);
-       destend = dest + len;
-
-       while (dest < destend)
-       {
-               c = *(src++);
-               *(dest++) = (char)c;
+       int num_wchars = 0;
+       uint16 *wsrc = (uint16 *)src;
+       uint16 *wdst = (uint16 *)dst;
+
+       while (*wsrc) {
+               *wdst++ = *wsrc++;
+               num_wchars++;
        }
+       *wdst = 0;
 
-       *dest = 0;
+       return num_wchars;
 }
 
+
+
 /*******************************************************************
-copies a UNISTR2 structure.
+ free any existing maps
 ********************************************************************/
-BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
+static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
 {
-       if (from != NULL)
-       {
-               /* set up string lengths. add one if string is not null-terminated */
-               str->uni_max_len = from->uni_max_len;
-               str->undoc       = from->undoc;
-               str->uni_str_len = from->uni_str_len;
-
-               /* copy the string */
-               memcpy(str->buffer, from->buffer, sizeof(from->buffer));
+       /* this handles identity mappings where we share the pointer */
+       if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
+               *pp_ucs2_to_cp = NULL;
        }
-       else
-       {
-               str->uni_max_len = 1;
-               str->undoc = 0;
-               str->uni_str_len = 1;
-               str->buffer[0] = 0;
+
+       if (*pp_cp_to_ucs2) {
+               free(*pp_cp_to_ucs2);
+               *pp_cp_to_ucs2 = NULL;
        }
 
-       return True;
+       if (*pp_ucs2_to_cp) {
+               free(*pp_ucs2_to_cp);
+               *pp_ucs2_to_cp = NULL;
+       }
 }
 
+
 /*******************************************************************
-duplicates a UNISTR2 structure.
+ Build a default (null) codepage to unicode map.
 ********************************************************************/
-UNISTR2 *unistr2_dup(const UNISTR2 *name)
+
+void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
 {
-       UNISTR2 *copy = (UNISTR2*)malloc(sizeof(*copy));
-       copy_unistr2(copy, name);
-       return copy;
+  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;
 }
 
 /*******************************************************************
-frees a UNISTR2 structure.
+ Load a codepage to unicode and vica-versa map.
 ********************************************************************/
-void unistr2_free(UNISTR2 *name)
+
+BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
 {
-       free(name);
+  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);
 }
index 62c7429b59554a8a5291c959a37116403b28d2cb..4f620bc5f4197e495865b0275f597349afc45b96 100644 (file)
@@ -2,8 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    SMB client generic functions
-   Copyright (C) Andrew Tridgell 1994-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell 1994-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
 #include "includes.h"
 #include "trans2.h"
 
+
 extern int DEBUGLEVEL;
+extern pstring user_socket_options;
+extern pstring scope;
 
-/* 
- * set the port that will be used for connections by the client
- */
+static void cli_process_oplock(struct cli_state *cli);
 
+/*
+ * Change the port number used to call on 
+ */
 int cli_set_port(struct cli_state *cli, int port)
 {
-
-       if (port != 0)
+       if (port > 0)
          cli->port = port;
 
-       return cli->port;   /* return it incase caller wants it */
-
+       return cli->port;
 }
 
 /****************************************************************************
-copy a string (unicode or otherwise) into an SMB buffer.  skips a string
-plus points to next
+recv an smb
 ****************************************************************************/
-static char *cli_put_string(struct cli_state *cli, char *p, const char *str,
-                               BOOL skip_end)
+static BOOL cli_receive_smb(struct cli_state *cli)
 {
-       uint16 flgs2 = SVAL(cli->outbuf, smb_flg2);
-       if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
-       {
-               p = align2(p, cli->outbuf);
-               p = ascii_to_unibuf(p, str, 1024);
-               if (skip_end)
-               {
-                       CVAL(p, 0) = 0; p++;
-                       CVAL(p, 0) = 0; p++;
-               }
-               return p;
-       }
-       else
-       {
-               pstrcpy(p, str);
-               p = skip_string(p, 1);
-               if (skip_end)
-               {
-                       CVAL(p, 0) = 0; p++;
+       BOOL ret;
+ again:
+       ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+       
+       if (ret) {
+               /* it might be an oplock break request */
+               if (CVAL(cli->inbuf,smb_com) == SMBlockingX &&
+                   SVAL(cli->inbuf,smb_vwv6) == 0 &&
+                   SVAL(cli->inbuf,smb_vwv7) == 0) {
+                       if (cli->use_oplocks) cli_process_oplock(cli);
+                       /* try to prevent loops */
+                       CVAL(cli->inbuf,smb_com) = 0xFF;
+                       goto again;
                }
-               return p;
-       }
-}
-
-/****************************************************************************
-copy a string (unicode or otherwise) into an SMB buffer.  skips a string
-plus points to next
-****************************************************************************/
-static const char *cli_get_string(struct cli_state *cli, char *p,
-                               char *str, size_t str_len)
-{
-       uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
-       if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
-       {
-               return unibuf_to_ascii(str, p, str_len);
        }
-       else
-       {
-               safe_strcpy(str, p, str_len-1);
-               return skip_string(p, 1);
-       }
-}
 
-/****************************************************************************
-recv an smb
-****************************************************************************/
-static BOOL cli_receive_smb(struct cli_state *cli)
-{
-       return client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+       return ret;
 }
 
 /****************************************************************************
   send an smb to a fd and re-establish if necessary
 ****************************************************************************/
-static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
+static BOOL cli_send_smb(struct cli_state *cli)
 {
        size_t len;
        size_t nwritten=0;
@@ -111,26 +78,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
 
        len = smb_len(cli->outbuf) + 4;
 
-       if (show)
-       {
-               uint8 msg_type = CVAL(cli->outbuf, 0);
-               if (msg_type == 0)
-               {
-                       show_msg(cli->outbuf);
-               }
-               else
-               {
-                       dump_data(10, cli->outbuf, len);
-               }
-       }
-
        while (nwritten < len) {
                ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
-               if (ret <= 0 && errno == EPIPE && !reestablished)
-               {
-                       DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n",
-                                 strerror(errno)));
-       
+               if (ret <= 0 && errno == EPIPE && !reestablished) {
                        if (cli_reestablish_connection(cli)) {
                                reestablished = True;
                                nwritten=0;
@@ -139,8 +89,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
                }
                if (ret <= 0) {
                        DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",
-                                len,ret));
-                       return False;
+                                (int)len,(int)ret));
+                       close_sockets();
+                       exit(1);
                }
                nwritten += ret;
        }
@@ -148,26 +99,62 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
        return True;
 }
 
-/******************************************************
- Return an error message - either an SMB error or a RAP
- error.
-*******************************************************/
-    
-char *cli_errstr(struct cli_state *cli)
-{   
-       static fstring error_message;
-       cli_safe_errstr(cli, error_message, sizeof(error_message));
-       return error_message;
+/****************************************************************************
+setup basics in a outgoing packet
+****************************************************************************/
+static void cli_setup_packet(struct cli_state *cli)
+{
+        cli->rap_error = 0;
+        cli->nt_error = 0;
+       SSVAL(cli->outbuf,smb_pid,cli->pid);
+       SSVAL(cli->outbuf,smb_uid,cli->vuid);
+       SSVAL(cli->outbuf,smb_mid,cli->mid);
+       if (cli->protocol > PROTOCOL_CORE) {
+               SCVAL(cli->outbuf,smb_flg,0x8);
+               SSVAL(cli->outbuf,smb_flg2,0x1);
+       }
 }
 
+
+
 /****************************************************************************
-  return a description of an SMB error
+process an oplock break request from the server
 ****************************************************************************/
-void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len)
+static void cli_process_oplock(struct cli_state *cli)
 {
-       smb_safe_errstr(cli->inbuf, msg, len);
+       char *oldbuf = cli->outbuf;
+       pstring buf;
+       int fnum;
+
+       fnum = SVAL(cli->inbuf,smb_vwv2);
+
+       /* damn, we really need to keep a record of open files so we
+          can detect a oplock break and a close crossing on the
+          wire. for now this swallows the errors */
+       if (fnum == 0) return;
+
+       cli->outbuf = buf;
+
+        memset(buf,'\0',smb_size);
+        set_message(buf,8,0,True);
+
+        CVAL(buf,smb_com) = SMBlockingX;
+       SSVAL(buf,smb_tid, cli->cnum);
+        cli_setup_packet(cli);
+       SSVAL(buf,smb_vwv0,0xFF);
+       SSVAL(buf,smb_vwv1,0);
+       SSVAL(buf,smb_vwv2,fnum);
+       SSVAL(buf,smb_vwv3,2); /* oplock break ack */
+       SIVAL(buf,smb_vwv4,0); /* timoeut */
+       SSVAL(buf,smb_vwv6,0); /* unlockcount */
+       SSVAL(buf,smb_vwv7,0); /* lockcount */
+
+        cli_send_smb(cli);     
+
+       cli->outbuf = oldbuf;
 }
 
+
 /*****************************************************
  RAP error codes - a small start but will be extended.
 *******************************************************/
@@ -186,36 +173,36 @@ struct
   {2244, "This password cannot be used now (password history conflict)." },
   {2245, "The password is shorter than required." },
   {2246, "The password of this user is too recent to change."},
+
+  /* these really shouldn't be here ... */
+  {0x80, "Not listening on called name"},
+  {0x81, "Not listening for calling name"},
+  {0x82, "Called name not present"},
+  {0x83, "Called name present, but insufficient resources"},
+
   {0, NULL}
 };  
 
 /****************************************************************************
-  return a description of a RAP error
+  return a description of an SMB error
 ****************************************************************************/
-BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen)
+static char *cli_smb_errstr(struct cli_state *cli)
 {
-       int i;
-
-       slprintf(err_msg, msglen - 1, "RAP code %d", rap_error);
-
-       for (i = 0; rap_errmap[i].message != NULL; i++)
-       {
-               if (rap_errmap[i].err == rap_error)
-               {
-                       safe_strcpy( err_msg, rap_errmap[i].message, msglen);
-                       return True;
-               }
-       } 
-       return False;
+       return smb_errstr(cli->inbuf);
 }
 
-/****************************************************************************
-  return a description of an SMB error
-****************************************************************************/
-void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen)
+/******************************************************
+ Return an error message - either an SMB error or a RAP
+ error.
+*******************************************************/
+    
+char *cli_errstr(struct cli_state *cli)
 {   
+       static fstring error_message;
        uint8 errclass;
        uint32 errnum;
+       uint32 nt_rpc_error;
+       int i;      
 
        /*  
         * Errors are of three kinds - smb errors,
@@ -224,54 +211,50 @@ void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen)
         * errors, whose error code is in cli.rap_error.
         */ 
 
-       cli_error(cli, &errclass, &errnum);
+       cli_error(cli, &errclass, &errnum, &nt_rpc_error);
 
        if (errclass != 0)
        {
-               cli_safe_smb_errstr(cli, err_msg, msglen);
+               return cli_smb_errstr(cli);
        }
-       else if (cli->nt_error)
-       {
-               /*
-                * Was it an NT error ?
-                */
 
-               (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen);
-       }
-       else
+       /*
+        * Was it an NT error ?
+        */
+
+       if (nt_rpc_error)
        {
-               /*
-                * Must have been a rap error.
-                */
-               (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen);
+               char *nt_msg = get_nt_error_msg(nt_rpc_error);
+
+               if (nt_msg == NULL)
+               {
+                       slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error);
+               }
+               else
+               {
+                       fstrcpy(error_message, nt_msg);
+               }
+
+               return error_message;
        }
-}
-/****************************************************************************
-setup basics in a outgoing packet
-****************************************************************************/
-static void cli_setup_packet(struct cli_state *cli)
-{
-       uint16 flgs2 = 0;
-       flgs2 |= FLAGS2_LONG_PATH_COMPONENTS;
-       flgs2 |= FLAGS2_32_BIT_ERROR_CODES;
-       flgs2 |= FLAGS2_EXT_SEC;
-#if 0
-       flgs2 |= FLAGS2_UNICODE_STRINGS;
-#endif
 
-        cli->rap_error = 0;
-        cli->nt_error = 0;
-       SSVAL(cli->outbuf,smb_pid,cli->pid);
-       SSVAL(cli->outbuf,smb_uid,cli->vuid);
-       SSVAL(cli->outbuf,smb_mid,cli->mid);
+       /*
+        * Must have been a rap error.
+        */
 
-       if (cli->protocol > PROTOCOL_CORE)
+       slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error);
+
+       for (i = 0; rap_errmap[i].message != NULL; i++)
        {
-               SCVAL(cli->outbuf,smb_flg,0x8);
-               SSVAL(cli->outbuf,smb_flg2,flgs2);
-       }
-}
+               if (rap_errmap[i].err == cli->rap_error)
+               {
+                       fstrcpy( error_message, rap_errmap[i].message);
+                       break;
+               }
+       } 
 
+       return error_message;
+}
 
 /*****************************************************************************
  Convert a character pointer in a cli_call_api() response to a form we can use.
@@ -299,7 +282,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter,
 /****************************************************************************
   send a SMB trans or trans2 request
   ****************************************************************************/
-BOOL cli_send_trans(struct cli_state *cli, int trans, 
+static BOOL cli_send_trans(struct cli_state *cli, int trans, 
                            char *name, int pipe_name_len, 
                            int fid, int flags,
                            uint16 *setup, int lsetup, int msetup,
@@ -315,7 +298,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
        this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
        this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
 
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,14+lsetup,0,True);
        CVAL(cli->outbuf,smb_com) = trans;
        SSVAL(cli->outbuf,smb_tid, cli->cnum);
@@ -353,7 +336,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
        set_message(cli->outbuf,14+lsetup,              /* wcnt, bcc */
                    PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
 
-       cli_send_smb(cli, True);
+       show_msg(cli->outbuf);
+       cli_send_smb(cli);
 
        if (this_ldata < ldata || this_lparam < lparam) {
                /* receive interim response */
@@ -387,13 +371,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
                        if (trans==SMBtrans2)
                                SSVALS(cli->outbuf,smb_sfid,fid);               /* fid */
                        if (this_lparam)                        /* param[] */
-                               memcpy(outparam,param,this_lparam);
+                               memcpy(outparam,param+tot_param,this_lparam);
                        if (this_ldata)                 /* data[] */
-                               memcpy(outdata,data,this_ldata);
+                               memcpy(outdata,data+tot_data,this_ldata);
                        set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
                                    PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
                        
-                       cli_send_smb(cli, True);
+                       show_msg(cli->outbuf);
+                       cli_send_smb(cli);
                        
                        tot_data += this_ldata;
                        tot_param += this_lparam;
@@ -414,12 +399,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
        int total_data=0;
        int total_param=0;
        int this_data,this_param;
-       
+       uint8 eclass;
+       uint32 ecode;
+
        *data_len = *param_len = 0;
 
        if (!cli_receive_smb(cli))
                return False;
 
+       show_msg(cli->inbuf);
+       
        /* sanity check */
        if (CVAL(cli->inbuf,smb_com) != trans) {
                DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -428,9 +417,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
                return(False);
        }
 
-       if (cli_error(cli, NULL, NULL))
+       /*
+        * An NT RPC pipe call can return ERRDOS, ERRmoredata
+        * to a trans call. This is not an error and should not
+        * be treated as such.
+        */
+
+       if (cli_error(cli, &eclass, &ecode, NULL))
        {
-               return(False);
+        if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+                       return(False);
        }
 
        /* parse out the lengths */
@@ -472,6 +468,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
                if (!cli_receive_smb(cli))
                        return False;
 
+               show_msg(cli->inbuf);
+               
                /* sanity check */
                if (CVAL(cli->inbuf,smb_com) != trans) {
                        DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -479,10 +477,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
                                 CVAL(cli->inbuf,smb_com)));
                        return(False);
                }
-
-               if (cli_error(cli, NULL, NULL))
+               if (cli_error(cli, &eclass, &ecode, NULL))
                {
-                       return(False);
+               if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+                               return(False);
                }
        }
        
@@ -642,6 +640,8 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c
                      int type = SVAL(p,14);
                      int comment_offset = IVAL(p,16) & 0xFFFF;
                      char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
+                         dos_to_unix(sname,True);
+                         dos_to_unix(cmnt,True);
                      fn(sname, type, cmnt);
              }
       } else {
@@ -719,6 +719,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
 
                                stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
 
+                               dos_to_unix(sname, True);
+                               dos_to_unix(cmnt, True);
                                fn(sname, stype, cmnt);
                        }
                }
@@ -754,41 +756,76 @@ prots[] =
 
 
 /****************************************************************************
-send a session setup 
+ Send a session setup. The username is in UNIX character format and must be
+ converted to DOS codepage format before sending. If the password is in
+ plaintext, the same should be done.
 ****************************************************************************/
-BOOL cli_session_setup_x(struct cli_state *cli, 
-                               char *user, 
-                               char *pass, int passlen,
-                               char *ntpass, int ntpasslen,
-                               char *user_domain)
+
+BOOL cli_session_setup(struct cli_state *cli, 
+                      char *user, 
+                      char *pass, int passlen,
+                      char *ntpass, int ntpasslen,
+                      char *workgroup)
 {
-       uint8 eclass;
-       uint32 ecode;
        char *p;
-       BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY;
+       fstring pword, ntpword;
 
-       if (cli->reuse)
-       {
-               DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n"));
+       if (cli->protocol < PROTOCOL_LANMAN1)
                return True;
-       }
 
-       DEBUG(100,("cli_session_setup.  extended security: %s\n",
-                   BOOLSTR(esec)));
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("cli_session_setup.  pass, ntpass\n"));
-       dump_data(100, pass, passlen);
-       dump_data(100, ntpass, ntpasslen);
-#endif
+       if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+               return False;
+       }
 
-       if (cli->protocol < PROTOCOL_LANMAN1)
-       {
-               return True;
+       if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) {
+               /* Null session connect. */
+               pword[0] = '\0';
+               ntpword[0] = '\0';
+       } else {
+               if ((cli->sec_mode & 2) && passlen != 24) {
+                       /*
+                        * Encrypted mode needed, and non encrypted password supplied.
+                        */
+                       passlen = 24;
+                       ntpasslen = 24;
+                       fstrcpy(pword, pass);
+                       unix_to_dos(pword,True);
+                       fstrcpy(ntpword, ntpass);;
+                       unix_to_dos(ntpword,True);
+                       SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword);
+                       SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword);
+               } else if ((cli->sec_mode & 2) && passlen == 24) {
+                       /*
+                        * Encrypted mode needed, and encrypted password supplied.
+                        */
+                       memcpy(pword, pass, passlen);
+                       if(ntpasslen == 24) {
+                               memcpy(ntpword, ntpass, ntpasslen);
+                       } else {
+                               fstrcpy(ntpword, "");
+                               ntpasslen = 0;
+                       }
+               } else {
+                       /*
+                        * Plaintext mode needed, assume plaintext supplied.
+                        */
+                       fstrcpy(pword, pass);
+                       unix_to_dos(pword,True);
+                       fstrcpy(ntpword, "");
+                       ntpasslen = 0;
+               }
        }
 
+       /* if in share level security then don't send a password now */
+       if (!(cli->sec_mode & 1)) {
+               fstrcpy(pword, "");
+               passlen=1;
+               fstrcpy(ntpword, "");
+               ntpasslen=1;
+       } 
+
        /* send a session setup command */
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
 
        if (cli->protocol < PROTOCOL_NT1)
        {
@@ -803,36 +840,13 @@ BOOL cli_session_setup_x(struct cli_state *cli,
                SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
                SSVAL(cli->outbuf,smb_vwv7,passlen);
                p = smb_buf(cli->outbuf);
-               memcpy(p,pass,passlen);
+               memcpy(p,pword,passlen);
                p += passlen;
                pstrcpy(p,user);
+               unix_to_dos(p,True);
                strupper(p);
        }
-       else if (esec)
-       {
-               set_message(cli->outbuf,12,0,True);
-               CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
-               cli_setup_packet(cli);
-               
-               CVAL(cli->outbuf,smb_vwv0) = 0xFF;
-               SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
-               SSVAL(cli->outbuf,smb_vwv3,2);
-               SSVAL(cli->outbuf,smb_vwv4,cli->pid);
-               SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
-               SSVAL(cli->outbuf,smb_vwv7,passlen);
-               SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE);
-               p = smb_buf(cli->outbuf);
-               memcpy(p,pass,passlen); 
-               p += passlen;
-
-               p = cli_put_string(cli, p, "Unix", False);
-               p = cli_put_string(cli, p, "Samba", False);
-               p = cli_put_string(cli, p, "", False);
-               p++;
-               
-               set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
-       }
-       else 
+       else
        {
                set_message(cli->outbuf,13,0,True);
                CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
@@ -845,228 +859,76 @@ BOOL cli_session_setup_x(struct cli_state *cli,
                SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
                SSVAL(cli->outbuf,smb_vwv7,passlen);
                SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
-               SIVAL(cli->outbuf,smb_vwv11, 0);
+               SSVAL(cli->outbuf,smb_vwv11,0);
                p = smb_buf(cli->outbuf);
-               memcpy(p,pass,passlen); 
+               memcpy(p,pword,passlen); 
                p += SVAL(cli->outbuf,smb_vwv7);
-               memcpy(p,ntpass,ntpasslen); 
+               memcpy(p,ntpword,ntpasslen); 
                p += SVAL(cli->outbuf,smb_vwv8);
-               strupper(user);
-               p = cli_put_string(cli, p, user, False);
-               strupper(user_domain);
-               p = cli_put_string(cli, p, user_domain, False);
-               p = cli_put_string(cli, p, "Unix", True);
-               p = cli_put_string(cli, p, "Samba", False);
-               
+               pstrcpy(p,user);
+               unix_to_dos(p,True);
+               strupper(p);
+               p = skip_string(p,1);
+               pstrcpy(p,workgroup);
+               strupper(p);
+               p = skip_string(p,1);
+               pstrcpy(p,"Unix");p = skip_string(p,1);
+               pstrcpy(p,"Samba");p = skip_string(p,1);
                set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
        }
 
-       cli_send_smb(cli, True);
-       if (!cli_receive_smb(cli))
-       {
-               DEBUG(10,("cli_session_setup_x: receive smb failed\n"));
+      cli_send_smb(cli);
+      if (!cli_receive_smb(cli))
              return False;
-       }
-
-       if (cli_error(cli, &eclass, &ecode))
-       {
-               uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
-               if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES))
-               {
-                       if (ecode != ERRmoredata || !esec)
-                       {
-                               return False;
-                       }
-               }
-               else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */
-               {
-                       return False;
-               }
-       }
 
-       /* use the returned vuid from now on */
-       cli->vuid = SVAL(cli->inbuf,smb_uid);
-
-       if (cli->protocol >= PROTOCOL_NT1)
-       {
-               if (esec)
-               {
-               }
-               else
-               {
-                       /*
-                        * Save off some of the connected server
-                        * info.
-                        */
-                       char *server_domain;
-                       char *server_os;
-                       char *server_type;
+      show_msg(cli->inbuf);
 
-                       server_os = smb_buf(cli->inbuf);
-                       server_type = skip_string(server_os,1);
-                       server_domain = skip_string(server_type,1);
+      if (CVAL(cli->inbuf,smb_rcls) != 0) {
+             return False;
+      }
 
-                       fstrcpy(cli->server_os, server_os);
-                       fstrcpy(cli->server_type, server_type);
-                       fstrcpy(cli->server_domain, server_domain);
-               }
+      /* use the returned vuid from now on */
+      cli->vuid = SVAL(cli->inbuf,smb_uid);
+
+      if (cli->protocol >= PROTOCOL_NT1) {
+        /*
+         * Save off some of the connected server
+         * info.
+         */
+        char *server_domain,*server_os,*server_type;
+        server_os = smb_buf(cli->inbuf);
+        server_type = skip_string(server_os,1);
+        server_domain = skip_string(server_type,1);
+        fstrcpy(cli->server_os, server_os);
+               dos_to_unix(cli->server_os, True);
+        fstrcpy(cli->server_type, server_type);
+               dos_to_unix(cli->server_type, True);
+        fstrcpy(cli->server_domain, server_domain);
+               dos_to_unix(cli->server_domain, True);
       }
 
+      fstrcpy(cli->user_name, user);
+      dos_to_unix(cli->user_name, True);
+
       return True;
 }
 
-static BOOL cli_calc_session_pwds(struct cli_state *cli,
-                               char *myhostname,
-                               char *pword, char *ntpword,
-                               char *pass, int *passlen,
-                               char *ntpass, int *ntpasslen,
-                               char *sess_key,
-                               BOOL ntlmv2)
+/****************************************************************************
+ Send a uloggoff.
+*****************************************************************************/
+
+BOOL cli_ulogoff(struct cli_state *cli)
 {
-       BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL;
+        memset(cli->outbuf,'\0',smb_size);
+        set_message(cli->outbuf,2,0,True);
+        CVAL(cli->outbuf,smb_com) = SMBulogoffX;
+        cli_setup_packet(cli);
+       SSVAL(cli->outbuf,smb_vwv0,0xFF);
+       SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
 
-       if (pass == NULL || passlen == NULL)
-       {
-               DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n"));
-               return False;
-       }
-       if ((ntpass != NULL || ntpasslen != NULL) &&
-           (ntpass == NULL || ntpasslen == NULL))
-       {
-               DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n"));
-               return False;
-       }
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("cli_calc_session_pwds.  pass, ntpass\n"));
-       dump_data(100, pass, *passlen);
-       if (ntpass_ok)
-       {
-               dump_data(100, ntpass, *ntpasslen);
-       }
-#endif
-       if (!IS_BITS_SET_ALL(cli->sec_mode, 1))
-       {
-               /* if in share level security then don't send a password now */
-               pword[0] = '\0';
-               *passlen=1;
-               if (ntpass_ok)
-               {
-                       ntpword[0] = '\0';
-                       *ntpasslen=1;
-               }
-               return True;
-       } 
-       else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0'))
-       {
-               /* Null session connect. */
-               pword  [0] = '\0';
-               if (ntpass_ok)
-               {
-                       ntpword[0] = '\0';
-                       *ntpasslen=0;
-               }
-
-               return True;
-       }
-
-       if (!ntpass_ok)
-       {
-               return False;
-       }
-
-       if (*passlen == 24 && *ntpasslen >= 24)
-       {
-               if (IS_BITS_SET_ALL(cli->sec_mode, 2))
-               {
-                       /* encrypted password, implicit from 24-byte lengths */
-                       memcpy(pword  , pass  , *passlen);
-                       memcpy(ntpword, ntpass, *ntpasslen);
-               }
-               else
-               {
-                       DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n"));
-                       return False;
-               }
-       }
-       else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2))
-       {
-               /* plain-text password: server doesn't support encrypted. */
-               fstrcpy(pword, pass);
-               fstrcpy(ntpword, "");
-               *ntpasslen = 0;
-       }
-       else if (ntpasslen != NULL)
-       {
-               if (cli->use_ntlmv2 != False)
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv2\n"));
-                       pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
-                                  cli->usr.user_name, myhostname,
-                                  cli->usr.domain);
-               }
-               else
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv1\n"));
-                       pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
-               }
-
-               pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass,
-                                 ntpasslen, sess_key);
-
-               *passlen = 24; 
-       }
-       return True;
-}
-
-/****************************************************************************
-send a session setup 
-****************************************************************************/
-BOOL cli_session_setup(struct cli_state *cli, 
-                               char *myhostname, char *user,
-                               char *pass, int passlen,
-                               char *ntpass, int ntpasslen,
-                               char *user_domain)
-{
-       fstring pword, ntpword;
-
-       if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1)
-       {
-               return False;
-       }
-
-       fstrcpy(cli->usr.user_name, user);
-
-       return cli_calc_session_pwds(cli, myhostname, pword, ntpword,
-                               pass, &passlen,
-                               ntpass, &ntpasslen, cli->sess_key,
-                               cli->use_ntlmv2) &&
-              cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen,
-                               user_domain);
-}
-
-/****************************************************************************
- Send a uloggoff.
-*****************************************************************************/
-
-BOOL cli_ulogoff(struct cli_state *cli)
-{
-       if (cli->reuse)
-       {
-               DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n"));
-               return True;
-       }
-
-        bzero(cli->outbuf,smb_size);
-        set_message(cli->outbuf,2,0,True);
-        CVAL(cli->outbuf,smb_com) = SMBulogoffX;
-        cli_setup_packet(cli);
-       SSVAL(cli->outbuf,smb_vwv0,0xFF);
-       SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
-
-        cli_send_smb(cli, True);
-        if (!cli_receive_smb(cli))
-                return False;
+        cli_send_smb(cli);
+        if (!cli_receive_smb(cli))
+                return False;
 
         return CVAL(cli->inbuf,smb_rcls) == 0;
 }
@@ -1077,10 +939,10 @@ send a tconX
 BOOL cli_send_tconX(struct cli_state *cli, 
                    char *share, char *dev, char *pass, int passlen)
 {
-       fstring fullshare, pword;
+       fstring fullshare, pword, dos_pword;
        char *p;
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        fstrcpy(cli->share, share);
 
@@ -1091,17 +953,32 @@ BOOL cli_send_tconX(struct cli_state *cli,
        }
 
        if ((cli->sec_mode & 2) && *pass && passlen != 24) {
+               /*
+                * Non-encrypted passwords - convert to DOS codepage before encryption.
+                */
                passlen = 24;
-               SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword);
+               fstrcpy(dos_pword,pass);
+               unix_to_dos(dos_pword,True);
+               SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword);
        } else {
-               memcpy(pword, pass, passlen);
+               if(!(cli->sec_mode & 2)) {
+                       /*
+                        * Non-encrypted passwords - convert to DOS codepage before using.
+                        */
+                       fstrcpy(pword,pass);
+                       unix_to_dos(pword,True);
+               } else {
+                       memcpy(pword, pass, passlen);
+               }
        }
 
        slprintf(fullshare, sizeof(fullshare)-1,
                 "\\\\%s\\%s", cli->desthost, share);
+       unix_to_dos(fullshare, True);
        strupper(fullshare);
 
-       set_message(cli->outbuf,4, 0, True);
+       set_message(cli->outbuf,4,
+                   2 + strlen(fullshare) + passlen + strlen(dev),True);
        CVAL(cli->outbuf,smb_com) = SMBtconX;
        cli_setup_packet(cli);
 
@@ -1111,15 +988,14 @@ BOOL cli_send_tconX(struct cli_state *cli,
        p = smb_buf(cli->outbuf);
        memcpy(p,pword,passlen);
        p += passlen;
-       p = cli_put_string(cli, p, fullshare, False);
-       fstrcpy(p, dev);
-       p = skip_string(p, 1);
-
-       set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
+       fstrcpy(p,fullshare);
+       p = skip_string(p,1);
+       pstrcpy(p,dev);
+       unix_to_dos(p,True);
 
        SCVAL(cli->inbuf,smb_rcls, 1);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli))
                return False;
 
@@ -1129,10 +1005,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
 
        fstrcpy(cli->dev, "A:");
 
-       if (cli->protocol >= PROTOCOL_NT1)
-       {
-               cli_get_string(cli, smb_buf(cli->inbuf),
-                              cli->dev, sizeof(cli->dev));
+       if (cli->protocol >= PROTOCOL_NT1) {
+               fstrcpy(cli->dev, smb_buf(cli->inbuf));
        }
 
        if (strcasecmp(share,"IPC$")==0) {
@@ -1140,8 +1014,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
        }
 
        /* only grab the device if we have a recent protocol level */
-       if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3)
-       {
+       if (cli->protocol >= PROTOCOL_NT1 &&
+           smb_buflen(cli->inbuf) == 3) {
                /* almost certainly win95 - enable bug fixes */
                cli->win95 = True;
        }
@@ -1156,13 +1030,13 @@ send a tree disconnect
 ****************************************************************************/
 BOOL cli_tdis(struct cli_state *cli)
 {
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,0,0,True);
        CVAL(cli->outbuf,smb_com) = SMBtdis;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
        cli_setup_packet(cli);
        
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli))
                return False;
        
@@ -1176,8 +1050,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
 {
         char *p;
 
-        bzero(cli->outbuf,smb_size);
-        bzero(cli->inbuf,smb_size);
+        memset(cli->outbuf,'\0',smb_size);
+        memset(cli->inbuf,'\0',smb_size);
 
         set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True);
 
@@ -1190,11 +1064,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
         p = smb_buf(cli->outbuf);
         *p++ = 4;
         pstrcpy(p,fname_src);
+        unix_to_dos(p,True);
         p = skip_string(p,1);
         *p++ = 4;
         pstrcpy(p,fname_dst);
+        unix_to_dos(p,True);
 
-        cli_send_smb(cli, True);
+        cli_send_smb(cli);
         if (!cli_receive_smb(cli)) {
                 return False;
         }
@@ -1213,8 +1089,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,1, 2 + strlen(fname),True);
 
@@ -1227,8 +1103,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
        p = smb_buf(cli->outbuf);
        *p++ = 4;      
        pstrcpy(p,fname);
+    unix_to_dos(p,True);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1247,8 +1124,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,0, 2 + strlen(dname),True);
 
@@ -1259,8 +1136,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
        p = smb_buf(cli->outbuf);
        *p++ = 4;      
        pstrcpy(p,dname);
+    unix_to_dos(p,True);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1279,8 +1157,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,0, 2 + strlen(dname),True);
 
@@ -1291,8 +1169,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
        p = smb_buf(cli->outbuf);
        *p++ = 4;      
        pstrcpy(p,dname);
+    unix_to_dos(p,True);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1309,12 +1188,12 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
 /****************************************************************************
 open a file
 ****************************************************************************/
-int cli_nt_create(struct cli_state *cli, const char *fname)
+int cli_nt_create(struct cli_state *cli, char *fname)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,24,1 + strlen(fname),True);
 
@@ -1335,9 +1214,10 @@ int cli_nt_create(struct cli_state *cli, const char *fname)
 
        p = smb_buf(cli->outbuf);
        pstrcpy(p,fname);
+    unix_to_dos(p,True);
        p = skip_string(p,1);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return -1;
        }
@@ -1353,8 +1233,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname)
 /****************************************************************************
 open a file
 ****************************************************************************/
-int cli_open(struct cli_state *cli, const char *fname,
-                               int flags, int share_mode)
+int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
 {
        char *p;
        unsigned openfn=0;
@@ -1389,8 +1268,8 @@ int cli_open(struct cli_state *cli, const char *fname,
        }
 #endif /* O_SYNC */
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,15,1 + strlen(fname),True);
 
@@ -1404,13 +1283,21 @@ int cli_open(struct cli_state *cli, const char *fname,
        SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
        SSVAL(cli->outbuf,smb_vwv5,0);
        SSVAL(cli->outbuf,smb_vwv8,openfn);
+
+       if (cli->use_oplocks) {
+               /* if using oplocks then ask for a batch oplock via
+                   core and extended methods */
+               CVAL(cli->outbuf,smb_flg) |= 
+                       FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
+               SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
+       }
   
        p = smb_buf(cli->outbuf);
-       p = cli_put_string(cli, p, fname, False);
-
-       set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
+       pstrcpy(p,fname);
+    unix_to_dos(p,True);
+       p = skip_string(p,1);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return -1;
        }
@@ -1430,8 +1317,8 @@ int cli_open(struct cli_state *cli, const char *fname,
 ****************************************************************************/
 BOOL cli_close(struct cli_state *cli, int fnum)
 {
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,3,0,True);
 
@@ -1442,7 +1329,7 @@ BOOL cli_close(struct cli_state *cli, int fnum)
        SSVAL(cli->outbuf,smb_vwv0,fnum);
        SIVALS(cli->outbuf,smb_vwv1,-1);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1463,8 +1350,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
        char *p;
         int saved_timeout = cli->timeout;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0', smb_size);
 
        set_message(cli->outbuf,8,10,True);
 
@@ -1483,7 +1370,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
        SSVAL(p, 0, cli->pid);
        SIVAL(p, 2, offset);
        SIVAL(p, 6, len);
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
 
         cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
 
@@ -1508,8 +1395,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,8,10,True);
 
@@ -1529,7 +1416,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int
        SIVAL(p, 2, offset);
        SIVAL(p, 6, len);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1549,8 +1436,8 @@ issue a single SMBread and don't wait for a reply
 static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, 
                           size_t size, int i)
 {
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,10,0,True);
                
@@ -1565,7 +1452,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
        SSVAL(cli->outbuf,smb_vwv6,size);
        SSVAL(cli->outbuf,smb_mid,cli->mid + i);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
 }
 
 /****************************************************************************
@@ -1577,15 +1464,24 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
        int total = -1;
        int issued=0;
        int received=0;
-       int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT);
+/*
+ * There is a problem in this code when mpx is more than one.
+ * for some reason files can get corrupted when being read.
+ * Until we understand this fully I am serializing reads (one
+ * read/one reply) for now. JRA.
+ */
+#if 0
+       int mpx = MAX(cli->max_mux-1, 1); 
+#else
+       int mpx = 1;
+#endif
        int block = (cli->max_xmit - (smb_size+32)) & ~1023;
        int mid;
        int blocks = (size + (block-1)) / block;
 
        if (size == 0) return 0;
 
-       while (received < blocks)
-       {
+       while (received < blocks) {
                int size2;
 
                while (issued - received < mpx && issued < blocks) {
@@ -1602,8 +1498,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
                mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
                size2 = SVAL(cli->inbuf, smb_vwv5);
 
-               if (cli_error(cli, NULL, NULL))
-               {
+               if (CVAL(cli->inbuf,smb_rcls) != 0) {
                        blocks = MIN(blocks, mid-1);
                        continue;
                }
@@ -1647,8 +1542,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,12,size,True);
        
@@ -1673,7 +1568,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
 
        SSVAL(cli->outbuf,smb_mid,cli->mid + i);
        
-       cli_send_smb(cli, True);
+       show_msg(cli->outbuf);
+       cli_send_smb(cli);
 }
 
 /****************************************************************************
@@ -1687,58 +1583,98 @@ ssize_t cli_write(struct cli_state *cli,
                  int fnum, uint16 write_mode,
                  char *buf, off_t offset, size_t size)
 {
-       int total = -1;
-       int issued=0;
-       int received=0;
+       int bwritten = 0;
+       int issued = 0;
+       int received = 0;
        int mpx = MAX(cli->max_mux-1, 1);
        int block = (cli->max_xmit - (smb_size+32)) & ~1023;
-       int mid;
        int blocks = (size + (block-1)) / block;
 
-       if (size == 0) return 0;
-
        while (received < blocks) {
-               int size2;
 
-               while (issued - received < mpx && issued < blocks) {
-                       int size1 = MIN(block, size-issued*block);
-                       cli_issue_write(cli, fnum, offset+issued*block,
+               while ((issued - received < mpx) && (issued < blocks))
+               {
+                       int bsent = issued * block;
+                       int size1 = MIN(block, size - bsent);
+
+                       cli_issue_write(cli, fnum, offset + bsent,
                                        write_mode,
-                                       buf + issued*block,
+                                       buf + bsent,
                                        size1, issued);
                        issued++;
                }
 
-               if (!cli_receive_smb(cli)) {
-                       return total;
+               if (!cli_receive_smb(cli))
+               {
+                       return bwritten;
                }
 
                received++;
-               mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
-               size2 = SVAL(cli->inbuf, smb_vwv2);
-
-               if (CVAL(cli->inbuf,smb_rcls) != 0) {
-                       blocks = MIN(blocks, mid-1);
-                       continue;
-               }
 
-               if (size2 <= 0) {
-                       blocks = MIN(blocks, mid-1);
-                       /* this distinguishes EOF from an error */
-                       total = MAX(total, 0);
-                       continue;
+               if (CVAL(cli->inbuf,smb_rcls) != 0)
+               {
+                       break;
                }
 
-               total += size2;
-
-               total = MAX(total, mid*block + size2);
+               bwritten += SVAL(cli->inbuf, smb_vwv2);
        }
 
-       while (received < issued) {
-               cli_receive_smb(cli);
+       while (received < issued && cli_receive_smb(cli))
+       {
                received++;
        }
        
+       return bwritten;
+}
+
+
+/****************************************************************************
+  write to a file using a SMBwrite and not bypassing 0 byte writes
+****************************************************************************/
+ssize_t cli_smbwrite(struct cli_state *cli,
+                    int fnum, char *buf, off_t offset, size_t size1)
+{
+       char *p;
+       ssize_t total = 0;
+
+       do {
+               size_t size = MIN(size1, cli->max_xmit - 48);
+               
+               memset(cli->outbuf,'\0',smb_size);
+               memset(cli->inbuf,'\0',smb_size);
+
+               set_message(cli->outbuf,5, 3 + size,True);
+
+               CVAL(cli->outbuf,smb_com) = SMBwrite;
+               SSVAL(cli->outbuf,smb_tid,cli->cnum);
+               cli_setup_packet(cli);
+               
+               SSVAL(cli->outbuf,smb_vwv0,fnum);
+               SSVAL(cli->outbuf,smb_vwv1,size);
+               SIVAL(cli->outbuf,smb_vwv2,offset);
+               SSVAL(cli->outbuf,smb_vwv4,0);
+               
+               p = smb_buf(cli->outbuf);
+               *p++ = 1;
+               SSVAL(p, 0, size);
+               memcpy(p+2, buf, size);
+               
+               cli_send_smb(cli);
+               if (!cli_receive_smb(cli)) {
+                       return -1;
+               }
+               
+               if (CVAL(cli->inbuf,smb_rcls) != 0) {
+                       return -1;
+               }
+
+               size = SVAL(cli->inbuf,smb_vwv0);
+               if (size == 0) break;
+
+               size1 -= size;
+               total += size;
+       } while (size1);
+
        return total;
 }
 
@@ -1750,10 +1686,10 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
                  uint16 *attr, size_t *size, 
                  time_t *c_time, time_t *a_time, time_t *m_time)
 {
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
-       set_message(cli->outbuf,2,0,True);
+       set_message(cli->outbuf,1,0,True);
 
        CVAL(cli->outbuf,smb_com) = SMBgetattrE;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -1761,7 +1697,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
 
        SSVAL(cli->outbuf,smb_vwv0,fd);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1802,8 +1738,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,0,strlen(fname)+2,True);
 
@@ -1814,8 +1750,9 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
        p = smb_buf(cli->outbuf);
        *p = 4;
        pstrcpy(p+1, fname);
+    unix_to_dos(p+1,True);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1848,8 +1785,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
-       bzero(cli->inbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
+       memset(cli->inbuf,'\0',smb_size);
 
        set_message(cli->outbuf,8,strlen(fname)+4,True);
 
@@ -1863,10 +1800,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
        p = smb_buf(cli->outbuf);
        *p = 4;
        pstrcpy(p+1, fname);
+    unix_to_dos(p+1,True);
        p = skip_string(p,1);
        *p = 4;
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -1899,6 +1837,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
        memset(param, 0, param_len);
        SSVAL(param, 0, SMB_INFO_STANDARD);
        pstrcpy(&param[6], fname);
+    unix_to_dos(&param[6],True);
 
        do {
                ret = (cli_send_trans(cli, SMBtrans2, 
@@ -1916,7 +1855,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
                           it gives ERRSRV/ERRerror temprarily */
                        uint8 eclass;
                        uint32 ecode;
-                       cli_error(cli, &eclass, &ecode);
+                       cli_error(cli, &eclass, &ecode, NULL);
                        if (eclass != ERRSRV || ecode != ERRerror) break;
                        msleep(100);
                }
@@ -1972,6 +1911,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
        memset(param, 0, param_len);
        SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO);
        pstrcpy(&param[6], fname);
+    unix_to_dos(&param[6],True);
 
        if (!cli_send_trans(cli, SMBtrans2, 
                             NULL, 0,                      /* name, length */
@@ -2009,7 +1949,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
                *mode = SVAL(rdata, 32);
        }
        if (size) {
-               *size = IVAL(rdata, 40);
+               *size = IVAL(rdata, 48);
        }
        if (ino) {
                *ino = IVAL(rdata, 64);
@@ -2081,7 +2021,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
                *mode = SVAL(rdata, 32);
        }
        if (size) {
-               *size = IVAL(rdata, 40);
+               *size = IVAL(rdata, 48);
        }
        if (ino) {
                *ino = IVAL(rdata, 64);
@@ -2117,6 +2057,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
                                finfo->size = IVAL(p,16);
                                finfo->mode = CVAL(p,24);
                                pstrcpy(finfo->name,p+27);
+                               dos_to_unix(finfo->name,True);
                        }
                        return(28 + CVAL(p,26));
 
@@ -2129,6 +2070,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
                                finfo->size = IVAL(p,16);
                                finfo->mode = CVAL(p,24);
                                pstrcpy(finfo->name,p+31);
+                               dos_to_unix(finfo->name,True);
                        }
                        return(32 + CVAL(p,30));
 
@@ -2142,6 +2084,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
                                finfo->size = IVAL(p,20);
                                finfo->mode = CVAL(p,28);
                                pstrcpy(finfo->name,p+33);
+                               dos_to_unix(finfo->name,True);
                        }
                        return(SVAL(p,4)+4);
                        
@@ -2154,6 +2097,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
                                finfo->size = IVAL(p,20);
                                finfo->mode = CVAL(p,28);
                                pstrcpy(finfo->name,p+37);
+                               dos_to_unix(finfo->name,True);
                        }
                        return(SVAL(p,4)+4);
                        
@@ -2189,7 +2133,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
                                p += 4; /* EA size */
                                p += 2; /* short name len? */
                                p += 24; /* short name? */        
-                               StrnCpy(finfo->name,p,namelen);
+                               StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen));
+                               dos_to_unix(finfo->name,True);
                                return(ret);
                        }
                        return(SVAL(p,0));
@@ -2217,7 +2162,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
        int dirlist_len = 0;
        int total_received = -1;
        BOOL First = True;
-       int ff_resume_key = 0;
        int ff_searchcount=0;
        int ff_eos=0;
        int ff_lastname=0;
@@ -2230,6 +2174,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
        pstring param;
        
        pstrcpy(mask,Mask);
+       unix_to_dos(mask,True);
        
        while (ff_eos == 0) {
                loop_count++;
@@ -2253,12 +2198,12 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
                        SSVAL(param,0,ff_dir_handle);
                        SSVAL(param,2,max_matches); /* max count */
                        SSVAL(param,4,info_level); 
-                       SIVAL(param,6,ff_resume_key); /* ff_resume_key */
+                       SIVAL(param,6,0); /* ff_resume_key */
                        SSVAL(param,10,8+4+2);  /* resume required + close on end + continue */
                        pstrcpy(param+12,mask);
 
-                       DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
-                                ff_dir_handle,ff_resume_key,ff_lastname,mask));
+                       DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n",
+                                ff_dir_handle,ff_lastname,mask));
                }
 
                if (!cli_send_trans(cli, SMBtrans2, 
@@ -2279,7 +2224,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
                           it gives ERRSRV/ERRerror temprarily */
                        uint8 eclass;
                        uint32 ecode;
-                       cli_error(cli, &eclass, &ecode);
+                       cli_error(cli, &eclass, &ecode, NULL);
                        if (eclass != ERRSRV || ecode != ERRerror) break;
                        msleep(100);
                        continue;
@@ -2311,19 +2256,19 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
                        switch(info_level)
                                {
                                case 260:
-                                       ff_resume_key =0;
                                        StrnCpy(mask,p+ff_lastname,
-                                               data_len-ff_lastname);
+                                               MIN(sizeof(mask)-1,data_len-ff_lastname));
                                        break;
                                case 1:
                                        pstrcpy(mask,p + ff_lastname + 1);
-                                       ff_resume_key = 0;
                                        break;
                                }
                } else {
                        pstrcpy(mask,"");
                }
-  
+               dos_to_unix(mask, True);
                /* and add them to the dirlist pool */
                dirlist = Realloc(dirlist,dirlist_len + data_len);
 
@@ -2347,8 +2292,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
                if (rdata) free(rdata); rdata = NULL;
                if (rparam) free(rparam); rparam = NULL;
                
-               DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
-                        ff_searchcount,ff_eos,ff_resume_key));
+               DEBUG(3,("received %d entries (eos=%d)\n",
+                        ff_searchcount,ff_eos));
+
+               if (ff_searchcount > 0) loop_count = 0;
 
                First = False;
        }
@@ -2383,6 +2330,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
   char *rparam = NULL;
   char *rdata = NULL;
   int rprcnt, rdrcnt;
+  pstring dos_new_password;
 
   if (strlen(user) >= sizeof(fstring)-1) {
     DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
@@ -2408,19 +2356,22 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
    */
   memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
   fstrcpy(upper_case_old_pw, old_password);
+  unix_to_dos(upper_case_old_pw,True);
   strupper(upper_case_old_pw);
   E_P16((uchar *)upper_case_old_pw, old_pw_hash);
 
-       if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False))
-       {
-               return False;
-       }
+  pstrcpy(dos_new_password, new_password);
+  unix_to_dos(dos_new_password, True);
+
+  if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False))
+    return False;
 
   /* 
    * Now place the old password hash in the data.
    */
   memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
   fstrcpy(upper_case_new_pw, new_password);
+  unix_to_dos(upper_case_new_pw,True);
   strupper(upper_case_new_pw);
 
   E_P16((uchar *)upper_case_new_pw, new_pw_hash);
@@ -2429,14 +2380,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
 
   data_len = 532;
     
-  if (!cli_send_trans(cli,SMBtrans,
+  if (cli_send_trans(cli,SMBtrans,
                     PIPE_LANMAN,strlen(PIPE_LANMAN),      /* name, length */
                     0,0,                                  /* fid, flags */
                     NULL,0,0,                             /* setup, length, max */
                     param,param_len,2,                    /* param, length, max */
                     data,data_len,0                       /* data, length, max */
-                   ))
-  {
+                   ) == False) {
     DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
               user ));
     return False;
@@ -2466,7 +2416,7 @@ BOOL cli_negprot(struct cli_state *cli)
        int numprots;
        int plength;
 
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
 
        /* setup the protocol strings */
        for (plength=0,numprots=0;
@@ -2482,6 +2432,7 @@ BOOL cli_negprot(struct cli_state *cli)
             numprots++) {
                *p++ = 2;
                pstrcpy(p,prots[numprots].name);
+               unix_to_dos(p,True);
                p += strlen(p) + 1;
        }
 
@@ -2490,11 +2441,11 @@ BOOL cli_negprot(struct cli_state *cli)
 
        CVAL(smb_buf(cli->outbuf),0) = 2;
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli))
-       {
                return False;
-       }
+
+       show_msg(cli->inbuf);
 
        if (CVAL(cli->inbuf,smb_rcls) != 0 || 
            ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
@@ -2504,56 +2455,28 @@ BOOL cli_negprot(struct cli_state *cli)
        cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
 
 
-       if (cli->protocol >= PROTOCOL_NT1)
-       {    
-               char *buf = smb_buf(cli->inbuf);
-               int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct)));
+       if (cli->protocol >= PROTOCOL_NT1) {    
                /* NT protocol */
                cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
                cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
                cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
                cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
-               cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60;
+               cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
+               cli->serverzone *= 60;
                /* this time arrives in real GMT */
                cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
-
+               memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
                cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
-               if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE))
-               {
+               if (cli->capabilities & 1) {
                        cli->readbraw_supported = True;
                        cli->writebraw_supported = True;      
                }
-
-               if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
-               {
-                       /* oops, some kerberos-related nonsense. */
-                       /* expect to have to use NTLMSSP-over-SMB */
-                       DEBUG(10,("unknown kerberos-related (?) blob\n"));
-                       memset(cli->cryptkey, 0, 8);
-                       cli->server_domain[0] = 0;
-               }
-               else
-               {
-                       memcpy(cli->cryptkey, buf,8);
-                       if (bcc > 8)
-                       {
-                               unibuf_to_ascii(cli->server_domain,  buf+8,
-                                               sizeof(cli->server_domain));
-                       }
-                       else
-                       {
-                               cli->server_domain[0] = 0;
-                       }
-                       DEBUG(5,("server's domain: %s bcc: %d\n",
-                               cli->server_domain, bcc));
-               }
-       }
-       else if (cli->protocol >= PROTOCOL_LANMAN1)
-       {
+       } else if (cli->protocol >= PROTOCOL_LANMAN1) {
                cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
                cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
                cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
-               cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
+               cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
+               cli->serverzone *= 60;
                /* this time is converted to GMT by make_unix_date */
                cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
                cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
@@ -2584,11 +2507,6 @@ BOOL cli_session_request(struct cli_state *cli,
        memcpy(&(cli->calling), calling, sizeof(*calling));
        memcpy(&(cli->called ), called , sizeof(*called ));
   
-       if (cli->port == 445)
-       {
-               return True;
-       }
-
        /* put in the destination name */
        p = cli->outbuf+len;
        name_mangle(cli->called .name, p, cli->called .name_type);
@@ -2607,12 +2525,41 @@ BOOL cli_session_request(struct cli_state *cli,
 retry:
 #endif /* WITH_SSL */
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        DEBUG(5,("Sent session request\n"));
 
        if (!cli_receive_smb(cli))
                return False;
 
+       if (CVAL(cli->inbuf,0) == 0x84) {
+               /* C. Hoch  9/14/95 Start */
+               /* For information, here is the response structure.
+                * We do the byte-twiddling to for portability.
+               struct RetargetResponse{
+               unsigned char type;
+               unsigned char flags;
+               int16 length;
+               int32 ip_addr;
+               int16 port;
+               };
+               */
+               int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+               /* SESSION RETARGET */
+               putip((char *)&cli->dest_ip,cli->inbuf+4);
+
+               close_sockets();
+               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
+               if (cli->fd == -1)
+                       return False;
+
+               DEBUG(3,("Retargeted\n"));
+
+               set_socket_options(cli->fd,user_socket_options);
+
+               /* Try again */
+               return cli_session_request(cli, calling, called);
+       } /* C. Hoch 9/14/95 End */
+
 #ifdef WITH_SSL
     if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
         if (!sslutil_fd_is_ssl(cli->fd)){
@@ -2624,7 +2571,7 @@ retry:
 
        if (CVAL(cli->inbuf,0) != 0x82) {
                 /* This is the wrong place to put the error... JRA. */
-               cli->rap_error = CVAL(cli->inbuf,0);
+               cli->rap_error = CVAL(cli->inbuf,4);
                return False;
        }
        return(True);
@@ -2637,7 +2584,6 @@ open the client sockets
 BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
 {
        extern struct in_addr ipzero;
-       int port = cli->port;
 
        fstrcpy(cli->desthost, host);
        
@@ -2650,38 +2596,19 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
                cli->dest_ip = *ip;
        }
 
-
-       if (port == 0) port = SMB_PORT2;
+        if (cli->port == 0) cli->port = 139;  /* Set to default */
 
        cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
-                                 port, cli->timeout);
+                                 cli->port, cli->timeout);
        if (cli->fd == -1)
-       {
-               if (cli->port != 0)
-               {
-                       return False;
-               }
-               port = SMB_PORT;
-
-               cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, 
-                                         port, cli->timeout);
-               if (cli->fd == -1) return False;
-       }
+               return False;
 
-       cli->port = port;
+       set_socket_options(cli->fd,user_socket_options);
 
        return True;
 }
 
 
-/****************************************************************************
-initialise a client structure
-****************************************************************************/
-void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
-{
-       copy_nt_creds(&cli->usr, usr);
-}
-
 /****************************************************************************
 initialise a client structure
 ****************************************************************************/
@@ -2707,7 +2634,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
        cli->mid = 1;
        cli->vuid = UID_FIELD_INVALID;
        cli->protocol = PROTOCOL_NT1;
-       cli->timeout = 20000;
+       cli->timeout = 20000; /* Timeout is in milliseconds. */
        cli->bufsize = CLI_BUFFER_SIZE+4;
        cli->max_xmit = cli->bufsize;
        cli->outbuf = (char *)malloc(cli->bufsize);
@@ -2717,39 +2644,19 @@ struct cli_state *cli_initialise(struct cli_state *cli)
                return False;
        }
 
-       cli->initialised = 1;
-       cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32;
-       cli->use_ntlmv2 = Auto;
+       memset(cli->outbuf, '\0', cli->bufsize);
+       memset(cli->inbuf, '\0', cli->bufsize);
 
-       cli_init_creds(cli, NULL);
+       cli->initialised = 1;
 
        return cli;
 }
 
-/****************************************************************************
-close the socket descriptor
-****************************************************************************/
-void cli_close_socket(struct cli_state *cli)
-{
-#ifdef WITH_SSL
-       if (cli->fd != -1)
-       {
-               sslutil_disconnect(cli->fd);
-       }
-#endif /* WITH_SSL */
-       if (cli->fd != -1) 
-       {
-               close(cli->fd);
-       }
-       cli->fd = -1;
-}
-
 /****************************************************************************
 shutdown a client structure
 ****************************************************************************/
 void cli_shutdown(struct cli_state *cli)
 {
-       DEBUG(10,("cli_shutdown\n"));
        if (cli->outbuf)
        {
                free(cli->outbuf);
@@ -2758,7 +2665,12 @@ void cli_shutdown(struct cli_state *cli)
        {
                free(cli->inbuf);
        }
-       cli_close_socket(cli);
+#ifdef WITH_SSL
+    if (cli->fd != -1)
+      sslutil_disconnect(cli->fd);
+#endif /* WITH_SSL */
+       if (cli->fd != -1) 
+      close(cli->fd);
        memset(cli, 0, sizeof(*cli));
 }
 
@@ -2771,43 +2683,34 @@ void cli_shutdown(struct cli_state *cli)
   for 32 bit "warnings", a return code of 0 is expected.
 
 ****************************************************************************/
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num)
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error)
 {
-       int  flgs2;
+       int  flgs2 = SVAL(cli->inbuf,smb_flg2);
        char rcls;
        int code;
 
-       if (!cli->initialised)
-       {
-               DEBUG(0,("cli_error: client state uninitialised!\n"));
-               return EINVAL;
-       }
-
-       flgs2 = SVAL(cli->inbuf,smb_flg2);
-
        if (eclass) *eclass = 0;
        if (num   ) *num = 0;
+       if (nt_rpc_error) *nt_rpc_error = cli->nt_error;
 
-       if (flgs2 & FLAGS2_32_BIT_ERROR_CODES)
-       {
+       if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
                /* 32 bit error codes detected */
                uint32 nt_err = IVAL(cli->inbuf,smb_rcls);
                if (num) *num = nt_err;
                DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err));
                if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0;
 
-               switch (nt_err & 0xFFFFFF)
-               {
-                       case NT_STATUS_ACCESS_VIOLATION     : return EACCES;
-                       case NT_STATUS_NO_SUCH_FILE         : return ENOENT;
-                       case NT_STATUS_NO_SUCH_DEVICE       : return ENODEV;
-                       case NT_STATUS_INVALID_HANDLE       : return EBADF;
-                       case NT_STATUS_NO_MEMORY            : return ENOMEM;
-                       case NT_STATUS_ACCESS_DENIED        : return EACCES;
-                       case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
-                       case NT_STATUS_SHARING_VIOLATION    : return EBUSY;
-                       case NT_STATUS_OBJECT_PATH_INVALID  : return ENOTDIR;
-                       case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
+               switch (nt_err & 0xFFFFFF) {
+               case NT_STATUS_ACCESS_VIOLATION: return EACCES;
+               case NT_STATUS_NO_SUCH_FILE: return ENOENT;
+               case NT_STATUS_NO_SUCH_DEVICE: return ENODEV;
+               case NT_STATUS_INVALID_HANDLE: return EBADF;
+               case NT_STATUS_NO_MEMORY: return ENOMEM;
+               case NT_STATUS_ACCESS_DENIED: return EACCES;
+               case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
+               case NT_STATUS_SHARING_VIOLATION: return EBUSY;
+               case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR;
+               case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
                }
 
                /* for all other cases - a default code */
@@ -2830,7 +2733,6 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num)
                case ERRrename: return EEXIST;
                case ERRbadshare: return EBUSY;
                case ERRlock: return EBUSY;
-               case ERRmoredata: return 0; /* Informational only */
                }
        }
        if (rcls == ERRSRV) {
@@ -2886,37 +2788,30 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
        /* copy the parameters necessary to re-establish the connection */
 
        if (cli->cnum != 0)
-       {
-               do_tcon = True;
-       }
-
-       if (do_tcon)
        {
                fstrcpy(share, cli->share);
                fstrcpy(dev  , cli->dev);
+               do_tcon = True;
        }
 
        memcpy(&called , &(cli->called ), sizeof(called ));
        memcpy(&calling, &(cli->calling), sizeof(calling));
-       fstrcpy(dest_host, cli->desthost);
+       fstrcpy(dest_host, cli->full_dest_host_name);
 
        DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
                 nmb_namestr(&calling), nmb_namestr(&called), 
                 inet_ntoa(cli->dest_ip),
-                cli->usr.user_name, cli->usr.domain));
+                cli->user_name, cli->domain));
 
        cli->fd = -1;
 
        if (cli_establish_connection(cli,
                                     dest_host, &cli->dest_ip,
                                     &calling, &called,
-                                    share, dev, False, do_tcon))
-       {
-               if (cli->fd != oldfd)
-               {
-                       if (dup2(cli->fd, oldfd) == oldfd)
-                       {
-                               cli_close_socket(cli);
+                                    share, dev, False, do_tcon)) {
+               if (cli->fd != oldfd) {
+                       if (dup2(cli->fd, oldfd) == oldfd) {
+                               close(cli->fd);
                        }
                }
                return True;
@@ -2924,101 +2819,18 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
        return False;
 }
 
-static BOOL cli_init_redirect(struct cli_state *cli,
-                               const char* srv_name, struct in_addr *destip,
-                               const struct ntuser_creds *usr)
-{
-       int sock;
-       fstring ip_name;
-       struct cli_state cli_redir;
-       fstring path;
-
-       uint32 len;
-       char *data;
-       char *in = cli->inbuf;
-       char *out = cli->outbuf;
-       prs_struct ps;
-       uint16 command;
-
-       slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid());
-
-       if (strequal(srv_name, "*SMBSERVER"))
-       {
-               fstrcpy(ip_name, "\\\\");
-               inet_aton(&ip_name[2], destip);
-               srv_name = ip_name;
-       }
-
-       sock = open_pipe_sock(path);
-
-       if (sock < 0)
-       {
-               return False;
-       }
-
-       command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
-
-       if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse))
-       {
-               DEBUG(0,("could not parse credentials\n"));
-               close(sock);
-               return False;
-       }
-
-       len = ps.offset;
-       data = mem_data(&ps.data, 0);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("data len: %d\n", len));
-       dump_data(100, data, len);
-#endif
-
-       SIVAL(data, 0, len);
-
-       if (write(sock, data, len) <= 0)
-       {
-               DEBUG(0,("write failed\n"));
-               close(sock);
-               return False;
-       }
-
-       len = read(sock, &cli_redir, sizeof(cli_redir));
-
-       if (len != sizeof(cli_redir))
-       {
-               DEBUG(0,("read failed\n"));
-               close(sock);
-               return False;
-       }
-       
-       memcpy(cli, &cli_redir, sizeof(cli_redir));
-       cli->inbuf = in;
-       cli->outbuf = out;
-       cli->fd = sock;
-       cli->reuse = False;
-
-       return sock;
-}
-
 /****************************************************************************
 establishes a connection right up to doing tconX, reading in a password.
 ****************************************************************************/
 BOOL cli_establish_connection(struct cli_state *cli, 
-                               const char *dest_host, struct in_addr *dest_ip,
+                               char *dest_host, struct in_addr *dest_ip,
                                struct nmb_name *calling, struct nmb_name *called,
                                char *service, char *service_type,
                                BOOL do_shutdown, BOOL do_tcon)
 {
-       fstring callingstr;
-       fstring calledstr;
-
-       nmb_safe_namestr(calling, callingstr, sizeof(callingstr));
-       nmb_safe_namestr(called , calledstr , sizeof(calledstr ));
-
-       DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n",
-                         callingstr, calledstr, inet_ntoa(*dest_ip),
-                     cli->usr.user_name, cli->usr.domain,
-                       cli->use_ntlmv2 ? "v2" : "v1"));
+       DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
+                         nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
+                     cli->user_name, cli->domain));
 
        /* establish connection */
 
@@ -3027,24 +2839,12 @@ BOOL cli_establish_connection(struct cli_state *cli,
                return False;
        }
 
-       if (cli->fd == -1 && cli->redirect)
-       {
-               if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr))
-               {
-                       DEBUG(10,("cli_establish_connection: redirected OK\n"));
-                       return True;
-               }
-               else
-               {
-                       DEBUG(10,("redirect FAILED, make direct connection\n"));
-               }
-       }
        if (cli->fd == -1)
        {
                if (!cli_connect(cli, dest_host, dest_ip))
                {
                        DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
-                                         callingstr, inet_ntoa(*dest_ip)));
+                                         nmb_namestr(calling), inet_ntoa(*dest_ip)));
                        return False;
                }
        }
@@ -3053,9 +2853,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
        {
                DEBUG(1,("failed session request\n"));
                if (do_shutdown)
-               {
-                       cli_shutdown(cli);
-               }
+          cli_shutdown(cli);
                return False;
        }
 
@@ -3063,242 +2861,33 @@ BOOL cli_establish_connection(struct cli_state *cli,
        {
                DEBUG(1,("failed negprot\n"));
                if (do_shutdown)
-               {
-                       cli_shutdown(cli);
-               }
+          cli_shutdown(cli);
                return False;
        }
 
-       if (cli->usr.domain[0] == 0)
+       if (cli->pwd.cleartext || cli->pwd.null_pwd)
        {
-               safe_strcpy(cli->usr.domain, cli->server_domain,
-                           sizeof(cli->usr.domain));
-       }
+               fstring passwd;
+               int pass_len;
 
-       if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
-       {
-               /* common to both session setups */
-               uint32 ntlmssp_flgs;
-               char pwd_buf[128];
-               int buf_len;
-               char *p;
-               char *e = pwd_buf + sizeof(pwd_buf);
-
-               /* 1st session setup */
-               char pwd_data[34] =
-               {
-                       0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
-                       0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e,
-                       0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
-                       0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22,
-                       0x04, 0x20
-               };
-               /* 2nd session setup */
-#if 0
-               char pwd_data_2[8] =
-               {
-                       0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b
-               };
-#endif
-               char pwd_data_2[8] =
-               {
-                       0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b
-               };
-               prs_struct auth_resp;
-               int resp_len;
-               char *p_gssapi;
-               char *p_oem;
-               char *p_gssapi_end;
-               uint16 gssapi_len;
-
-               memset(pwd_buf, 0, sizeof(pwd_buf));
-               memcpy(pwd_buf, pwd_data, sizeof(pwd_data));
-               p = pwd_buf + sizeof(pwd_data);
-
-               safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
-               p = skip_string(p, 1);
-               CVAL(p, 0) = 0x1;
-               p += 4;
-               ntlmssp_flgs = 
-                               NTLMSSP_NEGOTIATE_UNICODE |
-                               NTLMSSP_NEGOTIATE_OEM |
-                               NTLMSSP_NEGOTIATE_SIGN |
-                               NTLMSSP_NEGOTIATE_SEAL |
-                               NTLMSSP_NEGOTIATE_LM_KEY |
-                               NTLMSSP_NEGOTIATE_NTLM |
-                               NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
-                               NTLMSSP_NEGOTIATE_00001000 |
-                               NTLMSSP_NEGOTIATE_00002000;
-               SIVAL(p, 0, ntlmssp_flgs);
-               p += 4;
-               p += 16; /* skip some NULL space */
-               CVAL(p, 0) = 0; p++; /* alignment */
-
-               buf_len = PTR_DIFF(p, pwd_buf);
-
-               /* first session negotiation stage */
-               if (!cli_session_setup_x(cli, cli->usr.user_name,
-                              pwd_buf, buf_len,
-                              NULL, 0,
-                              cli->usr.domain))
-               {
-                       DEBUG(1,("failed session setup\n"));
-                       if (do_shutdown)
-                       {
-                               cli_shutdown(cli);
-                       }
-                       return False;
-               }
-
-               DEBUG(1,("1st session setup ok\n"));
-
-               if (*cli->server_domain || *cli->server_os || *cli->server_type)
-               {
-                       DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
-                            cli->server_domain,
-                            cli->server_os,
-                            cli->server_type));
-               }
-       
-               p = smb_buf(cli->inbuf) + 0x2f;
-               ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */
-               p += 4;
-               memcpy(cli->cryptkey, p, 8);
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n",
-                           ntlmssp_flgs));
-                          
-               DEBUG(100,("cli_session_setup_x: crypt key\n"));
-               dump_data(100, cli->cryptkey, 8);
-#endif
-               prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
-
-               if (cli->use_ntlmv2 != False)
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv2\n"));
-                       pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
-                                  cli->usr.user_name, calling->name, cli->usr.domain);
-               }
-               else
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv1\n"));
-                       pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
-               }
-
-               create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain,
-                                    cli->usr.user_name, cli->calling.name,
-                                    ntlmssp_flgs,
-                                    &auth_resp);
-               prs_link(NULL, &auth_resp, NULL);
-
-               memset(pwd_buf, 0, sizeof(pwd_buf));
-               p = pwd_buf;
-
-               CVAL(p, 0) = 0xa1; p++;
-               CVAL(p, 0) = 0x82; p++;
-               p_gssapi = p; p+= 2;
-               CVAL(p, 0) = 0x30; p++;
-               CVAL(p, 0) = 0x82; p++;
-               p += 2;
-               
-               CVAL(p, 0) = 0xa2; p++;
-               CVAL(p, 0) = 0x82; p++;
-               p_oem = p; p+= 2;
-               CVAL(p, 0) = 0x04; p++;
-               CVAL(p, 0) = 0x82; p++;
-               p += 2;
-
-               p_gssapi_end = p;
-               
-               safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
-               p = skip_string(p, 1);
-               CVAL(p, 0) = 0x3;
-               p += 4;
-
-               resp_len = mem_buf_len(auth_resp.data);
-               mem_buf_copy(p, auth_resp.data, 0, resp_len);
-               prs_mem_free(&auth_resp);
-
-               p += resp_len;
-
-               buf_len = PTR_DIFF(p, pwd_buf);
-               gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12;
-
-               *p_gssapi++ = (gssapi_len >> 8) & 0xff;
-               *p_gssapi++ = gssapi_len & 0xff;
-
-               p_gssapi += 2;
-               gssapi_len -= 4;
-
-               *p_gssapi++ = (gssapi_len >> 8) & 0xff;
-               *p_gssapi++ = gssapi_len & 0xff;
-
-               gssapi_len -= 4;
-
-               *p_oem++ = (gssapi_len >> 8) & 0xff;
-               *p_oem++ = gssapi_len & 0xff;
-
-               p_oem += 2;
-               gssapi_len -= 4;
-
-               *p_oem++ = (gssapi_len >> 8) & 0xff;
-               *p_oem++ = gssapi_len & 0xff;
-
-               /* second session negotiation stage */
-               if (!cli_session_setup_x(cli, cli->usr.user_name,
-                              pwd_buf, buf_len,
-                              NULL, 0,
-                              cli->usr.domain))
-               {
-                       DEBUG(1,("failed session setup\n"));
-                       if (do_shutdown)
-                       {
-                               cli_shutdown(cli);
-                       }
-                       return False;
-               }
-
-               DEBUG(1,("2nd session setup ok\n"));
-
-               if (do_tcon)
-               {
-                       if (!cli_send_tconX(cli, service, service_type,
-                                           NULL, 0))
-                                           
-                       {
-                               DEBUG(1,("failed tcon_X\n"));
-                               if (do_shutdown)
-                               {
-                                       cli_shutdown(cli);
-                               }
-                               return False;
-                       }
-               }
-       }
-       else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd)
-       {
-               fstring passwd, ntpasswd;
-               int pass_len = 0, ntpass_len = 0;
-
-               if (cli->usr.pwd.null_pwd)
+               if (cli->pwd.null_pwd)
                {
                        /* attempt null session */
-                       passwd[0] = ntpasswd[0] = 0;
-                       pass_len = ntpass_len = 1;
+                       passwd[0] = 0;
+                       pass_len = 1;
                }
                else
                {
                        /* attempt clear-text session */
-                       pwd_get_cleartext(&(cli->usr.pwd), passwd);
+                       pwd_get_cleartext(&(cli->pwd), passwd);
                        pass_len = strlen(passwd);
                }
 
                /* attempt clear-text session */
-               if (!cli_session_setup(cli, calling->name,
-                              cli->usr.user_name,
+               if (!cli_session_setup(cli, cli->user_name,
                               passwd, pass_len,
-                              ntpasswd, ntpass_len,
-                              cli->usr.domain))
+                              NULL, 0,
+                              cli->domain))
                {
                        DEBUG(1,("failed session setup\n"));
                        if (do_shutdown)
@@ -3324,68 +2913,25 @@ BOOL cli_establish_connection(struct cli_state *cli,
        else
        {
                /* attempt encrypted session */
+               unsigned char nt_sess_pwd[24];
                unsigned char lm_sess_pwd[24];
-               unsigned char nt_sess_pwd[128];
-               size_t nt_sess_pwd_len;
-
-               if (cli->use_ntlmv2 != False)
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv2\n"));
-                       pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
-                                  cli->usr.user_name, calling->name, cli->usr.domain);
-               }
-               else
-               {
-                       DEBUG(10,("cli_establish_connection: NTLMv1\n"));
-                       pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
-               }
 
-               pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd,
-                                 &nt_sess_pwd_len, cli->sess_key);
+               /* creates (storing a copy of) and then obtains a 24 byte password OWF */
+               pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
+               pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
 
                /* attempt encrypted session */
-               if (!cli_session_setup_x(cli, cli->usr.user_name,
-                                      (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
-                                      (char*)nt_sess_pwd, nt_sess_pwd_len,
-                                      cli->usr.domain))
+               if (!cli_session_setup(cli, cli->user_name,
+                              (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
+                              (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
+                              cli->domain))
                {
                        DEBUG(1,("failed session setup\n"));
-
-                       if (cli->use_ntlmv2 == Auto)
-                       {
-                               DEBUG(10,("NTLMv2 failed.  Using NTLMv1\n"));
-                               cli->use_ntlmv2 = False;
-                               if (do_tcon)
-                               {
-                                       fstrcpy(cli->share, service);
-                                       fstrcpy(cli->dev, service_type);
-                               }
-                               fstrcpy(cli->desthost, dest_host);
-                               cli_close_socket(cli);
-                               return cli_establish_connection(cli, 
-                                       dest_host, dest_ip,
-                                       calling, called,
-                                       service, service_type,
-                                       do_shutdown, do_tcon);
-                       }
-                       
                        if (do_shutdown)
-                       {
-                               cli_shutdown(cli);
-                       }
+              cli_shutdown(cli);
                        return False;
                }
 
-               DEBUG(1,("session setup ok\n"));
-
-               if (*cli->server_domain || *cli->server_os || *cli->server_type)
-               {
-                       DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
-                            cli->server_domain,
-                            cli->server_os,
-                            cli->server_type));
-               }
-       
                if (do_tcon)
                {
                        if (!cli_send_tconX(cli, service, service_type,
@@ -3393,184 +2939,18 @@ BOOL cli_establish_connection(struct cli_state *cli,
                        {
                                DEBUG(1,("failed tcon_X\n"));
                                if (do_shutdown)
-                               {
-                                       cli_shutdown(cli);
-                               }
+                  cli_shutdown(cli);
                                return False;
                        }
                }
        }
 
        if (do_shutdown)
-       {
-               cli_shutdown(cli);
-       }
+      cli_shutdown(cli);
 
        return True;
 }
 
-BOOL cli_connect_auth(struct cli_state *cli,
-                               const char* desthost,
-                               struct in_addr *dest_ip,
-                               const struct ntuser_creds *usr)
-{
-       extern pstring global_myname;
-       extern pstring scope;
-       struct nmb_name calling, called;
-
-       ZERO_STRUCTP(cli);
-       if (!cli_initialise(cli))
-       {
-               DEBUG(0,("unable to initialise client connection.\n"));
-               return False;
-       }
-
-       make_nmb_name(&calling, global_myname, 0x0 , scope);
-       make_nmb_name(&called , desthost     , 0x20, scope);
-
-       cli_init_creds(cli, usr);
-
-       if (!cli_establish_connection(cli, desthost, dest_ip,
-                                     &calling, &called,
-                                     "IPC$", "IPC", 
-                                     False, True))
-       {
-               cli_shutdown(cli);
-               return False;
-       }
-
-       return True;
-}
-
-/****************************************************************************
- connect to one of multiple servers: don't care which
-****************************************************************************/
-BOOL cli_connect_servers_auth(struct cli_state *cli,
-                               char *p,
-                               const struct ntuser_creds *usr)
-{
-       fstring remote_host;
-       BOOL connected_ok = False;
-
-       /*
-       * Treat each name in the 'password server =' line as a potential
-       * PDC/BDC. Contact each in turn and try and authenticate.
-       */
-
-       while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
-       {
-               fstring desthost;
-               struct in_addr dest_ip;
-               strupper(remote_host);
-
-               if (!resolve_srv_name( remote_host, desthost, &dest_ip))
-               {
-                       DEBUG(1,("Can't resolve address for %s\n", remote_host));
-                       continue;
-               }   
-
-               if (!cli_connect_auth(cli, desthost, &dest_ip, usr) &&
-                   !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr))
-               {
-                       continue;
-               }
-
-               if (cli->protocol < PROTOCOL_LANMAN2 ||
-                   !IS_BITS_SET_ALL(cli->sec_mode, 1))
-               {
-                       DEBUG(1,("machine %s not in user level security mode\n",
-                                 remote_host));
-                       cli_shutdown(cli);
-                       continue;
-               }
-
-               /*
-                * We have an anonymous connection to IPC$.
-                */
-
-               connected_ok = True;
-               break;
-       }
-
-       if (!connected_ok)
-       {
-               DEBUG(0,("Domain password server not available.\n"));
-       }
-
-       return connected_ok;
-}
-
-/****************************************************************************
- connect to one of multiple servers: don't care which
-****************************************************************************/
-BOOL cli_connect_serverlist(struct cli_state *cli, char *p)
-{
-       fstring remote_host;
-       fstring desthost;
-       struct in_addr dest_ip;
-       BOOL connected_ok = False;
-
-       /*
-       * Treat each name in the 'password server =' line as a potential
-       * PDC/BDC. Contact each in turn and try and authenticate.
-       */
-
-       while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
-       {
-               ZERO_STRUCTP(cli);
-
-               if (!cli_initialise(cli))
-               {
-                       DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n"));
-                       return False;
-               }
-
-               standard_sub_basic(remote_host);
-               strupper(remote_host);
-
-               if (!resolve_srv_name( remote_host, desthost, &dest_ip))
-               {
-                       DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host));
-                       continue;
-               }   
-
-               if ((lp_security() != SEC_USER) && (ismyip(dest_ip)))
-               {
-                       DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host));
-                       continue;
-               }
-
-               if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) &&
-                   !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL))
-               {
-                       continue;
-               }
-
-
-               if (cli->protocol < PROTOCOL_LANMAN2 ||
-                   !IS_BITS_SET_ALL(cli->sec_mode, 1))
-               {
-                       DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n",
-                                 remote_host));
-                       cli_shutdown(cli);
-                       continue;
-               }
-
-               /*
-                * We have an anonymous connection to IPC$.
-                */
-
-               connected_ok = True;
-               break;
-       }
-
-       if (!connected_ok)
-       {
-               DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n"));
-       }
-
-       return connected_ok;
-}
 
 /****************************************************************************
   cancel a print job
@@ -3583,7 +2963,7 @@ int cli_printjob_del(struct cli_state *cli, int job)
        int rdrcnt,rprcnt, ret = -1;
        pstring param;
 
-       bzero(param,sizeof(param));
+       memset(param,'\0',sizeof(param));
 
        p = param;
        SSVAL(p,0,81);          /* DosPrintJobDel() */
@@ -3624,7 +3004,7 @@ int cli_print_queue(struct cli_state *cli,
        int result_code=0;
        int i = -1;
        
-       bzero(param,sizeof(param));
+       memset(param,'\0',sizeof(param));
 
        p = param;
        SSVAL(p,0,76);         /* API function number 76 (DosPrintJobEnum) */
@@ -3686,29 +3066,29 @@ check for existance of a dir
 ****************************************************************************/
 BOOL cli_chkpath(struct cli_state *cli, char *path)
 {
-       fstring path2;
+       pstring path2;
        char *p;
        
-       fstrcpy(path2,path);
+       safe_strcpy(path2,path,sizeof(pstring));
        trim_string(path2,NULL,"\\");
        if (!*path2) *path2 = '\\';
        
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,0,4 + strlen(path2),True);
        SCVAL(cli->outbuf,smb_com,SMBchkpth);
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
        cli_setup_packet(cli);
-       
        p = smb_buf(cli->outbuf);
        *p++ = 4;
-       fstrcpy(p,path2);
+       safe_strcpy(p,path2,strlen(path2));
+       unix_to_dos(p,True);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
 
-       if (cli_error(cli, NULL, NULL)) return False;
+       if (cli_error(cli, NULL, NULL, NULL)) return False;
 
        return True;
 }
@@ -3723,7 +3103,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
        char *p;
 
        /* send a SMBsendstrt command */
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,0,0,True);
        CVAL(cli->outbuf,smb_com) = SMBsendstrt;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3732,20 +3112,22 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
        p = smb_buf(cli->outbuf);
        *p++ = 4;
        pstrcpy(p,username);
+       unix_to_dos(p,True);
        p = skip_string(p,1);
        *p++ = 4;
        pstrcpy(p,host);
+       unix_to_dos(p,True);
        p = skip_string(p,1);
        
        set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
        
-       cli_send_smb(cli, True);        
+       cli_send_smb(cli);      
        
        if (!cli_receive_smb(cli)) {
                return False;
        }
 
-       if (cli_error(cli, NULL, NULL)) return False;
+       if (cli_error(cli, NULL, NULL, NULL)) return False;
 
        *grp = SVAL(cli->inbuf,smb_vwv0);
 
@@ -3760,7 +3142,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
 {
        char *p;
 
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,1,len+3,True);
        CVAL(cli->outbuf,smb_com) = SMBsendtxt;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3772,13 +3154,13 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
        *p = 1;
        SSVAL(p,1,len);
        memcpy(p+3,msg,len);
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
 
        if (!cli_receive_smb(cli)) {
                return False;
        }
 
-       if (cli_error(cli, NULL, NULL)) return False;
+       if (cli_error(cli, NULL, NULL, NULL)) return False;
 
        return True;
 }      
@@ -3788,7 +3170,7 @@ end a message
 ****************************************************************************/
 BOOL cli_message_end(struct cli_state *cli, int grp)
 {
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,1,0,True);
        CVAL(cli->outbuf,smb_com) = SMBsendend;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3797,13 +3179,13 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
 
        cli_setup_packet(cli);
        
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
 
        if (!cli_receive_smb(cli)) {
                return False;
        }
 
-       if (cli_error(cli, NULL, NULL)) return False;
+       if (cli_error(cli, NULL, NULL, NULL)) return False;
 
        return True;
 }      
@@ -3814,13 +3196,13 @@ query disk space
 ****************************************************************************/
 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
 {
-       bzero(cli->outbuf,smb_size);
+       memset(cli->outbuf,'\0',smb_size);
        set_message(cli->outbuf,0,0,True);
        CVAL(cli->outbuf,smb_com) = SMBdskattr;
        SSVAL(cli->outbuf,smb_tid,cli->cnum);
        cli_setup_packet(cli);
 
-       cli_send_smb(cli, True);
+       cli_send_smb(cli);
        if (!cli_receive_smb(cli)) {
                return False;
        }
@@ -3832,21 +3214,49 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
        return True;
 }
 
-BOOL get_any_dc_name(const char *domain, char *srv_name)
+/****************************************************************************
+ Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
+****************************************************************************/
+
+BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
+                                            struct in_addr *pdest_ip)
 {
-       struct cli_state cli;
+  struct nmb_name calling, called;
 
-       if (!cli_connect_servers_auth(&cli,
-                                     get_trusted_serverlist(domain), NULL))
-       {
-               return False;
-       }
+  make_nmb_name(&calling, srchost, 0x0, scope);
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, cli.desthost);
-       strupper(srv_name);
+  /*
+   * If the called name is an IP address
+   * then use *SMBSERVER immediately.
+   */
 
-       cli_shutdown(&cli);
+  if(is_ipaddress(desthost))
+    make_nmb_name(&called, "*SMBSERVER", 0x20, scope);
+  else
+    make_nmb_name(&called, desthost, 0x20, scope);
 
-       return True;
+  if (!cli_session_request(cli, &calling, &called)) {
+    struct nmb_name smbservername;
+
+    /*
+     * If the name wasn't *SMBSERVER then
+     * try with *SMBSERVER if the first name fails.
+     */
+
+    cli_shutdown(cli);
+
+    make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope);
+
+    if (!nmb_name_equal(&called, &smbservername) ||
+        !cli_initialise(cli) ||
+        !cli_connect(cli, desthost, pdest_ip) ||
+        !cli_session_request(cli, &calling, &smbservername)) {
+          DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n",
+                desthost));
+          cli_shutdown(cli);
+          return False;
+    }
+  }
+
+  return True;
 }
index 299145ceff7d55b22b689b9ed12c103d7d7ae25e..abb9b7d42f5ca11080e327ed8ea3b2d12338d005 100644 (file)
 #include "includes.h"
 
 extern pstring scope;
-extern pstring global_myname;
 extern int DEBUGLEVEL;
 
 /* nmbd.c sets this to True. */
 BOOL global_in_nmbd = False;
 
-  static int name_trn_id = 0;
-
 /****************************************************************************
-interpret a node status response
+ Interpret a node status response.
 ****************************************************************************/
+
 static void _interpret_node_status(char *p, char *master,char *rname)
 {
   int numnames = CVAL(p,0);
@@ -43,55 +41,54 @@ static void _interpret_node_status(char *p, char *master,char *rname)
   if (master) *master = 0;
 
   p += 1;
-  while (numnames--)
-    {
-      char qname[17];
-      int type;
-      fstring flags;
-      int i;
-      *flags = 0;
-      StrnCpy(qname,p,15);
-      type = CVAL(p,15);
-      p += 16;
-
-      fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");
-      if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
-      if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
-      if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
-      if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
-      if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
-      if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
-      if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
-      if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
-
-      if (master && !*master && type == 0x1d) {
-       StrnCpy(master,qname,15);
-       trim_string(master,NULL," ");
-      }
+  while (numnames--) {
+    char qname[17];
+    int type;
+    fstring flags;
+    int i;
+    *flags = 0;
+    StrnCpy(qname,p,15);
+    type = CVAL(p,15);
+    p += 16;
+
+    fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");
+    if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
+    if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
+    if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
+    if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
+    if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
+    if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
+    if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
+    if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
+
+    if (master && !*master && type == 0x1d) {
+      StrnCpy(master,qname,15);
+      trim_string(master,NULL," ");
+    }
 
-      if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
-       StrnCpy(rname,qname,15);
-       trim_string(rname,NULL," ");
-      }
+    if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
+      StrnCpy(rname,qname,15);
+      trim_string(rname,NULL," ");
+    }
       
-      for (i = strlen( qname) ; --i >= 0 ; ) {
-       if (!isprint((int)qname[i])) qname[i] = '.';
-      }
-      DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
-      p+=2;
+    for (i = strlen( qname) ; --i >= 0 ; ) {
+      if (!isprint((int)qname[i])) qname[i] = '.';
     }
+    DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
+    p+=2;
+  }
+
   DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",
               IVAL(p,20),IVAL(p,24)));
 }
 
-
 /****************************************************************************
-  do a netbios name status query on a host
+ Internal function handling a netbios name status query on a host.
+**************************************************************************/
 
-  the "master" parameter is a hack used for finding workgroups.
-  **************************************************************************/
-BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
-                struct in_addr to_ip,char *master,char *rname,
+static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
+                struct in_addr to_ip,char *master,char *rname, BOOL verbose,
+         void (*fn_interpret_node_status)(char *, char *,char *),
                 void (*fn)(struct packet_struct *))
 {
   BOOL found=False;
@@ -101,21 +98,9 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
   struct packet_struct p;
   struct packet_struct *p2;
   struct nmb_packet *nmb = &p.packet.nmb;
-       int packet_type = NMB_PACKET;
-       BOOL first_time = True;
+  static int name_trn_id = 0;
 
-       if (fd == -1)
-       {
-               retries = 1;
-               packet_type = NMB_SOCK_PACKET;
-               fd = get_nmb_sock();
-
-               if (fd < 0)
-               {
-                       return False;
-               }
-       }
-  bzero((char *)&p,sizeof(p));
+  memset((char *)&p,'\0',sizeof(p));
 
   if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + 
     ((unsigned)getpid()%(unsigned)100);
@@ -144,39 +129,40 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
   p.port = NMB_PORT;
   p.fd = fd;
   p.timestamp = time(NULL);
-  p.packet_type = packet_type;
+  p.packet_type = NMB_PACKET;
 
   GetTimeOfDay(&tval);
 
-  while (1)
-    {
-      struct timeval tval2;
-      GetTimeOfDay(&tval2);
-      if (first_time || TvalDiff(&tval,&tval2) > retry_time)
-       {
-               first_time = False;
-       if (!found && !send_packet(&p))
-       {
-               if (packet_type == NMB_SOCK_PACKET) close(fd);
-         return False;
-       }
-       GetTimeOfDay(&tval);
-      }
+  if (!send_packet(&p)) 
+    return(False);
+
+  retries--;
+
+  while (1) {
+    struct timeval tval2;
+    GetTimeOfDay(&tval2);
+    if (TvalDiff(&tval,&tval2) > retry_time) {
+      if (!retries)
+        break;
+      if (!found && !send_packet(&p))
+        return False;
+      GetTimeOfDay(&tval);
+      retries--;
+    }
 
-      if ((p2=receive_packet(fd,packet_type,90)))
-       {     
-         struct nmb_packet *nmb2 = &p2->packet.nmb;
+    if ((p2=receive_packet(fd,NMB_PACKET,90))) {     
+      struct nmb_packet *nmb2 = &p2->packet.nmb;
       debug_nmb_packet(p2);
 
-         if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
-             !nmb2->header.response) {
-           /* its not for us - maybe deal with it later */
-           if (fn) 
-             fn(p2);
-           else
-             free_packet(p2);
-           continue;
-         }
+      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
+             !nmb2->header.response) {
+        /* its not for us - maybe deal with it later */
+        if (fn) 
+          fn(p2);
+        else
+          free_packet(p2);
+        continue;
+      }
          
          if (nmb2->header.opcode != 0 ||
              nmb2->header.nm_flags.bcast ||
@@ -189,55 +175,53 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
            continue;
          }
 
-       retries--;
-
-         _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
+      if(fn_interpret_node_status)
+           (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname);
          free_packet(p2);
-               if (packet_type == NMB_SOCK_PACKET) close(fd);
          return(True);
        }
-    }
-  
+  }
 
-  DEBUG(0,("No status response (this is not unusual)\n"));
+  if(verbose)
+    DEBUG(0,("No status response (this is not unusual)\n"));
 
-if (packet_type == NMB_SOCK_PACKET) close(fd);
   return(False);
 }
 
+/****************************************************************************
+ Do a netbios name status query on a host.
+ The "master" parameter is a hack used for finding workgroups.
+**************************************************************************/
+
+BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
+                struct in_addr to_ip,char *master,char *rname,
+                void (*fn)(struct packet_struct *))
+{
+  return internal_name_status(fd,name,name_type,recurse,
+                to_ip,master,rname,True,
+         _interpret_node_status, fn);
+}
 
 /****************************************************************************
-  do a netbios name query to find someones IP
-  returns an array of IP addresses or NULL if none
-  *count will be set to the number of addresses returned
-  ****************************************************************************/
+ Do a netbios name query to find someones IP.
+ Returns an array of IP addresses or NULL if none.
+ *count will be set to the number of addresses returned.
+****************************************************************************/
+
 struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
          struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *))
 {
   BOOL found=False;
   int i, retries = 3;
-  int retry_time = bcast?2000:2000;
+  int retry_time = bcast?250:2000;
   struct timeval tval;
   struct packet_struct p;
   struct packet_struct *p2;
   struct nmb_packet *nmb = &p.packet.nmb;
+  static int name_trn_id = 0;
   struct in_addr *ip_list = NULL;
-       BOOL packet_type = NMB_PACKET;
-       BOOL first_send = True;
-
-       if (fd == -1)
-       {
-               retries = 1;
-               packet_type = NMB_SOCK_PACKET;
-               fd = get_nmb_sock();
-
-               if (fd < 0)
-               {
-                       return NULL;
-               }
-       }
 
-  bzero((char *)&p,sizeof(p));
+  memset((char *)&p,'\0',sizeof(p));
   (*count) = 0;
 
   if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + 
@@ -267,27 +251,30 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
   p.port = NMB_PORT;
   p.fd = fd;
   p.timestamp = time(NULL);
-  p.packet_type = packet_type;
+  p.packet_type = NMB_PACKET;
+
+  GetTimeOfDay(&tval);
 
-     GetTimeOfDay(&tval);
+  if (!send_packet(&p)) 
+    return NULL;
 
-  while (retries >= 0)
+  retries--;
+
+  while (1)
   {
     struct timeval tval2;
-
     GetTimeOfDay(&tval2);
-    if (first_send || TvalDiff(&tval,&tval2) > retry_time)
+    if (TvalDiff(&tval,&tval2) > retry_time) 
     {
-       first_send = False;
+      if (!retries)
+        break;
       if (!found && !send_packet(&p))
-       {
-               if (packet_type == NMB_SOCK_PACKET) close(fd);
         return NULL;
-       }
       GetTimeOfDay(&tval);
+      retries--;
     }
 
-    if ((p2=receive_packet(fd,packet_type,90)))
+    if ((p2=receive_packet(fd,NMB_PACKET,90)))
     {     
       struct nmb_packet *nmb2 = &p2->packet.nmb;
       debug_nmb_packet(p2);
@@ -295,8 +282,6 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
       if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
           !nmb2->header.response)
       {
-       DEBUG(10,("packet not for us (received %d, expected %d\n",
-      nmb2->header.name_trn_id, nmb->header.name_trn_id));
         /* 
          * Its not for us - maybe deal with it later 
          * (put it on the queue?).
@@ -305,12 +290,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
           fn(p2);
         else
           free_packet(p2);
-
         continue;
       }
          
-       retries--;
-
       if (nmb2->header.opcode != 0 ||
           nmb2->header.nm_flags.bcast ||
           nmb2->header.rcode ||
@@ -345,15 +327,16 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
       if (fn)
         break;
 
-      if(found)
-       {
-        DEBUG(10,("returning OK\n"));
+      /*
+       * If we're doing a unicast lookup we only
+       * expect one reply. Don't wait the full 2
+       * seconds if we got one. JRA.
+       */
+      if(!bcast && found)
         break;
-        }
     }
   }
 
-       if (packet_type == NMB_SOCK_PACKET) close(fd);
   return ip_list;
 }
 
@@ -375,6 +358,7 @@ FILE *startlmhosts(char *fname)
 /********************************************************
  Parse the next line in the lmhosts file.
 *********************************************************/
+
 BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
 {
   pstring line;
@@ -439,7 +423,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad
       char *endptr;
 
       ptr++;
-      *name_type = (int)strtol(ptr, &endptr,0);
+      *name_type = (int)strtol(ptr, &endptr, 16);
 
       if(!*ptr || (endptr == ptr))
       {
@@ -465,108 +449,107 @@ void endlmhosts(FILE *fp)
   fclose(fp);
 }
 
-
-
 /********************************************************
-resolve via "bcast" method
+ Resolve via "bcast" method.
 *********************************************************/
-static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_bcast(const char *name, int name_type,
+                               struct in_addr **return_ip_list, int *return_count)
 {
        int sock, i;
+       int num_interfaces = iface_count();
+
+       *return_ip_list = NULL;
+       *return_count = 0;
        
        /*
         * "bcast" means do a broadcast lookup on all the local interfaces.
         */
 
-       DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name));
+       DEBUG(3,("resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
 
        sock = open_socket_in( SOCK_DGRAM, 0, 3,
-                              interpret_addr(lp_socket_address()) );
-
-       if (sock != -1) {
-               struct in_addr *iplist = NULL;
-               int count;
-               int num_interfaces = iface_count();
-               set_socket_options(sock,"SO_BROADCAST");
-               /*
-                * Lookup the name on all the interfaces, return on
-                * the first successful match.
-                */
-               for( i = 0; i < num_interfaces; i++) {
-                       struct in_addr sendto_ip;
-                       /* Done this way to fix compiler error on IRIX 5.x */
-                       sendto_ip = *iface_bcast(*iface_n_ip(i));
-                       iplist = name_query(sock, name, name_type, True, 
-                                           True, sendto_ip, &count, NULL);
-                       if(iplist != NULL) {
-                               *return_ip = iplist[0];
-                               free((char *)iplist);
-                               close(sock);
-                               return True;
-                       }
+                              interpret_addr(lp_socket_address()), True );
+
+       if (sock == -1) return False;
+
+       set_socket_options(sock,"SO_BROADCAST");
+       /*
+        * Lookup the name on all the interfaces, return on
+        * the first successful match.
+        */
+       for( i = num_interfaces-1; i >= 0; i--) {
+               struct in_addr sendto_ip;
+               /* Done this way to fix compiler error on IRIX 5.x */
+               sendto_ip = *iface_bcast(*iface_n_ip(i));
+               *return_ip_list = name_query(sock, name, name_type, True, 
+                                   True, sendto_ip, return_count, NULL);
+               if(*return_ip_list != NULL) {
+                       close(sock);
+                       return True;
                }
-               close(sock);
        }
 
+       close(sock);
        return False;
 }
 
-
-
 /********************************************************
-resolve via "wins" method
+ Resolve via "wins" method.
 *********************************************************/
-static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_wins(const char *name, int name_type,
+                         struct in_addr **return_iplist, int *return_count)
 {
-      int sock;
-      struct in_addr wins_ip;
-      BOOL wins_ismyip;
+       int sock;
+       struct in_addr wins_ip;
+       BOOL wins_ismyip;
 
-      /*
-       * "wins" means do a unicast lookup to the WINS server.
-       * Ignore if there is no WINS server specified or if the
-       * WINS server is one of our interfaces (if we're being
-       * called from within nmbd - we can't do this call as we
-       * would then block).
-       */
+       *return_iplist = NULL;
+       *return_count = 0;
+       
+       /*
+        * "wins" means do a unicast lookup to the WINS server.
+        * Ignore if there is no WINS server specified or if the
+        * WINS server is one of our interfaces (if we're being
+        * called from within nmbd - we can't do this call as we
+        * would then block).
+        */
 
-      DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name));
+       DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
 
-      if(!*lp_wins_server()) {
-             DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n"));
-             return False;
-      }
+       if(!*lp_wins_server()) {
+               DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS server present.\n"));
+               return False;
+       }
 
-      wins_ip = *interpret_addr2(lp_wins_server());
-      wins_ismyip = ismyip(wins_ip);
+       wins_ip = *interpret_addr2(lp_wins_server());
+       wins_ismyip = ismyip(wins_ip);
 
-      if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
-             sock = open_socket_in( SOCK_DGRAM, 0, 3,
-                                    interpret_addr(lp_socket_address()) );
+       if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
+               sock = open_socket_in( SOCK_DGRAM, 0, 3,
+                                                       interpret_addr(lp_socket_address()), True );
              
-             if (sock != -1) {
-                     struct in_addr *iplist = NULL;
-                     int count;
-                     iplist = name_query(sock, name, name_type, False, 
-                                         True, wins_ip, &count, NULL);
-                     if(iplist != NULL) {
-                             *return_ip = iplist[0];
-                             free((char *)iplist);
-                             close(sock);
-                             return True;
-                     }
-                     close(sock);
-             }
-      }
+               if (sock != -1) {
+                       *return_iplist = name_query(sock, name, name_type, False, 
+                                                               True, wins_ip, return_count, NULL);
+                       if(*return_iplist != NULL) {
+                               close(sock);
+                               return True;
+                       }
+                       close(sock);
+               }
+       }
 
-      return False;
+       return False;
 }
 
-
 /********************************************************
-resolve via "lmhosts" method
+ Resolve via "lmhosts" method.
 *********************************************************/
-static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_lmhosts(const char *name, int name_type,
+                         struct in_addr **return_iplist, int *return_count)
 {
        /*
         * "lmhosts" means parse the local lmhosts file.
@@ -575,15 +558,27 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam
        FILE *fp;
        pstring lmhost_name;
        int name_type2;
+       struct in_addr return_ip;
+
+       *return_iplist = NULL;
+       *return_count = 0;
 
-       DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name));
+       DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
 
        fp = startlmhosts( LMHOSTSFILE );
        if(fp) {
-               while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) {
+               while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
                        if (strequal(name, lmhost_name) && 
-                           name_type == name_type2) {
+                ((name_type2 == -1) || (name_type == name_type2))
+               ) {
                                endlmhosts(fp);
+                               *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+                               if(*return_iplist == NULL) {
+                                       DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
+                                       return False;
+                               }
+                               **return_iplist = return_ip;
+                               *return_count = 1;
                                return True; 
                        }
                }
@@ -594,89 +589,94 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam
 
 
 /********************************************************
-resolve via "hosts" method
+ Resolve via "hosts" method.
 *********************************************************/
-static BOOL resolve_hosts(const char *name, struct in_addr *return_ip)
+
+static BOOL resolve_hosts(const char *name,
+                         struct in_addr **return_iplist, int *return_count)
 {
        /*
         * "host" means do a localhost, or dns lookup.
         */
        struct hostent *hp;
 
-       DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name));
+       *return_iplist = NULL;
+       *return_count = 0;
+
+       DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
        
        if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
-               putip((char *)return_ip,(char *)hp->h_addr);
+               struct in_addr return_ip;
+               putip((char *)&return_ip,(char *)hp->h_addr);
+               *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+               if(*return_iplist == NULL) {
+                       DEBUG(3,("resolve_hosts: malloc fail !\n"));
+                       return False;
+               }
+               **return_iplist = return_ip;
+               *return_count = 1;
                return True;
        }
        return False;
 }
 
-
 /********************************************************
- Resolve a name into an IP address. Use this function if
- the string is either an IP address, DNS or host name
- or NetBIOS name. This uses the name switch in the
+ Internal interface to resolve a name into an IP address.
+ Use this function if the string is either an IP address, DNS
+ or host name or NetBIOS name. This uses the name switch in the
  smb.conf to determine the order of name resolution.
 *********************************************************/
-BOOL is_ip_address(const char *name)
-{
-  int i;
-  for (i=0; name[i]; i++)
-    if (!(isdigit((int)name[i]) || name[i] == '.'))
-       return False;
-   
-  return True;
-}
 
-/********************************************************
- Resolve a name into an IP address. Use this function if
- the string is either an IP address, DNS or host name
- or NetBIOS name. This uses the name switch in the
- smb.conf to determine the order of name resolution.
-*********************************************************/
-BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+static BOOL internal_resolve_name(const char *name, int name_type,
+                                       struct in_addr **return_iplist, int *return_count)
 {
   pstring name_resolve_list;
   fstring tok;
   char *ptr;
-
-  if (strcmp(name,"0.0.0.0") == 0) {
-    return_ip->s_addr = 0;
-    return True;
-  }
-  if (strcmp(name,"255.255.255.255") == 0) {
-    return_ip->s_addr = 0xFFFFFFFF;
-    return True;
-  }
-   
-  /* if it's in the form of an IP address then get the lib to interpret it */
-  if (is_ip_address(name)) {
-    return_ip->s_addr = inet_addr(name);
+  BOOL allones = (strcmp(name,"255.255.255.255") == 0);
+  BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
+  BOOL is_address = is_ipaddress(name);
+  *return_iplist = NULL;
+  *return_count = 0;
+
+  if (allzeros || allones || is_address) {
+       *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+       if(*return_iplist == NULL) {
+               DEBUG(3,("internal_resolve_name: malloc fail !\n"));
+               return False;
+       }
+       if(is_address) { 
+               /* if it's in the form of an IP address then get the lib to interpret it */
+               (*return_iplist)->s_addr = inet_addr(name);
+    } else {
+               (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
+               *return_count = 1;
+       }
     return True;
   }
-
+  
   pstrcpy(name_resolve_list, lp_name_resolve_order());
   ptr = name_resolve_list;
-  if (!ptr || !*ptr) ptr = "host";
+  if (!ptr || !*ptr)
+    ptr = "host";
 
   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
          if((strequal(tok, "host") || strequal(tok, "hosts"))) {
-                 if (name_type == 0x20 && resolve_hosts(name, return_ip)) {
+                 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
                          return True;
                  }
          } else if(strequal( tok, "lmhosts")) {
-                 if (resolve_lmhosts(name, return_ip, name_type)) {
+                 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
                          return True;
                  }
          } else if(strequal( tok, "wins")) {
                  /* don't resolve 1D via WINS */
                  if (name_type != 0x1D &&
-                     resolve_wins(name, return_ip, name_type)) {
+                     resolve_wins(name, name_type, return_iplist, return_count)) {
                          return True;
                  }
          } else if(strequal( tok, "bcast")) {
-                 if (resolve_bcast(name, return_ip, name_type)) {
+                 if (resolve_bcast(name, name_type, return_iplist, return_count)) {
                          return True;
                  }
          } else {
@@ -684,50 +684,319 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
          }
   }
 
+  if((*return_iplist) != NULL) {
+    free((char *)(*return_iplist));
+    *return_iplist = NULL;
+  }
   return False;
 }
 
 /********************************************************
- resolve a name of format \\server_name or \\ipaddress
- into a name.  also, cut the \\ from the front for us.
+ Internal interface to resolve a name into one IP address.
+ Use this function if the string is either an IP address, DNS
+ or host name or NetBIOS name. This uses the name switch in the
+ smb.conf to determine the order of name resolution.
 *********************************************************/
-BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
-                               struct in_addr *ip)
-{
-       BOOL ret;
-       const char *sv_name = srv_name;
 
-       DEBUG(10,("resolve_srv_name: %s\n", srv_name));
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+{
+       struct in_addr *ip_list = NULL;
+       int count = 0;
 
-       if (srv_name == NULL || strequal("\\\\.", srv_name))
-       {
-               fstrcpy(dest_host, global_myname);
-               ip = interpret_addr2("127.0.0.1");
+       if(internal_resolve_name(name, name_type, &ip_list, &count)) {
+               *return_ip = ip_list[0];
+               free((char *)ip_list);
                return True;
        }
+       if(ip_list != NULL)
+               free((char *)ip_list);
+       return False;
+}
 
-       if (strnequal("\\\\", srv_name, 2))
-       {
-               sv_name = &srv_name[2];
-       }
+/********************************************************
+ Find the IP address of the master browser or DMB for a workgroup.
+*********************************************************/
 
-       fstrcpy(dest_host, sv_name);
-       ret = resolve_name(dest_host, ip, 0x20);
-       
-       if (is_ip_address(dest_host))
-       {
-               fstrcpy(dest_host, "*SMBSERVER");
+BOOL find_master_ip(char *group, struct in_addr *master_ip)
+{
+       struct in_addr *ip_list = NULL;
+       int count = 0;
+
+       if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
+               *master_ip = ip_list[0];
+               free((char *)ip_list);
+               return True;
        }
-       
-       return ret;
+       if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
+               *master_ip = ip_list[0];
+               free((char *)ip_list);
+               return True;
+       }
+
+       if(ip_list != NULL)
+               free((char *)ip_list);
+       return False;
 }
 
 /********************************************************
-find the IP address of the master browser or DMB for a workgroup
+ Internal function to extract the MACHINE<0x20> name.
 *********************************************************/
-BOOL find_master_ip(char *group, struct in_addr *master_ip)
+
+static void _lookup_pdc_name(char *p, char *master,char *rname)
+{
+  int numnames = CVAL(p,0);
+
+  *rname = '\0';
+
+  p += 1;
+  while (numnames--) {
+    int type = CVAL(p,15);
+    if(type == 0x20) {
+      StrnCpy(rname,p,15);
+      trim_string(rname,NULL," ");
+      return;
+    }
+    p += 18;
+  }
+}
+
+/********************************************************
+ Lookup a PDC name given a Domain name and IP address.
+*********************************************************/
+
+BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name)
 {
-       if (resolve_name(group, master_ip, 0x1D)) return True;
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)
+
+  fstring pdc_name;
+  BOOL ret;
+
+  /*
+   * Due to the fact win WinNT *sucks* we must do a node status
+   * query here... JRA.
+   */
 
-       return resolve_name(group, master_ip, 0x1B);
+  int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
+
+  if(sock == -1)
+    return False;
+
+  *pdc_name = '\0';
+
+  ret = internal_name_status(sock,"*SMBSERVER",0x20,True,
+                *pdc_ip,NULL,pdc_name,False,
+         _lookup_pdc_name,NULL);
+
+  close(sock);
+
+  if(ret && *pdc_name) {
+    fstrcpy(ret_name, pdc_name);
+    return True;
+  }
+
+  return False;
+
+#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
+  /*
+   * Sigh. I *love* this code, it took me ages to get right and it's
+   * completely *USELESS* because NT 4.x refuses to send the mailslot
+   * reply back to the correct port (it always uses 138).
+   * I hate NT when it does these things... JRA.
+   */
+
+  int retries = 3;
+  int retry_time = 2000;
+  struct timeval tval;
+  struct packet_struct p;
+  struct dgram_packet *dgram = &p.packet.dgram;
+  char *ptr,*p2;
+  char tmp[4];
+  int len;
+  struct sockaddr_in sock_name;
+  int sock_len = sizeof(sock_name);
+  const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON";
+  static int name_trn_id = 0;
+  char buffer[1024];
+  char *bufp;
+  int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
+
+  if(sock == -1)
+    return False;
+
+  /* Find out the transient UDP port we have been allocated. */
+  if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
+    DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
+            strerror(errno)));
+    close(sock);
+    return False;
+  }
+
+  /*
+   * Create the request data.
+   */
+
+  memset(buffer,'\0',sizeof(buffer));
+  bufp = buffer;
+  SSVAL(bufp,0,QUERYFORPDC);
+  bufp += 2;
+  fstrcpy(bufp,srcname);
+  bufp += (strlen(bufp) + 1);
+  fstrcpy(bufp,"\\MAILSLOT\\NET\\GETDC411");
+  bufp += (strlen(bufp) + 1);
+  bufp = align2(bufp, buffer);
+  dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1);
+  bufp = skip_unicode_string(bufp, 1);
+  SIVAL(bufp,0,1);
+  SSVAL(bufp,4,0xFFFF); 
+  SSVAL(bufp,6,0xFFFF); 
+  bufp += 8;
+  len = PTR_DIFF(bufp,buffer);
+
+  if (!name_trn_id)
+    name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
+  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+
+  memset((char *)&p,'\0',sizeof(p));
+
+  /* DIRECT GROUP or UNIQUE datagram. */
+  dgram->header.msg_type = 0x10;
+  dgram->header.flags.node_type = M_NODE;
+  dgram->header.flags.first = True;
+  dgram->header.flags.more = False;
+  dgram->header.dgm_id = name_trn_id;
+  dgram->header.source_ip = sock_name.sin_addr;
+  dgram->header.source_port = ntohs(sock_name.sin_port);
+  dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
+  dgram->header.packet_offset = 0;
+  make_nmb_name(&dgram->source_name,srcname,0,scope);
+  make_nmb_name(&dgram->dest_name,domain,0x1B,scope);
+
+  ptr = &dgram->data[0];
+
+  /* Setup the smb part. */
+  ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
+  memcpy(tmp,ptr,4);
+  set_message(ptr,17,17 + len,True);
+  memcpy(ptr,tmp,4);
+
+  CVAL(ptr,smb_com) = SMBtrans;
+  SSVAL(ptr,smb_vwv1,len);
+  SSVAL(ptr,smb_vwv11,len);
+  SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
+  SSVAL(ptr,smb_vwv13,3);
+  SSVAL(ptr,smb_vwv14,1);
+  SSVAL(ptr,smb_vwv15,1);
+  SSVAL(ptr,smb_vwv16,2);
+  p2 = smb_buf(ptr);
+  pstrcpy(p2,mailslot);
+  p2 = skip_string(p2,1);
+
+  memcpy(p2,buffer,len);
+  p2 += len;
+
+  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
+
+  p.ip = *pdc_ip;
+  p.port = DGRAM_PORT;
+  p.fd = sock;
+  p.timestamp = time(NULL);
+  p.packet_type = DGRAM_PACKET;
+
+  GetTimeOfDay(&tval);
+
+  if (!send_packet(&p)) {
+    DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+    close(sock);
+    return False;
+  }
+
+  retries--;
+
+  while (1) {
+    struct timeval tval2;
+    struct packet_struct *p_ret;
+
+    GetTimeOfDay(&tval2);
+    if (TvalDiff(&tval,&tval2) > retry_time) {
+      if (!retries)
+        break;
+      if (!send_packet(&p)) {
+        DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+        close(sock);
+        return False;
+      }
+      GetTimeOfDay(&tval);
+      retries--;
+    }
+
+    if ((p_ret = receive_packet(sock,NMB_PACKET,90))) {
+      struct nmb_packet *nmb2 = &p_ret->packet.nmb;
+      struct dgram_packet *dgram2 = &p_ret->packet.dgram;
+      char *buf;
+      char *buf2;
+
+      debug_nmb_packet(p_ret);
+
+      if (memcmp(&p.ip, &p_ret->ip, sizeof(p.ip))) {
+        /* 
+         * Not for us.
+         */
+        DEBUG(0,("lookup_pdc_name: datagram return IP %s doesn't match\n", inet_ntoa(p_ret->ip) ));
+        free_packet(p_ret);
+        continue;
+      }
+
+      buf = &dgram2->data[0];
+      buf -= 4;
+
+      if (CVAL(buf,smb_com) != SMBtrans) {
+        DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)CVAL(buf,smb_com),
+              (unsigned int)SMBtrans ));
+        free_packet(p_ret);
+        continue;
+      }
+
+      len = SVAL(buf,smb_vwv11);
+      buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+
+      if (len <= 0) {
+        DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
+        free_packet(p_ret);
+        continue;
+      }
+
+      DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
+       nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
+       inet_ntoa(p_ret->ip), smb_buf(buf),CVAL(buf2,0),len));
+
+      if(SVAL(buf,0) != QUERYFORPDC_R) {
+        DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
+              (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
+        free_packet(p_ret);
+        continue;
+      }
+
+      buf += 2;
+      /* Note this is safe as it is a bounded strcpy. */
+      fstrcpy(ret_name, buf);
+      ret_name[sizeof(fstring)-1] = '\0';
+      close(sock);
+      free_packet(p_ret);
+      return True;
+    }
+  }
+
+  close(sock);
+  return False;
+#endif /* I_HATE_WINDOWS_REPLY_CODE */
+}
+
+/********************************************************
+ Get the IP address list of the PDC/BDC's of a Domain.
+*********************************************************/
+
+BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count)
+{
+       return internal_resolve_name(group, 0x1C, ip_list, count);
 }
index 006cb5f5eed4cd953bd12380dadc32f76dba8606..3b14fd2c6b08fcee6ea594e1756a993006a7e392 100644 (file)
@@ -179,27 +179,34 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
   unsigned char *ubuf = (unsigned char *)inbuf;
   int ret = 0;
   BOOL got_pointer=False;
+  int loop_count=0;
 
-  if (length - offset < 2) return(0);  
+  if (length - offset < 2)
+    return(0);  
 
   /* handle initial name pointers */
-  if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+  if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+    return(0);
   
   m = ubuf[offset];
 
-  if (!m) return(0);
-  if ((m & 0xC0) || offset+m+2 > length) return(0);
+  if (!m)
+    return(0);
+  if ((m & 0xC0) || offset+m+2 > length)
+    return(0);
 
-  bzero((char *)name,sizeof(*name));
+  memset((char *)name,'\0',sizeof(*name));
 
   /* the "compressed" part */
-  if (!got_pointer) ret += m + 2;
+  if (!got_pointer)
+    ret += m + 2;
   offset++;
-  while (m) {
+  while (m > 0) {
     unsigned char c1,c2;
     c1 = ubuf[offset++]-'A';
     c2 = ubuf[offset++]-'A';
-    if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
+    if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
+      return(0);
     name->name[n++] = (c1<<4) | c2;
     m -= 2;
   }
@@ -213,21 +220,38 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
     /* remove trailing spaces */
     name->name[15] = 0;
     n = 14;
-    while (n && name->name[n]==' ') name->name[n--] = 0;  
+    while (n && name->name[n]==' ')
+      name->name[n--] = 0;  
   }
 
   /* now the domain parts (if any) */
   n = 0;
   while (ubuf[offset]) {
     /* we can have pointers within the domain part as well */
-    if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+    if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+      return(0);
 
     m = ubuf[offset];
-    if (!got_pointer) ret += m+1;
-    if (n) name->scope[n++] = '.';
-    if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
+    /*
+     * Don't allow null domain parts.
+     */
+    if (!m)
+      return(0);
+    if (!got_pointer)
+      ret += m+1;
+    if (n)
+      name->scope[n++] = '.';
+    if (m+2+offset>length || n+m+1>sizeof(name->scope))
+      return(0);
     offset++;
-    while (m--) name->scope[n++] = (char)ubuf[offset++];
+    while (m--)
+      name->scope[n++] = (char)ubuf[offset++];
+
+    /*
+     * Watch for malicious loops.
+     */
+    if (loop_count++ == 10)
+      return 0;
   }
   name->scope[n++] = 0;  
 
@@ -251,7 +275,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
 
   if (strcmp(name->name,"*") == 0) {
     /* special case for wildcard name */
-    bzero(buf1,20);
+    memset(buf1,'\0',20);
     buf1[0] = '*';
     buf1[15] = name->name_type;
   } else {
@@ -287,7 +311,6 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
   return(ret);
 }
 
-
 /*******************************************************************
   useful for debugging messages
   ******************************************************************/
@@ -297,23 +320,15 @@ char *nmb_namestr(struct nmb_name *n)
   static fstring ret[4];
   char *p = ret[i];
 
-  nmb_safe_namestr(n, p, sizeof(fstring));
+  if (!n->scope[0])
+    slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
+  else
+    slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
 
   i = (i+1)%4;
   return(p);
 }
 
-/*******************************************************************
-  useful for debugging messages
-  ******************************************************************/
-void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
-{
-  if (!n->scope[0])
-    slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
-  else
-    slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
-}
-
 /*******************************************************************
   allocate and parse some resource records
   ******************************************************************/
@@ -324,13 +339,14 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
   *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
   if (!*recs) return(False);
 
-  bzero(*recs,sizeof(**recs)*count);
+  memset((char *)*recs,'\0',sizeof(**recs)*count);
 
   for (i=0;i<count;i++) {
     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
     (*offset) += l;
     if (!l || (*offset)+10 > length) {
       free(*recs);
+      *recs = NULL;
       return(False);
     }
     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
@@ -341,6 +357,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
        (*offset)+(*recs)[i].rdlength > length) {
       free(*recs);
+      *recs = NULL;
       return(False);
     }
     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
@@ -405,7 +422,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
   int offset;
   int flags;
 
-  bzero((char *)dgram,sizeof(*dgram));
+  memset((char *)dgram,'\0',sizeof(*dgram));
 
   if (length < 14) return(False);
 
@@ -447,7 +464,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
 {
   int nm_flags,offset;
 
-  bzero((char *)nmb,sizeof(*nmb));
+  memset((char *)nmb,'\0',sizeof(*nmb));
 
   if (length < 12) return(False);
 
@@ -563,12 +580,18 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
 
 free_and_exit:
 
-  if(copy_nmb->answers)
+  if(copy_nmb->answers) {
     free((char *)copy_nmb->answers);
-  if(copy_nmb->nsrecs)
+    copy_nmb->answers = NULL;
+  }
+  if(copy_nmb->nsrecs) {
     free((char *)copy_nmb->nsrecs);
-  if(copy_nmb->additional)
+    copy_nmb->nsrecs = NULL;
+  }
+  if(copy_nmb->additional) {
     free((char *)copy_nmb->additional);
+    copy_nmb->additional = NULL;
+  }
   free((char *)pkt_copy);
 
   DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
@@ -617,9 +640,18 @@ struct packet_struct *copy_packet(struct packet_struct *packet)
   ******************************************************************/
 static void free_nmb_packet(struct nmb_packet *nmb)
 {  
-  if (nmb->answers) free(nmb->answers);
-  if (nmb->nsrecs) free(nmb->nsrecs);
-  if (nmb->additional) free(nmb->additional);
+  if (nmb->answers) {
+    free(nmb->answers);
+    nmb->answers = NULL;
+  }
+  if (nmb->nsrecs) {
+    free(nmb->nsrecs);
+    nmb->nsrecs = NULL;
+  }
+  if (nmb->additional) {
+    free(nmb->additional);
+    nmb->additional = NULL;
+  }
 }
 
 /*******************************************************************
@@ -641,6 +673,7 @@ void free_packet(struct packet_struct *packet)
     free_nmb_packet(&packet->packet.nmb);
   else if (packet->packet_type == DGRAM_PACKET)
     free_dgram_packet(&packet->packet.dgram);
+  ZERO_STRUCTPN(packet);
   free(packet);
 }
 
@@ -651,47 +684,15 @@ void free_packet(struct packet_struct *packet)
 struct packet_struct *read_packet(int fd,enum packet_type packet_type)
 {
   extern struct in_addr lastip;
-       struct nmb_state con;
   extern int lastport;
   struct packet_struct *packet;
   char buf[MAX_DGRAM_SIZE];
   int length;
   BOOL ok=False;
   
-       if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
-       {
-               uint16 trn_id = 0;
-               if (!read_nmb_sock(fd, &con))
-               {
-                       return False;
-               }
-               if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
-               {
-                       return False;
-               }
-       }
-       
-       length = read_udp_socket(fd,buf,sizeof(buf));
-       
-       dump_data(100, buf, length);
-
-       if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
-       {
-               uint16 trn_id = 0;
-               if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
-               {
-                       return False;
-               }
-       }
-       
+  length = read_udp_socket(fd,buf,sizeof(buf));
   if (length < MIN_DGRAM_SIZE) return(NULL);
 
-       if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
-       {
-               lastip = con.ip;
-               lastport = con.port;
-       }
-
   packet = (struct packet_struct *)malloc(sizeof(*packet));
   if (!packet) return(NULL);
 
@@ -706,19 +707,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
   switch (packet_type) 
     {
     case NMB_PACKET:
-    case NMB_SOCK_PACKET:
       ok = parse_nmb(buf,length,&packet->packet.nmb);
       break;
 
     case DGRAM_PACKET:
-    case DGRAM_SOCK_PACKET:
       ok = parse_dgram(buf,length,&packet->packet.dgram);
       break;
     }
   if (!ok) {
     DEBUG(10,("read_packet: discarding packet id = %d\n", 
                  packet->packet.nmb.header.name_trn_id));
-    free(packet);
+    free_packet(packet);
     return(NULL);
   }
 
@@ -740,7 +739,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
   struct sockaddr_in sock_out;
 
   /* set the address and port */
-  bzero((char *)&sock_out,sizeof(sock_out));
+  memset((char *)&sock_out,'\0',sizeof(sock_out));
   putip((char *)&sock_out.sin_addr,(char *)&ip);
   sock_out.sin_port = htons( port );
   sock_out.sin_family = AF_INET;
@@ -776,7 +775,7 @@ static int build_dgram(char *buf,struct packet_struct *p)
 
   /* put in the header */
   ubuf[0] = dgram->header.msg_type;
-  ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2);
+  ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
   if (dgram->header.flags.more) ubuf[1] |= 1;
   if (dgram->header.flags.first) ubuf[1] |= 2;
   RSSVAL(ubuf,2,dgram->header.dgm_id);
@@ -909,82 +908,23 @@ BOOL send_packet(struct packet_struct *p)
   char buf[1024];
   int len=0;
 
-       DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
-
-  bzero(buf,sizeof(buf));
+  memset(buf,'\0',sizeof(buf));
 
   switch (p->packet_type) 
     {
     case NMB_PACKET:
-    case NMB_SOCK_PACKET:
       len = build_nmb(buf,p);
       debug_nmb_packet(p);
       break;
 
     case DGRAM_PACKET:
-    case DGRAM_SOCK_PACKET:
       len = build_dgram(buf,p);
       break;
     }
 
   if (!len) return(False);
 
-  switch (p->packet_type) 
-    {
-    case DGRAM_PACKET:
-    case NMB_PACKET:
-         return(send_udp(p->fd,buf,len,p->ip,p->port));
-      break;
-
-    case NMB_SOCK_PACKET:
-    case DGRAM_SOCK_PACKET:
-       {
-               fstring qbuf;
-               struct nmb_state nmb;
-               int qlen;
-               uint16 trn_id;
-               char *q = qbuf + 4;
-
-               nmb.ip = p->ip;
-               nmb.port = p->port;
-
-               SSVAL(q, 0, 0);
-               q += 2;
-               SSVAL(q, 0, 0);
-               q += 2;
-               memcpy(q, &nmb, sizeof(nmb));
-               q += sizeof(nmb);
-
-               qlen = PTR_DIFF(q, qbuf);
-               SIVAL(qbuf, 0, qlen);
-
-               dump_data(100, qbuf, qlen);
-
-                 if (write(p->fd,qbuf,qlen) != qlen)
-               {
-                       DEBUG(0,("send_packet: write hdr failed\n"));
-                       return False;
-               }
-               if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
-               {
-                       DEBUG(0,("send_packet: 1st ack failed\n"));
-                       return False;
-               }
-               if (write(p->fd,buf,len) != len)
-               {
-                       DEBUG(0,("send_packet: write packet failed\n"));
-                       return False;
-               }
-               if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
-               {
-                       DEBUG(0,("send_packet: 2nd ack failed\n"));
-                       return False;
-               }
-               return True;
-       }
-    }
-
-       return False;
+  return(send_udp(p->fd,buf,len,p->ip,p->port));
 }
 
 /****************************************************************************
@@ -1001,8 +941,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);
 
-       DEBUG(100,("receive_packet: %d %d\n", fd, type));
-  sys_select(fd+1,&fds,NULL, &timeout);
+  sys_select(fd+1,&fds,&timeout);
 
   if (FD_ISSET(fd,&fds)) 
     return(read_packet(fd,type));
@@ -1055,76 +994,3 @@ void sort_query_replies(char *data, int n, struct in_addr ip)
 
        qsort(data, n, 6, QSORT_CAST name_query_comp);
 }
-
-BOOL read_nmb_sock(int c, struct nmb_state *con)
-{
-       fstring buf;
-       char *p = buf;
-       int rl;
-       uint32 len;
-       uint16 version;
-       uint16 command;
-
-       ZERO_STRUCTP(con);
-
-       rl = read(c, &buf, sizeof(len));
-
-       if (rl < 0)
-       {
-               DEBUG(0,("read_nmb_sock: error\n"));
-               return False;
-       }
-       if (rl != sizeof(len))
-       {
-               DEBUG(0,("Unable to read length\n"));
-               dump_data(0, buf, sizeof(len));
-               return False;
-       }
-
-       len = IVAL(buf, 0);
-
-       if (len > sizeof(buf))
-       {
-               DEBUG(0,("length %d too long\n", len));
-               return False;
-       }
-
-       rl = read(c, buf, len);
-
-       if (rl < 0)
-       {
-               DEBUG(0,("Unable to read from connection\n"));
-               return False;
-       }
-       
-#ifdef DEBUG_PASSWORD
-       dump_data(100, buf, rl);
-#endif
-       version = SVAL(p, 0);
-       p += 2;
-       command = SVAL(p, 0);
-       p += 2;
-
-       memcpy(con, p, sizeof(*con));
-       p += sizeof(*con);
-
-       DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
-                  inet_ntoa(con->ip), con->port));
-
-       if (PTR_DIFF(p, buf) != rl)
-       {
-               DEBUG(0,("Buffer size %d %d!\n",
-                       PTR_DIFF(p, buf), rl));
-               return False;
-       }
-
-       return True;
-}
-
-int get_nmb_sock(void)
-{
-       fstring path;
-       slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
-
-       return open_pipe_sock(path);
-}
index 9cf1fb82140d1b6015e01055e3b6c4d061c15842..d2f9335000d5ce8af019c465fe95ee03a5b65d53 100644 (file)
@@ -514,18 +514,18 @@ nt_err_code_struct nt_errs[] =
        { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
        { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
        { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
-       { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB },
        { NULL, 0 }
 };
 
 /*****************************************************************************
  returns an NT error message.  not amazingly helpful, but better than a number.
  *****************************************************************************/
-void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len)
+char *get_nt_error_msg(uint32 nt_code)
 {
+       static pstring msg;
        int idx = 0;
 
-       snprintf(msg, len, "NT code %08x", nt_code);
+       pstrcpy(msg, "Unknown NT error");
 
         nt_code &= 0xFFFF;
 
@@ -533,19 +533,11 @@ void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len)
        {
                if (nt_errs[idx].nt_errcode == nt_code)
                {
-                       safe_strcpy(msg, nt_errs[idx].nt_errstr, len);
-                       return;
+                       pstrcpy(msg, nt_errs[idx].nt_errstr);
+                       return msg;
                }
                idx++;
        }
-}
-
-/*****************************************************************************
- returns an NT error message.  not amazingly helpful, but better than a number.
- *****************************************************************************/
-char *get_nt_error_msg(uint32 nt_code)
-{
-       static pstring msg;
-       get_safe_nt_error_msg(nt_code, msg, sizeof(msg));
        return msg;
 }
+
index b5552d4cea18c35f7fe8b7efe4fa9ecdd049fe3b..b0b1188f3210e3c944653955acf7c3ef9596d7cc 100644 (file)
@@ -36,6 +36,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
        struct cli_state cli;
        struct in_addr ip;
 
+       *err_str = '\0';
+
        if(!resolve_name( remote_machine, &ip, 0x20)) {
                slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n",
                        remote_machine );
@@ -75,7 +77,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
         * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
         */
 
-       if (!cli_session_setup(&cli, global_myname, "", "", 0, "", 0, "")) {
+       if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
                slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",        
                        remote_machine, cli_errstr(&cli) );
                cli_shutdown(&cli);
index 29cf77dd55d9a9c7478b4a9869eb345a6ba05324..94b60d3ff0e3ed66f8bd9de9f46dc7db75306815 100644 (file)
@@ -29,38 +29,28 @@ initialises a password structure
 ****************************************************************************/
 void pwd_init(struct pwd_info *pwd)
 {
-       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);
-       ZERO_STRUCT(pwd->sess_key  );
-       pwd->nt_owf_len = 0;
+       memset((char *)pwd->password  , '\0', sizeof(pwd->password  ));
+       memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd));
+       memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd));
+       memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf));
+       memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf));
 
        pwd->null_pwd  = True; /* safest option... */
        pwd->cleartext = False;
        pwd->crypted   = False;
 }
 
-/****************************************************************************
-returns NULL password flag
-****************************************************************************/
-BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
-{
-       return pwd->null_pwd;
-}
-
 /****************************************************************************
 de-obfuscates a password
 ****************************************************************************/
-static void pwd_deobfuscate(const struct pwd_info *pwd)
+static void pwd_deobfuscate(struct pwd_info *pwd)
 {
 }
 
 /****************************************************************************
 obfuscates a password
 ****************************************************************************/
-static void pwd_obfuscate(const struct pwd_info *pwd)
+static void pwd_obfuscate(struct pwd_info *pwd)
 {
 }
 
@@ -71,59 +61,6 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
 {
 }
 
-/****************************************************************************
-compares two passwords.  hmm, not as trivial as expected.  hmm.
-****************************************************************************/
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
-{
-       pwd_deobfuscate(pwd1);
-       pwd_deobfuscate(pwd2);
-       if (pwd1->cleartext && pwd2->cleartext)
-       {
-               if (strequal(pwd1->password, pwd2->password))
-               {
-                       pwd_obfuscate(pwd1);
-                       pwd_obfuscate(pwd2);
-                       return True;
-               }
-       }
-       if (pwd1->null_pwd && pwd2->null_pwd)
-       {
-               pwd_obfuscate(pwd1);
-               pwd_obfuscate(pwd2);
-               return True;
-       }
-
-       if (!pwd1->null_pwd  && !pwd2->null_pwd &&
-           !pwd1->cleartext && !pwd2->cleartext)
-       {
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd compare: nt#\n"));
-               dump_data(100, pwd1->smb_nt_pwd, 16);
-               dump_data(100, pwd2->smb_nt_pwd, 16);
-#endif
-               if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
-               {
-                       pwd_obfuscate(pwd1);
-                       pwd_obfuscate(pwd2);
-                       return True;
-               }
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd compare: lm#\n"));
-               dump_data(100, pwd1->smb_lm_pwd, 16);
-               dump_data(100, pwd2->smb_lm_pwd, 16);
-#endif
-               if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
-               {
-                       pwd_obfuscate(pwd1);
-                       pwd_obfuscate(pwd2);
-                       return True;
-               }
-       }
-       pwd_obfuscate(pwd1);
-       pwd_obfuscate(pwd2);
-       return False;
-}
 /****************************************************************************
 reads a password
 ****************************************************************************/
@@ -169,6 +106,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
 {
        pwd_init(pwd);
        fstrcpy(pwd->password, clr);
+       unix_to_dos(pwd->password,True);
        pwd->cleartext = True;
        pwd->null_pwd  = False;
        pwd->crypted   = False;
@@ -185,6 +123,7 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
        if (pwd->cleartext)
        {
                fstrcpy(clr, pwd->password);
+               dos_to_unix(clr, True);
        }
        else
        {
@@ -206,7 +145,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
        }
        else
        {
-               bzero(pwd->smb_lm_pwd, 16);
+               memset((char *)pwd->smb_lm_pwd, '\0', 16);
        }
 
        if (nt_pwd)
@@ -215,7 +154,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
        }
        else
        {
-               bzero(pwd->smb_nt_pwd, 16);
+               memset((char *)pwd->smb_nt_pwd, '\0', 16);
        }
 
        pwd->null_pwd  = False;
@@ -228,7 +167,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
 /****************************************************************************
  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(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
 {
        pwd_deobfuscate(pwd);
        if (lm_pwd != NULL)
@@ -247,9 +186,14 @@ void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd
  ****************************************************************************/
 void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
 {
+       pstring dos_passwd;
+
        pwd_init(pwd);
 
-       nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
+       pstrcpy(dos_passwd, clr);
+       unix_to_dos(dos_passwd, True);
+
+       nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
        pwd->null_pwd  = False;
        pwd->cleartext = False;
        pwd->crypted = False;
@@ -260,109 +204,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)
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
 {
-       uchar kr[16];
-
-       DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
-               user, server, domain));
-
        pwd_deobfuscate(pwd);
 
-       SMBgenclientchals(pwd->lm_cli_chal,
-                         pwd->nt_cli_chal,
-                         &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);
-       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);
-       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;
-
-       SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key);
-
-#if DEBUG_PASSWORD
-#endif
-
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("server cryptkey: "));
-       dump_data(100, srv_key, 8);
-
-       DEBUG(100,("client lmv2 cryptkey: "));
-       dump_data(100, pwd->lm_cli_chal, 8);
-
-       DEBUG(100,("client ntv2 cryptkey: "));
-       dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
-
-       DEBUG(100,("ntv2_owf_passwd: "));
-       dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
-       DEBUG(100,("nt_sess_pwd: "));
-       dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
-
-       DEBUG(100,("lmv2_owf_passwd: "));
-       dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
-       DEBUG(100,("lm_sess_pwd: "));
-       dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
-
-       DEBUG(100,("session key:\n"));
-       dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
+       DEBUG(100,("client cryptkey: "));
+       dump_data(100, (char *)cryptkey, 8);
 #endif
-       pwd->crypted = True;
 
-       pwd_obfuscate(pwd);
-}
+       SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
 
-/****************************************************************************
- makes lm and nt OWF crypts
- ****************************************************************************/
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
-{
-       if (pwd->null_pwd)
-       {
 #ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
+       DEBUG(100,("nt_owf_passwd: "));
+       dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
+       DEBUG(100,("nt_sess_pwd: "));
+       dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
 #endif
-               pwd->nt_owf_len = 0;
-               return;
-       }
-       pwd_deobfuscate(pwd);
 
-       /* generate 24-byte hashes */
        SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
-       SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
-       pwd->nt_owf_len = 24;
-
-       SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key);
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("client cryptkey: "));
-       dump_data(100, cryptkey, 8);
-
-       DEBUG(100,("nt_owf_passwd: "));
-       dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
-       DEBUG(100,("nt_sess_pwd: "));
-       dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
-
        DEBUG(100,("lm_owf_passwd: "));
-       dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+       dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
        DEBUG(100,("lm_sess_pwd: "));
-       dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
-
-       DEBUG(100,("session key:\n"));
-       dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
+       dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
 #endif
 
        pwd->crypted = True;
@@ -373,22 +239,8 @@ 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 *sess_key)
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
 {
-       if (pwd->null_pwd)
-       {
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
-#endif
-               if (nt_owf_len != NULL)
-               {
-                       *nt_owf_len = 0;
-               }
-               return;
-       }
-               
        pwd_deobfuscate(pwd);
        if (lm_owf != NULL)
        {
@@ -396,16 +248,7 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
        }
        if (nt_owf != NULL)
        {
-               memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
-       }
-       if (sess_key != NULL)
-       {
-               memcpy(sess_key, pwd->sess_key, 16);
-       }
-       if (nt_owf_len != NULL)
-       {
-               *nt_owf_len = pwd->nt_owf_len;
+               memcpy(nt_owf, pwd->smb_nt_owf, 24);
        }
        pwd_obfuscate(pwd);
 }
-
index e60b93d6a29c1b171cea919bd521ea19796c9dcf..d0e1c6e85fb00d0c91c0af57f5f1d74dc018f04e 100644 (file)
@@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw)
        permute(out, rl, perm6, 64);
 }
 
-static void str_to_key(const uchar *str, uchar *key)
+static void str_to_key(unsigned char *str,unsigned char *key)
 {
        int i;
 
@@ -277,7 +277,7 @@ static void str_to_key(const uchar *str, uchar *key)
 }
 
 
-void smbhash(unsigned char *out, const uchar *in, const uchar *key, int forw)
+static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
 {
        int i;
        char outb[64];
@@ -365,10 +365,6 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
   unsigned char index_j = 0;
   unsigned char j = 0;
   int ind;
-  int len = 0;
-  if (val == 1) len = 516;
-  if (val == 0) len = 16;
-  if (val == 2) len = 68;
 
   for (ind = 0; ind < 256; ind++)
   {
@@ -385,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
      s_box[ind] = s_box[j];
      s_box[j] = tc;
   }
-  for( ind = 0; ind < len; ind++)
+  for( ind = 0; ind < (val ? 516 : 16); ind++)
   {
     unsigned char tc;
     unsigned char t;
@@ -401,16 +397,3 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
     data[ind] = data[ind] ^ s_box[t];
   }
 }
-
-void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw)
-{
-       unsigned char s[14];
-
-       s[0] = s[4] = s[8] = s[12] = (unsigned char)(rid & 0xFF);
-       s[1] = s[5] = s[9] = s[13] = (unsigned char)((rid >> 8) & 0xFF);
-       s[2] = s[6] = s[10]        = (unsigned char)((rid >> 16) & 0xFF);
-       s[3] = s[7] = s[11]        = (unsigned char)((rid >> 24) & 0xFF);
-
-       smbhash(out, in, s, forw);
-       smbhash(out+8, in+8, s+7, forw);
-}
index 34e6f43975ed69b3a2a49427084fcf0884dd4d03..b927e193dd7485ad9c403ddb997af703f237bedd 100644 (file)
 
 extern int DEBUGLEVEL;
 
+#include "byteorder.h"
+
 /*
    This implements the X/Open SMB password encryption
    It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
    encrypted password into p24 */
-void SMBencrypt(uchar *pwrd, uchar *c8, uchar *p24)
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
 {
-       uchar p21[21];
+       uchar p14[15], p21[21];
 
-       lm_owf_gen(pwrd, p21);
-       SMBOWFencrypt(p21, c8, p24);
+       memset(p21,'\0',21);
+       memset(p14,'\0',14);
+       StrnCpy((char *)p14,(char *)passwd,14);
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
-       dump_data(100, p21, 16);
-       dump_data(100, c8, 8);
-       dump_data(100, p24, 24);
-#endif
-}
+       strupper((char *)p14);
+       E_P16(p14, p21); 
 
-void SMBNTencrypt(uchar *pwrd, uchar *c8, uchar *p24)
-{
-       uchar p21[21];
-       memset(p21,'\0',21);
-       nt_owf_gen(pwrd, p21);    
        SMBOWFencrypt(p21, c8, p24);
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
-       dump_data(100, p21, 16);
-       dump_data(100, c8, 8);
-       dump_data(100, p24, 24);
+       DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
+       dump_data(100, (char *)p21, 16);
+       dump_data(100, (char *)c8, 8);
+       dump_data(100, (char *)p24, 24);
 #endif
 }
 
@@ -76,23 +67,7 @@ static int _my_wcslen(int16 *str)
  * format.
  */
  
-static int _my_mbstowcsupper(int16 *dst, const uchar *src, int len)
-{
-       int i;
-       int16 val;
-       for(i = 0; i < len; i++) {
-               val = toupper(*src);
-               SSVAL(dst,0,val);
-               dst++;
-               src++;
-               if(val == 0)
-                       break;
-       }
-       return i;
-}
-
-static int _my_mbstowcs(int16 *dst, const uchar *src, int len)
+static int _my_mbstowcs(int16 *dst, uchar *src, int len)
 {
        int i;
        int16 val;
@@ -112,17 +87,17 @@ static int _my_mbstowcs(int16 *dst, const uchar *src, int len)
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
  
-void E_md4hash(uchar *pwrd, uchar *p16)
+void E_md4hash(uchar *passwd, uchar *p16)
 {
        int len;
        int16 wpwd[129];
        
        /* Password cannot be longer than 128 characters */
-       len = strlen((char *)pwrd);
+       len = strlen((char *)passwd);
        if(len > 128)
                len = 128;
        /* Password must be converted to NT unicode */
-       _my_mbstowcs(wpwd, pwrd, len);
+       _my_mbstowcs(wpwd, passwd, len);
        wpwd[len] = 0; /* Ensure string is null terminated */
        /* Calculate length in bytes */
        len = _my_wcslen(wpwd) * sizeof(int16);
@@ -130,289 +105,98 @@ void E_md4hash(uchar *pwrd, uchar *p16)
        mdfour(p16, (unsigned char *)wpwd, len);
 }
 
-/* Does the LM owf of a user's password */
-void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16])
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
 {
-       char pwrd[15];
-
-       memset(pwrd,'\0',15);
-       if (pwd != NULL)
-       {
-               unistr2_to_ascii( pwrd, pwd, sizeof(pwrd)-1);
-       }
+       char passwd[130];
 
-       /* Mangle the passwords into Lanman format */
-       pwrd[14] = '\0';
-       strupper(pwrd);
-
-       /* Calculate the SMB (lanman) hash functions of the password */
+       memset(passwd,'\0',130);
+       safe_strcpy( passwd, pwd, sizeof(passwd)-1);
 
-       memset(p16, '\0', 16);
-       E_P16((uchar *) pwrd, (uchar *)p16);
+       /* Calculate the MD4 hash (NT compatible) of the password */
+       memset(nt_p16, '\0', 16);
+       E_md4hash((uchar *)passwd, nt_p16);
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
-       dump_data(120, pwrd, strlen(pwrd));
-       dump_data(100, p16, 16);
+       DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
+       dump_data(120, passwd, strlen(passwd));
+       dump_data(100, (char *)nt_p16, 16);
 #endif
-       /* clear out local copy of user's password (just being paranoid). */
-       bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does the LM owf of a user's password */
-void lm_owf_gen(const char *pwd, uchar p16[16])
-{
-       char pwrd[15];
-
-       memset(pwrd,'\0',15);
-       if (pwd != NULL)
-       {
-               safe_strcpy( pwrd, pwd, sizeof(pwrd)-1);
-       }
 
        /* Mangle the passwords into Lanman format */
-       pwrd[14] = '\0';
-       strupper(pwrd);
+       passwd[14] = '\0';
+       strupper(passwd);
 
        /* Calculate the SMB (lanman) hash functions of the password */
 
        memset(p16, '\0', 16);
-       E_P16((uchar *) pwrd, (uchar *)p16);
+       E_P16((uchar *) passwd, (uchar *)p16);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
-       dump_data(120, pwrd, strlen(pwrd));
-       dump_data(100, p16, 16);
-#endif
-       /* clear out local copy of user's password (just being paranoid). */
-       bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16])
-{
-       UNISTR2 pwrd;
-
-       memset(&pwrd,'\0',sizeof(pwrd));
-       if (pwd != NULL)
-       {
-               copy_unistr2(&pwrd, pwd);
-       }
-
-       /* Calculate the MD4 hash (NT compatible) of the password */
-       memset(nt_p16, '\0', 16);
-       mdfour(nt_p16, (unsigned char *)pwrd.buffer, pwrd.uni_str_len * 2);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("nt_owf_gen: pwd, nt#\n"));
-       dump_data(120, (const char*)pwrd.buffer, pwrd.uni_str_len * 2);
-       dump_data(100, nt_p16, 16);
-#endif
-       /* clear out local copy of user's password (just being paranoid). */
-       memset(&pwrd, 0, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_owf_gen(const char *pwd, uchar nt_p16[16])
-{
-       char pwrd[130];
-
-       memset(pwrd,'\0',130);
-       if (pwd != NULL)
-       {
-               safe_strcpy( pwrd, pwd, sizeof(pwrd)-1);
-       }
-
-       /* Calculate the MD4 hash (NT compatible) of the password */
-       memset(nt_p16, '\0', 16);
-       E_md4hash((uchar *)pwrd, nt_p16);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("nt_owf_gen: pwd, nt#\n"));
-       dump_data(120, pwrd, strlen(pwrd));
-       dump_data(100, nt_p16, 16);
+       dump_data(120, passwd, strlen(passwd));
+       dump_data(100, (char *)p16, 16);
 #endif
        /* clear out local copy of user's password (just being paranoid). */
-       bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's UNICODE password */
-void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16])
-{
-       nt_owf_genW(pwd, nt_p16);
-       lm_owf_genW(pwd, lm_p16);
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16])
-{
-       nt_owf_gen(pwd, nt_p16);
-       lm_owf_gen(pwd, lm_p16);
+       memset(passwd, '\0', sizeof(passwd));
 }
 
 /* Does the des encryption from the NT or LM MD4 hash. */
-void SMBOWFencrypt(uchar pwrd[16], uchar *c8, uchar p24[24])
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
 {
        uchar p21[21];
  
        memset(p21,'\0',21);
  
-       memcpy(p21, pwrd, 16);    
+       memcpy(p21, passwd, 16);    
        E_P24(p21, c8, p24);
 }
 
-void SMBOWFencrypt_ntv2(const uchar kr[16], 
-                               const uchar *srv_chal, int srv_chal_len,
-                               const uchar *cli_chal, int cli_chal_len,
-                               char resp_buf[16])
-{
-       HMACMD5Context ctx;
-
-       hmac_md5_init_limK_to_64(kr, 16, &ctx);
-       hmac_md5_update(srv_chal, srv_chal_len, &ctx);
-       hmac_md5_update(cli_chal, cli_chal_len, &ctx);
-       hmac_md5_final(resp_buf, &ctx);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
-       dump_data(100, srv_chal, srv_chal_len);
-       dump_data(100, cli_chal, cli_chal_len);
-       dump_data(100, resp_buf, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv2(const uchar kr[16], 
-                               const uchar *nt_resp, 
-                               char sess_key[16])
-{
-       HMACMD5Context ctx;
-
-       hmac_md5_init_limK_to_64(kr, 16, &ctx);
-       hmac_md5_update(nt_resp, 16, &ctx);
-       hmac_md5_final(sess_key, &ctx);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("SMBsesskeygen_ntv2:\n"));
-       dump_data(100, sess_key, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv1(const uchar kr[16], 
-                               const uchar *nt_resp, 
-                               char sess_key[16])
+/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
 {
-       mdfour(sess_key, kr, 16);
+       uchar p21[21];
+       memset(p21,'\0',21);
+       memcpy(p21, passwd, 8);    
+       memset(p21 + 8, 0xbd, 8);    
 
+       E_P24(p21, ntlmchalresp, p24);
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("SMBsesskeygen_ntv2:\n"));
-       dump_data(100, sess_key, 16);
+       DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
+       dump_data(100, (char *)p21, 21);
+       dump_data(100, (char *)ntlmchalresp, 8);
+       dump_data(100, (char *)p24, 24);
 #endif
 }
 
-void SMBgenclientchals(char *lm_cli_chal,
-                               char *nt_cli_chal, int *nt_cli_chal_len,
-                               const char *srv, const char *dom)
-{
-       NTTIME nt_time;
-       int srv_len = strlen(srv);
-       int dom_len = strlen(dom);
-       fstring server;
-       fstring domain;
-       fstrcpy(server, srv);
-       fstrcpy(domain, dom);
-       strupper(server);
-       strupper(domain);
-
-       generate_random_buffer(lm_cli_chal, 8, False);
-       unix_to_nt_time(&nt_time, time(NULL));
-
-       CVAL(nt_cli_chal,0) = 0x1;
-       CVAL(nt_cli_chal,1) = 0x1;
-       SSVAL(nt_cli_chal, 2, 0x0);
-       SIVAL(nt_cli_chal, 4, 0x0);
-       SIVAL(nt_cli_chal, 8, nt_time.low);
-       SIVAL(nt_cli_chal, 12, nt_time.high);
-       memcpy(nt_cli_chal+16, lm_cli_chal, 8);
-       /* fill in offset 24, size of structure, later */
-
-       *nt_cli_chal_len = 28;
-
-       SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
-       *nt_cli_chal_len += 2;
-       SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len*2);
-       *nt_cli_chal_len += 2;
-       ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), domain, dom_len*2);
-       *nt_cli_chal_len += dom_len*2;
-       *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4);
-
-       SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
-       *nt_cli_chal_len += 2;
-       SSVAL(nt_cli_chal, 30, srv_len*2);
-       *nt_cli_chal_len += 2;
-       ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), server, srv_len*2);
-       *nt_cli_chal_len += srv_len*2;
-
-       SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16);
-       SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15);
-
-       DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", server, domain));
-       dump_data(100, nt_cli_chal, *nt_cli_chal_len);
-}
-
-void ntv2_owf_gen(const uchar owf[16], 
-                               const char *user_n,
-                               const char *domain_n,
-                               uchar kr_buf[16])
-{
-       pstring user_u;
-       pstring dom_u;
-       HMACMD5Context ctx;
-
-       int user_l   = strlen(user_n  );
-       int domain_l = strlen(domain_n);
-
-       _my_mbstowcsupper((int16*)user_u, user_n  , user_l*2  );
-       _my_mbstowcsupper((int16*)dom_u , domain_n, domain_l*2);
-
-       hmac_md5_init_limK_to_64(owf, 16, &ctx);
-       hmac_md5_update(user_u, user_l*2, &ctx);
-       hmac_md5_update(dom_u, domain_l*2, &ctx);
-       hmac_md5_final(kr_buf, &ctx);
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("ntv2_owf_gen: user, domain, owfkey, kr\n"));
-       dump_data(100, user_u, user_l*2);
-       dump_data(100, dom_u, domain_l*2);
-       dump_data(100, owf, 16);
-       dump_data(100, kr_buf, 16);
-#endif
-}
-
-/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void NTLMSSPOWFencrypt(uchar pwrd[8], uchar *ntlmchalresp, uchar p24[24])
+/* Does the NT MD4 hash then des encryption. */
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
 {
        uchar p21[21];
  
        memset(p21,'\0',21);
-       memcpy(p21, pwrd, 8);    
-       memset(p21 + 8, 0xbd, 8);    
+       E_md4hash(passwd, p21);    
+       SMBOWFencrypt(p21, c8, p24);
 
-       E_P24(p21, ntlmchalresp, p24);
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
-       dump_data(100, p21, 21);
-       dump_data(100, ntlmchalresp, 8);
-       dump_data(100, p24, 24);
+       DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
+       dump_data(100, (char *)p21, 16);
+       dump_data(100, (char *)c8, 8);
+       dump_data(100, (char *)p24, 24);
 #endif
 }
 
-BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16], BOOL unicode)
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
 {
-       int new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
+       int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
 
        if (new_pw_len > 512)
        {
-               DEBUG(0,("make_oem_pwrd_hash: new password is too long.\n"));
+               DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
                return False;
        }
 
@@ -425,16 +209,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16
        generate_random_buffer((unsigned char *)data, 516, False);
        if (unicode)
        {
-               ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
+               /* Note that passwd should be in DOS oem character set. */
+               dos_struni2( &data[512 - new_pw_len], passwd, 512);
        }
        else
        {
-               fstrcpy( &data[512 - new_pw_len], pwrd);
+               /* Note that passwd should be in DOS oem character set. */
+               fstrcpy( &data[512 - new_pw_len], passwd);
        }
        SIVAL(data, 512, new_pw_len);
 
 #ifdef DEBUG_PASSWORD
-       DEBUG(100,("make_oem_pwrd_hash\n"));
+       DEBUG(100,("make_oem_passwd_hash\n"));
        dump_data(100, data, 516);
 #endif
        SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
@@ -442,138 +228,3 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16
        return True;
 }
 
-BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, const uchar *key)
-{
-       uchar bufhdr[8];
-       int datalen;
-
-       const uchar *keyptr = key;
-       const uchar *keyend = key + 16;
-
-       uchar *outbuf = (uchar *)out->buffer;
-       const uchar *inbuf = (const uchar *)in->buffer;
-       const uchar *inbufend;
-
-       smbhash(bufhdr, inbuf, keyptr, 0);
-       datalen = IVAL(bufhdr, 0);
-
-       if ((datalen > in->str_str_len) || (datalen > MAX_STRINGLEN))
-       {
-               DEBUG(0, ("nt_decrypt_string2: failed\n"));
-               return False;
-       }
-
-       out->str_max_len = out->str_str_len = datalen;
-       inbuf += 8;
-       inbufend = inbuf + datalen;
-
-       while (inbuf < inbufend)
-       {
-               keyptr += 7;
-               if (keyptr + 7 > keyend)
-               {
-                       keyptr = (keyend - keyptr) + key;
-               }
-
-               smbhash(outbuf, inbuf, keyptr, 0);
-
-               inbuf += 8;
-               outbuf += 8;
-       }
-
-       return True;
-}
-
-/*******************************************************************
- creates a DCE/RPC bind authentication response
-
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
-
- ********************************************************************/
-void create_ntlmssp_resp(struct pwd_info *pwd,
-                               char *domain, char *user_name, char *my_name,
-                               uint32 ntlmssp_cli_flgs,
-                                prs_struct *auth_resp)
-{
-       RPC_AUTH_NTLMSSP_RESP     ntlmssp_resp;
-       unsigned char lm_owf[24];
-       unsigned char nt_owf[128];
-       size_t nt_owf_len;
-
-       pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len, NULL);
-                       
-       make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
-                                lm_owf, nt_owf, nt_owf_len,
-                                domain, user_name, my_name,
-                                ntlmssp_cli_flgs);
-
-       smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0);
-       mem_realloc_data(auth_resp->data, auth_resp->offset);
-}
-
-/***********************************************************
- decode a password buffer
-************************************************************/
-BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
-                       int new_pwrd_size, uint32 *new_pw_len)
-{
-       /* 
-        * The length of the new password is in the last 4 bytes of
-        * the data buffer.
-        */
-
-       (*new_pw_len) = IVAL(buffer, 512);
-
-#ifdef DEBUG_PASSWORD
-       dump_data(100, buffer, 516);
-#endif
-
-       if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1)
-       {
-               DEBUG(0,("check_oem_password: incorrect password length (%d).\n", (*new_pw_len)));
-               return False;
-       }
-
-       memcpy(new_pwrd, &buffer[512-(*new_pw_len)], (*new_pw_len));
-       new_pwrd[(*new_pw_len)] = '\0';
-
-       return True;
-}
-
-/***********************************************************
- encode a password buffer
-************************************************************/
-BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
-                       int new_pw_len, BOOL nt_pass_set)
-{
-       generate_random_buffer(buffer, 516, True);
-
-       if (nt_pass_set)
-       {
-               /*
-                * nt passwords are in unicode.  last char overwrites NULL
-                * in ascii_to_unibuf, so use SIVAL *afterwards*.
-                */
-               new_pw_len *= 2;
-               ascii_to_unibuf(&buffer[512-new_pw_len], new_pass, new_pw_len);
-       }
-       else
-       {
-               memcpy(&buffer[512-new_pw_len], new_pass, new_pw_len);
-       }
-
-       /* 
-        * The length of the new password is in the last 4 bytes of
-        * the data buffer.
-        */
-
-       SIVAL(buffer, 512, new_pw_len);
-
-#ifdef DEBUG_PASSWORD
-       dump_data(100, buffer, 516);
-#endif
-
-       return True;
-}
index 228eee5892af5596ef5d63efac71996795eca317..c2d8884d7384395cbd05577bc39e5f3f8b2b02f8 100644 (file)
@@ -143,70 +143,39 @@ struct
   {0xFF,"ERRCMD",NULL},
   {-1,NULL,NULL}};
 
-char *smb_err_msg(uint8 class, uint32 num)
-{
-       static pstring ret;
-       smb_safe_err_msg(class, num, ret, sizeof(ret));
-       return ret;
-}
-       
 
 /****************************************************************************
 return a SMB error string from a SMB buffer
 ****************************************************************************/
-BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len)
+char *smb_errstr(char *inbuf)
 {
-       int i,j;
-
-       for (i=0;err_classes[i].class;i++)
-       {
-               if (err_classes[i].code == class)
+  static pstring ret;
+  int class = CVAL(inbuf,smb_rcls);
+  int num = SVAL(inbuf,smb_err);
+  int i,j;
+
+  for (i=0;err_classes[i].class;i++)
+    if (err_classes[i].code == class)
+      {
+       if (err_classes[i].err_msgs)
+         {
+           err_code_struct *err = err_classes[i].err_msgs;
+           for (j=0;err[j].name;j++)
+             if (num == err[j].code)
                {
-                       err_code_struct *err = err_classes[i].err_msgs;
-                       if (err != NULL)
-                       {
-                               for (j=0;err[j].name;j++)
-                               {
-                                       if (num == err[j].code)
-                                       {
-                                               if (DEBUGLEVEL > 0)
-                                               {
-                                                       slprintf(ret, len - 1, "%s - %s (%s)",err_classes[i].class,
-                                                       err[j].name,err[j].message);
-                                               }
-                                               else
-                                               {
-                                                       slprintf(ret, len - 1, "%s - %s",err_classes[i].class,err[j].name);
-                                               }
-                                               return True;
-                                       }
-                               }
-                       }
-                       slprintf(ret, len - 1, "%s - %d",err_classes[i].class, num);
-                       return True;
+                 if (DEBUGLEVEL > 0)
+                   slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
+                           err[j].name,err[j].message);
+                 else
+                   slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
+                 return ret;
                }
+         }
 
-       }
-
-       slprintf(ret, len - 1, "Error: Unknown error (%d,%d)",class,num);
-       return False;
-}
-
-/****************************************************************************
-return a SMB error string from a SMB buffer
-****************************************************************************/
-BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len)
-{
-       return smb_safe_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err),
-                               msg, len);
-}
-
-/****************************************************************************
-return a SMB error string from a SMB buffer
-****************************************************************************/
-char *smb_errstr(char *inbuf)
-{
-       static fstring errmsg;
-       (void)smb_safe_errstr(inbuf, errmsg, sizeof(errmsg));
-       return errmsg;
+       slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
+       return ret;
+      }
+  
+  slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
+  return(ret);
 }
index fdc39d00407fe38b4fa2f0574e9ab45322609094..012d954e501533402bc5b53c350bb8a2d7d29590 100644 (file)
@@ -87,8 +87,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
         * fd. So we don't need to use map_lock_type here.
         */
        
-       return(conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,
-                                 lock_type));
+       return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type));
 }
 
 
@@ -114,8 +113,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
         lock_type, (double)offset, (double)count, fsp->fsp_name ));
 
   if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
-    ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
-                           map_lock_type(fsp,lock_type));
+    ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
+                    map_lock_type(fsp,lock_type));
 
   if (!ok) {
     *eclass = ERRDOS;
@@ -141,7 +140,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
         (double)offset, (double)count, fsp->fsp_name ));
 
   if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
-    ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
+    ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
    
   if (!ok) {
     *eclass = ERRDOS;
@@ -157,21 +156,26 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
 
 BOOL locking_init(int read_only)
 {
-  if (share_ops)
-    return True;
+       if (share_ops)
+               return True;
 
 #ifdef FAST_SHARE_MODES
-  share_ops = locking_shm_init(read_only);
+       share_ops = locking_shm_init(read_only);
+       if (!share_ops && read_only && (getuid() == 0)) {
+               /* this may be the first time the share modes code has
+                   been run. Initialise it now by running it read-write */
+               share_ops = locking_shm_init(0);
+       }
 #else
-  share_ops = locking_slow_init(read_only);
+       share_ops = locking_slow_init(read_only);
 #endif
 
-  if (!share_ops) {
-    DEBUG(0,("ERROR: Failed to initialise share modes!\n"));
-    return False;
-  }
+       if (!share_ops) {
+               DEBUG(0,("ERROR: Failed to initialise share modes\n"));
+               return False;
+       }
        
-  return True;
+       return True;
 }
 
 /*******************************************************************
@@ -242,7 +246,7 @@ static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_I
         (unsigned int)dev, (double)inode ));
   /* Delete the oplock info. */
   entry->op_port = 0;
-  entry->op_type = 0;
+  entry->op_type = NO_OPLOCK;
 }
 
 /*******************************************************************
@@ -259,14 +263,45 @@ BOOL remove_share_oplock(int token, files_struct *fsp)
  below.
 ********************************************************************/
 
+static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
+                                   void *param)
+{
+  DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
+        (unsigned int)dev, (double)inode ));
+  entry->op_type = LEVEL_II_OPLOCK;
+}
+
+/*******************************************************************
+ Downgrade a oplock type from exclusive to level II.
+********************************************************************/
+
+BOOL downgrade_share_oplock(int token, files_struct *fsp)
+{
+    return share_ops->mod_entry(token, fsp, downgrade_share_oplock_fn, NULL);
+}
+
+/*******************************************************************
+ Static function that actually does the work for the generic function
+ below.
+********************************************************************/
+
+struct mod_val {
+       int new_share_mode;
+       uint16 new_oplock;
+};
+
 static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, 
                                    void *param)
 {
-  int new_share_mode = *(int *)param;
-  DEBUG(10,("modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f\n",
-        entry->share_mode, new_share_mode, (unsigned int)dev, (double)inode ));
-  /* Change the share mode info. */
-  entry->share_mode = new_share_mode;
+       struct mod_val *mvp = (struct mod_val *)param;
+
+       DEBUG(10,("modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f\n",
+        entry->share_mode, mvp->new_share_mode, (unsigned int)dev, (double)inode ));
+       DEBUG(10,("modify_share_mode_fn: changing oplock state from %x to %x for entry dev=%x ino=%.0f\n",
+        entry->op_type, (int)mvp->new_oplock, (unsigned int)dev, (double)inode ));
+       /* Change the share mode info. */
+       entry->share_mode = mvp->new_share_mode;
+       entry->op_type = mvp->new_oplock;
 }
 
 /*******************************************************************
@@ -274,9 +309,14 @@ static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO
  Return False on fail, True on success.
 ********************************************************************/
 
-BOOL modify_share_mode(int token, files_struct *fsp, int new_mode)
+BOOL modify_share_mode(int token, files_struct *fsp, int new_mode, uint16 new_oplock)
 {
-       return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&new_mode);
+       struct mod_val mv;
+
+       mv.new_share_mode = new_mode;
+    mv.new_oplock = new_oplock;
+
+       return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&mv);
 }
 
 /*******************************************************************
index 375a8b7f109edbc5df849eb42b0702ef39b9f889..174ad73e97758d3788b1a6537a9ea53c303e0782 100644 (file)
@@ -80,6 +80,7 @@ static BOOL shm_stop_share_mode_mgmt(void)
 static BOOL shm_lock_share_entry(connection_struct *conn,
                                 SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
 {
+       *ptok = 0; /* For purify... */
        return shmops->lock_hash_entry(HASH_ENTRY(dev, inode));
 }
 
@@ -165,7 +166,7 @@ static int shm_get_share_modes(connection_struct *conn,
                  malloc(num_entries * sizeof(share_mode_entry));
     if(*old_shares == 0)
     {
-      DEBUG(0,("get_share_modes: malloc fail!\n"));
+      DEBUG(0,("get_share_modes: malloc fail for size 0x%x!\n", (unsigned int)(num_entries * sizeof(share_mode_entry))));
       return 0;
     }
   }
@@ -177,7 +178,7 @@ static int shm_get_share_modes(connection_struct *conn,
   entry_prev_p = entry_scanner_p;
   while(entry_scanner_p)
   {
-    int pid = entry_scanner_p->e.pid;
+    pid_t pid = entry_scanner_p->e.pid;
 
     if (pid && !process_exists(pid))
     {
@@ -209,7 +210,7 @@ static int shm_get_share_modes(connection_struct *conn,
         return 0;
       }
 
-      DEBUG(0,("get_share_modes: process %d no longer exists\n", pid));
+      DEBUG(0,("get_share_modes: process %d no longer exists\n", (int)pid));
 
       shmops->shm_free(shmops->addr2offset(delete_entry_p));
     } 
@@ -226,7 +227,7 @@ static int shm_get_share_modes(connection_struct *conn,
               sizeof(struct timeval));
        num_entries_copied++;
        DEBUG(5,("get_share_modes Read share mode 0x%X pid=%d\n", 
-               entry_scanner_p->e.share_mode, entry_scanner_p->e.pid));
+               entry_scanner_p->e.share_mode, (int)entry_scanner_p->e.pid));
        entry_prev_p = entry_scanner_p;
        entry_scanner_p = (shm_share_mode_entry *)
                            shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
@@ -270,7 +271,7 @@ static void shm_del_share_mode(int token, files_struct *fsp)
   shm_share_mode_entry *entry_scanner_p;
   shm_share_mode_entry *entry_prev_p;
   BOOL found = False;
-  int pid = getpid();
+  pid_t pid = getpid();
 
   dev = fsp->fd_ptr->dev;
   inode = fsp->fd_ptr->inode;
@@ -430,7 +431,7 @@ static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16
     /* We must create a share_mode_record */
     share_mode_record *new_mode_p = NULL;
     int new_offset = shmops->shm_alloc(sizeof(share_mode_record) +
-                                  strlen(fsp->fsp_name) + 1);
+                                  strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2);
     if(new_offset == 0) {
            DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n"));
            return False;
@@ -441,7 +442,9 @@ static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16
     new_mode_p->st_ino = inode;
     new_mode_p->num_share_mode_entries = 0;
     new_mode_p->share_mode_entries = 0;
-    pstrcpy(new_mode_p->file_name, fsp->fsp_name);
+    pstrcpy(new_mode_p->file_name, fsp->conn->connectpath);
+    pstrcat(new_mode_p->file_name, "/");
+    pstrcat(new_mode_p->file_name, fsp->fsp_name);
 
     /* Chain onto the start of the hash chain (in the hope we will be used first). */
     new_mode_p->next_offset = mode_array[hash_entry];
@@ -489,7 +492,7 @@ static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16
   file_scanner_p->num_share_mode_entries += 1;
 
   DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n",
-          fsp->fsp_name, fsp->share_mode, new_entry_p->e.pid));
+          fsp->fsp_name, fsp->share_mode, (int)new_entry_p->e.pid));
 
   return(True);
 }
@@ -510,7 +513,7 @@ static BOOL shm_mod_share_entry(int token, files_struct *fsp,
   share_mode_record *file_prev_p;
   shm_share_mode_entry *entry_scanner_p;
   BOOL found = False;
-  int pid = getpid();
+  pid_t pid = getpid();
 
   dev = fsp->fd_ptr->dev;
   inode = fsp->fd_ptr->inode;
@@ -689,12 +692,12 @@ struct share_ops *locking_shm_init(int ronly)
 {
        read_only = ronly;
 
-#ifdef HAVE_SYSV_IPC
+#ifdef USE_SYSV_IPC
        shmops = sysv_shm_open(read_only);
        if (shmops) return &share_ops;
 #endif
 
-#ifdef HAVE_SHARED_MMAP
+#ifdef USE_SHARED_MMAP
        shmops = smb_shm_open(read_only);
        if (shmops) return &share_ops;
 #endif
index 64bedca4ad27cd66464dd8e991fac9288e24503a..58673d2707936a4260f7fa46149947348e28cb6f 100644 (file)
@@ -118,7 +118,7 @@ static int delete_share_file(connection_struct *conn, char *fname )
     DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
   }
 
-  /* return to our previous privilage level */
+  /* return to our previous privilege level */
   unbecome_root(False);
 
   return 0;
@@ -177,7 +177,7 @@ static BOOL slow_lock_share_entry(connection_struct *conn,
 
        /* At this point we have an open fd to the share mode file. 
          Lock the first byte exclusively to signify a lock. */
-      if(conn->vfs_ops.lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
+      if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
       {
         DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
                   fname, strerror(errno)));   
@@ -210,7 +210,7 @@ static BOOL slow_lock_share_entry(connection_struct *conn,
 
   *ptok = (int)fd;
 
-  /* return to our previous privilage level */
+  /* return to our previous privilege level */
   unbecome_root(False);
 
   return ret;
@@ -254,7 +254,7 @@ static BOOL slow_unlock_share_entry(connection_struct *conn,
 
   /* token is the fd of the open share mode file. */
   /* Unlock the first byte. */
-  if(conn->vfs_ops.lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
+  if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
    { 
       DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
                       strerror(errno)));   
@@ -434,16 +434,16 @@ for share file %s\n", num_entries, fname));
 
   for( i = 0; i < num_entries; i++)
   {
-    int pid;
+    pid_t pid;
     char *p = base + (i*SMF_ENTRY_LENGTH);
 
-    pid = IVAL(p,SME_PID_OFFSET);
+    pid = (pid_t)IVAL(p,SME_PID_OFFSET);
 
     if(!process_exists(pid))
     {
       DEBUG(0,("get_share_modes: process %d no longer exists and \
 it left a share mode entry with mode 0x%X in share file %s\n",
-            pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
+            (int)pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
       continue;
     }
     share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
@@ -492,7 +492,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
     {
       char *p = base + (i*SMF_ENTRY_LENGTH);
 
-      SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
+      SIVAL(p,SME_PID_OFFSET,(uint32)share_array[i].pid);
       SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
       SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
       SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
@@ -513,8 +513,18 @@ mode file %s (%s)\n", fname, strerror(errno)));
       return 0;
     }
     /* Now truncate the file at this point. */
+#ifdef FTRUNCATE_NEEDS_ROOT
+    become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
     if(sys_ftruncate(fd, (SMB_OFF_T)newsize)!= 0)
     {
+#ifdef FTRUNCATE_NEEDS_ROOT
+      int saved_errno = errno;
+      unbecome_root(False);
+      errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
       DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
       if(*old_shares)
@@ -526,6 +536,10 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
     }
   }
 
+#ifdef FTRUNCATE_NEEDS_ROOT
+      unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(buf)
     free(buf);
 
@@ -547,7 +561,7 @@ static void slow_del_share_mode(int token, files_struct *fsp)
   int num_entries;
   int newsize;
   int i;
-  int pid;
+  pid_t pid;
   BOOL deleted = False;
   BOOL new_file;
 
@@ -608,7 +622,7 @@ for share file %s\n", num_entries, fname));
     if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || 
        (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
        (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || 
-       (IVAL(p,SME_PID_OFFSET) != pid))
+       (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
       continue;
 
     DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
@@ -665,14 +679,30 @@ mode file %s (%s)\n", fname, strerror(errno)));
   }
 
   /* Now truncate the file at this point. */
+#ifdef FTRUNCATE_NEEDS_ROOT
+  become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(sys_ftruncate(fd, (SMB_OFF_T)newsize) != 0)
   {
+#ifdef FTRUNCATE_NEEDS_ROOT
+    int saved_errno = errno;
+    unbecome_root(False);
+    errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
+
     DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
     if(buf)
       free(buf);
     return;
   }
+
+#ifdef FTRUNCATE_NEEDS_ROOT
+  unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
 }
   
 /*******************************************************************
@@ -682,7 +712,7 @@ static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16
 {
   pstring fname;
   int fd = (int)token;
-  int pid = (int)getpid();
+  pid_t pid = getpid();
   SMB_STRUCT_STAT sb;
   char *buf;
   int num_entries;
@@ -692,7 +722,7 @@ static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16
   share_name(fsp->conn, fsp->fd_ptr->dev,
                        fsp->fd_ptr->inode, fname);
 
-  if(fsp->conn->vfs_ops.fstat_file(fd, &sb) != 0)
+  if(sys_fstat(fd, &sb) != 0)
   {
     DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
                   fname));
@@ -759,15 +789,17 @@ deleting it.\n", fname));
   {
     /* New file - just use a single_entry. */
     if((buf = (char *)malloc(SMF_HEADER_LENGTH + 
-                  strlen(fsp->fsp_name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
+                  strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2 + SMF_ENTRY_LENGTH)) == NULL)
     {
       DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
       return False;
     }
     SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
     SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
-    SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + 1);
-    pstrcpy(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
+    SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2);
+    pstrcpy(buf + SMF_HEADER_LENGTH, fsp->conn->connectpath);
+    pstrcat(buf + SMF_HEADER_LENGTH, "/");
+    pstrcat(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
   }
 
   num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
@@ -776,7 +808,7 @@ deleting it.\n", fname));
   SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec);
   SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec);
   SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode);
-  SIVAL(p,SME_PID_OFFSET,pid);
+  SIVAL(p,SME_PID_OFFSET,(uint32)pid);
   SSVAL(p,SME_PORT_OFFSET,port);
   SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
 
@@ -806,8 +838,19 @@ deleting it (%s).\n",fname, strerror(errno)));
 
   /* Now truncate the file at this point - just for safety. */
 
+#ifdef FTRUNCATE_NEEDS_ROOT
+  become_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(sys_ftruncate(fd, (SMB_OFF_T)(header_size + (SMF_ENTRY_LENGTH*num_entries)))!= 0)
   {
+
+#ifdef FTRUNCATE_NEEDS_ROOT
+    int saved_errno = errno;
+    unbecome_root(False);
+    errno = saved_errno;
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
     DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
 mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries), 
                 strerror(errno)));
@@ -816,11 +859,15 @@ mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entr
     return False;
   }
 
+#ifdef FTRUNCATE_NEEDS_ROOT
+  unbecome_root(False);
+#endif /* FTRUNCATE_NEEDS_ROOT */
+
   if(buf)
     free(buf);
 
   DEBUG(3,("set_share_mode: Created share file %s with \
-mode 0x%X pid=%d\n",fname,fsp->share_mode,pid));
+mode 0x%X pid=%d\n",fname,fsp->share_mode,(int)pid));
 
   return True;
 }
@@ -840,7 +887,7 @@ static BOOL slow_mod_share_entry(int token, files_struct *fsp,
   int num_entries;
   int fsize;
   int i;
-  int pid;
+  pid_t pid;
   BOOL found = False;
   BOOL new_file;
   share_mode_entry entry;
@@ -898,7 +945,7 @@ for share file %s\n", num_entries, fname));
     if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) || 
        (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
        (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) || 
-       (IVAL(p,SME_PID_OFFSET) != pid))
+       (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
       continue;
 
     DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
@@ -909,12 +956,12 @@ from the share file %s\n", i, num_entries, fname));
      * the generic function with the given parameter.
      */
 
-    entry.pid = IVAL(p,SME_PID_OFFSET);
+    entry.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
     entry.op_port = SVAL(p,SME_PORT_OFFSET);
     entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
     entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
-    entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET)
-    entry.time.tv_sec = IVAL(p,SME_USEC_OFFSET);
+    entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
+    entry.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
 
     (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
 
@@ -922,12 +969,12 @@ from the share file %s\n", i, num_entries, fname));
      * Now copy any changes the function made back into the buffer.
      */
 
-    SIVAL(p,SME_PID_OFFSET, entry.pid)
+    SIVAL(p,SME_PID_OFFSET, (uint32)entry.pid);
     SSVAL(p,SME_PORT_OFFSET,entry.op_port);
     SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
     SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
-    SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec)
-    SIVAL(p,SME_USEC_OFFSET,entry.time.tv_sec);
+    SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec);
+    SIVAL(p,SME_USEC_OFFSET,entry.time.tv_usec);
 
     found = True;
     break;
@@ -968,7 +1015,7 @@ mode file %s (%s)\n", fname, strerror(errno)));
 
 /*******************************************************************
 call the specified function on each entry under management by the
-share ode system
+share mode system
 ********************************************************************/
 static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
 {
@@ -1030,12 +1077,11 @@ static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
                        SVAL(buf,SMF_FILENAME_LEN_OFFSET); 
                for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
                        char *p = base + (i*SMF_ENTRY_LENGTH);
-                       e.pid = IVAL(p,SME_PID_OFFSET);
+                       e.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
                        e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
                        e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
                        e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
                        e.op_port = SVAL(p,SME_PORT_OFFSET);
-                       e.pid = SVAL(p,SME_PID_OFFSET);
                        e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
 
                        if (process_exists(e.pid)) {
index 435c0d4c7894f59f9df69eee77ecb0f64e67966f..bf2802c9ec51265c6ccfcdf47a8be733dac34735 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 
 
-#ifdef HAVE_SHARED_MMAP
+#ifdef USE_SHARED_MMAP
 
 
 extern int DEBUGLEVEL;
index d4e814d26fb6e5d81b091d884c91e8c552588202..04a2e744608411c2ba3abfadf97f6967d938e717 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 
 
-#ifdef HAVE_SYSV_IPC
+#ifdef USE_SYSV_IPC
 
 extern int DEBUGLEVEL;
 
@@ -33,7 +33,11 @@ extern int DEBUGLEVEL;
 #define SHM_MAGIC 0x53484100
 #define SHM_VERSION 2
 
+#ifdef SHM_R
 #define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
+#else
+#define IPC_PERMS 0644
+#endif
 
 
 #ifdef SECURE_SEMAPHORES
@@ -320,7 +324,7 @@ static BOOL shm_free(int offset)
        shm_header_p->consistent = False;
        
        DEBUG(6,("shm_free : freeing %d bytes at offset %d\n",
-                header_p->size*CellSize,offset));
+                (int)(header_p->size*CellSize),(int)offset));
 
        /* zero the area being freed - this allows us to find bugs faster */
        memset(shm_offset2addr(offset), 0, header_p->size*CellSize);
@@ -524,6 +528,7 @@ static struct shmem_ops shmops = {
 /*******************************************************************
   open the shared memory
   ******************************************************************/
+
 struct shmem_ops *sysv_shm_open(int ronly)
 {
        BOOL other_processes;
@@ -531,7 +536,9 @@ struct shmem_ops *sysv_shm_open(int ronly)
        struct semid_ds sem_ds;
        union semun su;
        int i;
-       int pid;
+       pid_t pid;
+       struct passwd *root_pwd = sys_getpwuid((uid_t)0);
+       gid_t root_gid = root_pwd ? root_pwd->pw_gid : (gid_t)0;
 
        read_only = ronly;
 
@@ -589,15 +596,16 @@ struct shmem_ops *sysv_shm_open(int ronly)
        hash_size = sem_ds.sem_nsems-1;
 
        if (!read_only) {
-               if (sem_ds.sem_perm.cuid != 0 || sem_ds.sem_perm.cgid != 0) {
-                       DEBUG(0,("ERROR: root did not create the semaphore\n"));
+               if (sem_ds.sem_perm.cuid != 0 || ((sem_ds.sem_perm.cgid != root_gid) && (sem_ds.sem_perm.cgid != 0))) {
+                       DEBUG(0,("ERROR: root did not create the semaphore: semgid=%u, rootgid=%u\n",
+                  (unsigned int)sem_ds.sem_perm.cgid, (unsigned int)root_gid));
                        return NULL;
                }
 
                if (semctl(sem_id, 0, GETVAL, su) == 0 &&
-                   !process_exists((pid=semctl(sem_id, 0, GETPID, su)))) {
+                   !process_exists((pid=(pid_t)semctl(sem_id, 0, GETPID, su)))) {
                        DEBUG(0,("WARNING: clearing global IPC lock set by dead process %d\n",
-                                pid));
+                                (int)pid));
                        su.val = 1;
                        if (semctl(sem_id, 0, SETVAL, su) != 0) {
                                DEBUG(0,("ERROR: Failed to clear global lock. Error was %s\n",
@@ -620,9 +628,9 @@ struct shmem_ops *sysv_shm_open(int ronly)
 
        for (i=1;i<hash_size+1;i++) {
                if (semctl(sem_id, i, GETVAL, su) == 0 && 
-                   !process_exists((pid=semctl(sem_id, i, GETPID, su)))) {
+                   !process_exists((pid=(pid_t)semctl(sem_id, i, GETPID, su)))) {
                        DEBUG(1,("WARNING: clearing IPC lock %d set by dead process %d\n", 
-                                i, pid));
+                                i, (int)pid));
                        su.val = 1;
                        if (semctl(sem_id, i, SETVAL, su) != 0) {
                                DEBUG(0,("ERROR: Failed to clear IPC lock %d. Error was %s\n",
@@ -680,7 +688,7 @@ struct shmem_ops *sysv_shm_open(int ronly)
        }
 
        if (!read_only) {
-               if (shm_ds.shm_perm.cuid != 0 || shm_ds.shm_perm.cgid != 0) {
+               if (shm_ds.shm_perm.cuid != 0 || ((shm_ds.shm_perm.cgid != root_gid) && (shm_ds.shm_perm.cgid != 0))) {
                        DEBUG(0,("ERROR: root did not create the shmem\n"));
                        global_unlock();
                        return NULL;
index fbe83b02c86f19b37b6b0ab2f4c99f06c2267da8..7094d842b41126cfc575dd214ed3d6f7b132bbf0 100644 (file)
 
 extern int DEBUGLEVEL;
 extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
-extern DOM_SID global_member_sid;
 extern fstring global_myworkgroup;
-extern DOM_SID global_sid_S_1_5_20;
+extern pstring global_myname;
 
 /***************************************************************************
-lsa_reply_open_policy2
+ lsa_reply_open_policy2
  ***************************************************************************/
-static void lsa_reply_open_policy2(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy2(prs_struct *rdata)
 {
+       int i;
        LSA_R_OPEN_POL2 r_o;
 
        ZERO_STRUCT(r_o);
 
        /* set up the LSA QUERY INFO response */
 
+       for (i = 4; i < POL_HND_SIZE; i++)
+               r_o.pol.data[i] = i;
        r_o.status = 0x0;
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (!open_policy_hnd(&r_o.pol))
-       {
-               r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       /* store the response in the SMB stream */
+       if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
+               DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_open_pol2("", &r_o, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
 lsa_reply_open_policy
  ***************************************************************************/
-static void lsa_reply_open_policy(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy(prs_struct *rdata)
 {
+       int i;
        LSA_R_OPEN_POL r_o;
 
        ZERO_STRUCT(r_o);
 
        /* set up the LSA QUERY INFO response */
 
+       for (i = 4; i < POL_HND_SIZE; i++)
+               r_o.pol.data[i] = i;
        r_o.status = 0x0;
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (!open_policy_hnd(&r_o.pol))
-       {
-               r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       /* store the response in the SMB stream */
+       if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
+               DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_open_pol("", &r_o, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
-make_dom_query
+Init dom_query
  ***************************************************************************/
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+
+static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
 {
        fstring sid_str;
        int domlen = strlen(dom_name);
 
-       d_q->uni_dom_str_len = (domlen+1) * 2;
        d_q->uni_dom_max_len = domlen * 2;
+       d_q->uni_dom_str_len = domlen * 2;
 
        d_q->buffer_dom_name = domlen  != 0    ? 1 : 0; /* domain buffer pointer */
        d_q->buffer_dom_sid  = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
 
        /* this string is supposed to be character short */
-       make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
-       d_q->uni_domain_name.uni_max_len++;
+       init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
 
        sid_to_string(sid_str, dom_sid);
-       make_dom_sid2(&(d_q->dom_sid), dom_sid);
+       init_dom_sid2(&d_q->dom_sid, dom_sid);
 }
 
 /***************************************************************************
-lsa_reply_query_info
+ lsa_reply_enum_trust_dom
  ***************************************************************************/
+
 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
                                prs_struct *rdata,
                                uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
@@ -114,7 +119,7 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
        ZERO_STRUCT(r_e);
 
        /* set up the LSA QUERY INFO response */
-       make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
+       init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
              dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
 
        /* store the response in the SMB stream */
@@ -124,63 +129,53 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
 /***************************************************************************
 lsa_reply_query_info
  ***************************************************************************/
-static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
+
+static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
                                char *dom_name, DOM_SID *dom_sid)
 {
        LSA_R_QUERY_INFO r_q;
 
        ZERO_STRUCT(r_q);
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (r_q.status == 0x0 && !open_policy_hnd(&q_q->pol))
-       {
-               r_q.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-       else
-       {
-               /* set up the LSA QUERY INFO response */
+       /* set up the LSA QUERY INFO response */
 
-               r_q.undoc_buffer = 0x1; 
-               r_q.info_class = q_q->info_class;
+       r_q.undoc_buffer = 0x22000000; /* bizarre */
+       r_q.info_class = q_q->info_class;
 
-               make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+       init_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+
+       r_q.status = 0x0;
 
-               r_q.status = 0x0;
-       }
        /* store the response in the SMB stream */
-       lsa_io_r_query("", &r_q, rdata, 0);
-}
+       if(!lsa_io_r_query("", &r_q, rdata, 0)) {
+               DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
+               return False;
+       }
 
+       return True;
+}
 
 /***************************************************************************
-make_dom_ref - adds a domain if it's not already in, returns the index
- ***************************************************************************/
-static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
-                         
+ init_dom_ref - adds a domain if it's not already in, returns the index.
+***************************************************************************/
+
+static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
 {
        int num = 0;
        int len;
 
-       if (dom_name != NULL)
-       {
-               for (num = 0; num < ref->num_ref_doms_1; num++)
-               {
+       if (dom_name != NULL) {
+               for (num = 0; num < ref->num_ref_doms_1; num++) {
                        fstring domname;
-                       unistr2_to_ascii(domname, &ref->ref_dom[num].uni_dom_name, sizeof(domname)-1);
+                       fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
                        if (strequal(domname, dom_name))
-                       {       
                                return num;
-                       }
                }
-
-       }
-       else
-       {
+       } else {
                num = ref->num_ref_doms_1;
        }
 
-       if (num >= MAX_REF_DOMAINS)
-       {
+       if (num >= MAX_REF_DOMAINS) {
                /* index not found, already at maximum domain limit */
                return -1;
        }
@@ -190,95 +185,85 @@ static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
        ref->max_entries = MAX_REF_DOMAINS;
        ref->num_ref_doms_2 = num+1;
 
-       len = dom_name != NULL ? strlen(dom_name) : 0;
+       len = (dom_name != NULL) ? strlen(dom_name) : 0;
+       if(dom_name != NULL && len == 0)
+               len = 1;
 
-       make_uni_hdr(&(ref->hdr_ref_dom[num].hdr_dom_name), len);
+       init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
        ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
 
-       make_unistr2 (&(ref->ref_dom[num].uni_dom_name), dom_name, len);
-       make_dom_sid2(&(ref->ref_dom[num].ref_dom     ), dom_sid );
+       init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
+       init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
 
        return num;
 }
 
 /***************************************************************************
-make_lsa_rid2s
+ init_lsa_rid2s
  ***************************************************************************/
-static void make_lsa_rid2s(DOM_R_REF *ref,
-                               DOM_RID2 *rid2,
+
+static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
                                int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
                                uint32 *mapped_count)
 {
        int i;
        int total = 0;
-       (*mapped_count) = 0;
+       *mapped_count = 0;
 
        SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
-       for (i = 0; i < num_entries; i++)
-       {
-               uint32 status = 0x0;
-               DOM_SID find_sid;
+       for (i = 0; i < num_entries; i++) {
+               BOOL status = False;
+               DOM_SID dom_sid;
                DOM_SID sid;
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
-               fstring find_name;
-               char *dom_name = NULL;
+               pstring full_name;
+               fstring dom_name;
+               fstring user;
                uint8 sid_name_use = SID_NAME_UNKNOWN;
 
-               unistr2_to_ascii(find_name, &name[i], sizeof(find_name)-1);
-               dom_name = strdup(find_name);
+               pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
 
-               if (map_domain_name_to_sid(&sid, &dom_name))
-               {
-                       sid_name_use = SID_NAME_DOMAIN;
-                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
-               }
+               /*
+                * Try and split the name into a DOMAIN and
+                * user component.
+                */
 
-               if (lookup_name(find_name, &sid, &sid_name_use) == 0x0 &&
-                   sid_split_rid(&sid, &rid))
-               {
-                       if (map_domain_sid_to_name(&sid, find_name))
-                       {
-                               dom_idx = make_dom_ref(ref, find_name, &sid);
-                       }
-                       else
-                       {
-                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-                       }
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               split_domain_name(full_name, dom_name, user);
+
+               /*
+                * We only do anything with this name if we
+                * can map the Domain into a SID we know.
+                */
+
+               if (map_domain_name_to_sid(&dom_sid, dom_name)) {
+                       dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
+
+                       if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) 
+                               status = True;
                }
 
-               if (status == 0x0)
-               {
+               if (status)
                        (*mapped_count)++;
-               }
-               else
-               {
+               else {
                        dom_idx = -1;
                        rid = 0xffffffff;
                        sid_name_use = SID_NAME_UNKNOWN;
                }
 
-               make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+               init_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
                total++;
-
-               if (dom_name != NULL)
-               {
-                       free(dom_name);
-               }
        }
 }
 
 /***************************************************************************
-make_reply_lookup_names
+ init_reply_lookup_names
  ***************************************************************************/
-static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
-                               DOM_R_REF *ref, uint32 num_entries,
-                               DOM_RID2 *rid2, uint32 mapped_count)
+
+static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+                DOM_R_REF *ref, uint32 num_entries,
+                DOM_RID2 *rid2, uint32 mapped_count)
 {
        r_l->ptr_dom_ref  = 1;
        r_l->dom_ref      = ref;
@@ -291,84 +276,74 @@ static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
        r_l->mapped_count = mapped_count;
 
        if (mapped_count == 0)
-       {
                r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
        else
-       {
                r_l->status = 0x0;
-       }
 }
 
 /***************************************************************************
-make_lsa_trans_names
+ Init lsa_trans_names.
  ***************************************************************************/
-static void make_lsa_trans_names(DOM_R_REF *ref,
-                               LSA_TRANS_NAME_ENUM *trn,
-                               int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
-                               uint32 *mapped_count)
+
+static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
+                               int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS], uint32 *mapped_count)
 {
+       extern DOM_SID global_sid_S_1_5_0x20; /* BUILTIN sid. */
        int i;
        int total = 0;
-       (*mapped_count) = 0;
+       *mapped_count = 0;
 
        SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
-       for (i = 0; i < num_entries; i++)
-       {
-               uint32 status = 0x0;
+       for (i = 0; i < num_entries; i++) {
+               BOOL status = False;
                DOM_SID find_sid = sid[i].sid;
-               DOM_SID tmp_sid  = sid[i].sid;
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
                fstring name;
                fstring dom_name;
                uint8 sid_name_use = 0;
-               
-               memset(dom_name, 0, sizeof(dom_name));
-               memset(name    , 0, sizeof(name    ));
 
-               if (map_domain_sid_to_name(&find_sid, dom_name))
-               {
+               memset(dom_name, '\0', sizeof(dom_name));
+               memset(name, '\0', sizeof(name));
+
+               /*
+                * First, check to see if the SID is one of the well
+                * known ones (this includes our own domain SID).
+                * Next, check if the domain prefix is one of the
+                * well known ones. If so and the domain prefix was
+                * either BUILTIN or our own global sid, then lookup
+                * the RID as a user or group id and translate to
+                * a name.
+                */
+
+               if (map_domain_sid_to_name(&find_sid, dom_name)) {
                        sid_name_use = SID_NAME_DOMAIN;
-                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
-               }
-               else if (sid_split_rid         (&find_sid, &rid) &&
-                        map_domain_sid_to_name(&find_sid, dom_name))
-               {
+               } else if (sid_split_rid(&find_sid, &rid) && map_domain_sid_to_name(&find_sid, dom_name)) {
                        if (sid_equal(&find_sid, &global_sam_sid) ||
-                           sid_equal(&find_sid, &global_sid_S_1_5_20))
-                       {
-                               /* lkclXXXX REPLACE THIS FUNCTION WITH
-                                  samr_xxxx() routines
-                                */
-                               status = lookup_sid(&tmp_sid, name, &sid_name_use);
+                               sid_equal(&find_sid, &global_sid_S_1_5_0x20)) {
+                               status = lookup_local_rid(rid, name, &sid_name_use);
+                       } else  {
+                               status = lookup_known_rid(&find_sid, rid, name, &sid_name_use);
                        }
-                       else
-                       {
-                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-                       }
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
                }
 
-               dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+               DEBUG(10,("init_lsa_trans_names: adding domain '%s' sid %s to referenced list.\n",
+                               dom_name, name ));
 
-               if (status == 0x0)
-               {
-                       (*mapped_count)++;
-               }
-               else
-               {
-                       snprintf(name, sizeof(name), "%08x", rid);
-                       sid_name_use = SID_NAME_UNKNOWN;
+               dom_idx = init_dom_ref(ref, dom_name, &find_sid);
 
+               if(!status) {
+                       slprintf(name, sizeof(name)-1, "unix.%08x", rid);
+                       sid_name_use = SID_NAME_UNKNOWN;
                }
-               make_lsa_trans_name(&(trn->name    [total]),
-                                   &(trn->uni_name[total]),
-                                   sid_name_use, name, dom_idx);
+
+               DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to referenced list.\n", dom_name, name ));
+
+               (*mapped_count)++;
+
+               init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
+                                       sid_name_use, name, dom_idx);
                total++;
        }
 
@@ -378,11 +353,12 @@ static void make_lsa_trans_names(DOM_R_REF *ref,
 }
 
 /***************************************************************************
-make_reply_lookup_sids
+ Init_reply_lookup_sids.
  ***************************************************************************/
-static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
-                               DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
-                               uint32 mapped_count)
+
+static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+                DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+                uint32 mapped_count)
 {
        r_l->ptr_dom_ref  = 1;
        r_l->dom_ref      = ref;
@@ -390,20 +366,16 @@ static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
        r_l->mapped_count = mapped_count;
 
        if (mapped_count == 0)
-       {
                r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
        else
-       {
                r_l->status = 0x0;
-       }
 }
 
 /***************************************************************************
 lsa_reply_lookup_sids
  ***************************************************************************/
-static void lsa_reply_lookup_sids(prs_struct *rdata,
-                               DOM_SID2 *sid, int num_entries)
+
+static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
 {
        LSA_R_LOOKUP_SIDS r_l;
        DOM_R_REF ref;
@@ -415,18 +387,24 @@ static void lsa_reply_lookup_sids(prs_struct *rdata,
        ZERO_STRUCT(names);
 
        /* set up the LSA Lookup SIDs response */
-       make_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
-       make_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
+       init_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
+       init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
 
        /* store the response in the SMB stream */
-       lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+       if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
+               DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
 lsa_reply_lookup_names
  ***************************************************************************/
-static void lsa_reply_lookup_names(prs_struct *rdata,
-                               UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
+
+static BOOL lsa_reply_lookup_names(prs_struct *rdata,
+                UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
 {
        LSA_R_LOOKUP_NAMES r_l;
        DOM_R_REF ref;
@@ -435,20 +413,26 @@ static void lsa_reply_lookup_names(prs_struct *rdata,
 
        ZERO_STRUCT(r_l);
        ZERO_STRUCT(ref);
-       ZERO_STRUCT(rids);
+       ZERO_ARRAY(rids);
 
        /* set up the LSA Lookup RIDs response */
-       make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
-       make_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
+       init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+       init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
 
        /* store the response in the SMB stream */
-       lsa_io_r_lookup_names("", &r_l, rdata, 0);
+       if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
+               DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_open_policy
+ api_lsa_open_policy2
  ***************************************************************************/
-static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
+
+static BOOL api_lsa_open_policy2( uint16 vuid, prs_struct *data,
                              prs_struct *rdata )
 {
        LSA_Q_OPEN_POL2 q_o;
@@ -456,18 +440,24 @@ static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_o);
 
        /* grab the server, object attributes and desired access flag...*/
-       lsa_io_q_open_pol2("", &q_o, data, 0);
+       if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
+               DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
+               return False;
+       }
 
        /* lkclXXXX having decoded it, ignore all fields in the open policy! */
 
        /* return a 20 byte policy handle */
-       lsa_reply_open_policy2(rdata);
+       if(!lsa_reply_open_policy2(rdata))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_open_policy
  ***************************************************************************/
-static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_policy( uint16 vuid, prs_struct *data,
                              prs_struct *rdata )
 {
        LSA_Q_OPEN_POL q_o;
@@ -475,18 +465,24 @@ static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_o);
 
        /* grab the server, object attributes and desired access flag...*/
-       lsa_io_q_open_pol("", &q_o, data, 0);
+       if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
+               DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
+               return False;
+       }
 
        /* lkclXXXX having decoded it, ignore all fields in the open policy! */
 
        /* return a 20 byte policy handle */
-       lsa_reply_open_policy(rdata);
+       if(!lsa_reply_open_policy(rdata))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_enum_trust_dom
  ***************************************************************************/
-static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_enum_trust_dom( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        LSA_Q_ENUM_TRUST_DOM q_e;
@@ -498,12 +494,14 @@ static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  return status is always 0x0 */
        lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_query_info
  ***************************************************************************/
-static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_query_info( uint16 vuid, prs_struct *data,
                                 prs_struct *rdata )
 {
        LSA_Q_QUERY_INFO q_i;
@@ -514,119 +512,118 @@ static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_i);
 
        /* grab the info class and policy handle */
-       lsa_io_q_query("", &q_i, data, 0);
-
-       switch (q_i.info_class)
-       {
-               case 0x03:
-               {
-                       fstrcpy(name, global_myworkgroup);
-                       sid = &global_member_sid;
-                       break;
-               }
-               case 0x05:
-               {
-                       fstrcpy(name, global_sam_name);
-                       sid = &global_sam_sid;
-                       break;
-               }
-               default:
-               {
-                       DEBUG(5,("unknown info level in Lsa Query: %d\n",
-                                 q_i.info_class));
-                       break;
-               }
+       if(!lsa_io_q_query("", &q_i, data, 0)) {
+               DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
+               return False;
+       }
+
+       switch (q_i.info_class) {
+       case 0x03:
+               fstrcpy(name, global_myworkgroup);
+               sid = &global_sam_sid;
+               break;
+       case 0x05:
+               fstrcpy(name, global_myname);
+               sid = &global_sam_sid;
+               break;
+       default:
+               DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
+               break;
        }
 
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_query_info(&q_i, rdata, name, sid);
+       if(!lsa_reply_query_info(&q_i, rdata, name, sid))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_lookup_sids
+ api_lsa_lookup_sids
  ***************************************************************************/
-static void api_lsa_lookup_sids( rpcsrv_struct *p, prs_struct *data,
-                                 prs_struct *rdata )
+
+static BOOL api_lsa_lookup_sids( uint16 vuid, prs_struct *data, prs_struct *rdata )
 {
        LSA_Q_LOOKUP_SIDS q_l;
        ZERO_STRUCT(q_l);
 
        /* grab the info class and policy handle */
-       lsa_io_q_lookup_sids("", &q_l, data, 0);
+       if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
+               DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
+               return False;
+       }
 
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries);
+       if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_lookup_names
+ api_lsa_lookup_names
  ***************************************************************************/
-static void api_lsa_lookup_names( rpcsrv_struct *p, prs_struct *data,
-                                  prs_struct *rdata )
+
+static BOOL api_lsa_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata )
 {
        LSA_Q_LOOKUP_NAMES q_l;
        ZERO_STRUCT(q_l);
 
        /* grab the info class and policy handle */
-       lsa_io_q_lookup_names("", &q_l, data, 0);
+       if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
+               DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
+               return False;
+       }
 
        SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
 
-       lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
+       return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
 }
 
 /***************************************************************************
  api_lsa_close
  ***************************************************************************/
-static void api_lsa_close( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_close( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata)
 {
        LSA_R_CLOSE r_c;
-       LSA_Q_CLOSE q_c;
-
-       lsa_io_q_close("", &q_c, data, 0);
 
        ZERO_STRUCT(r_c);
 
-       r_c.status = 0x0;
-
-       /* find the connection policy handle. */
-       if (r_c.status == 0x0 && (find_policy_by_hnd(&(q_c.pol)) == -1))
-       {
-               r_c.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       if (r_c.status == 0x0)
-       {
-               close_policy_hnd(&(q_c.pol));
+       /* store the response in the SMB stream */
+       if (!lsa_io_r_close("", &r_c, rdata, 0)) {
+               DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_close("", &r_c, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
  api_lsa_open_secret
  ***************************************************************************/
-static void api_lsa_open_secret( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_secret( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata)
 {
        /* XXXX this is NOT good */
-       char *q = mem_data(&(rdata->data), rdata->offset);
-
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND);
-       q += 4;
-       
-       rdata->offset += 24;
+       size_t i;
+       uint32 dummy = 0;
+
+       for(i =0; i < 4; i++) {
+               if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+                       DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
+                               (int)i ));
+                       return False;
+               }
+       }
+
+       dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+               DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
@@ -648,7 +645,7 @@ static struct api_struct api_lsa_cmds[] =
 /***************************************************************************
  api_ntLsarpcTNP
  ***************************************************************************/
-BOOL api_ntlsa_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
 }
index 34ae6fd43c126b03cf35a9a57977f06d8159e925..758fac438657dd43dab4bc2acac14b7794617ef2 100644 (file)
@@ -501,9 +501,8 @@ int smb_mem_free(void *ptr,char *file,int line)
 static void mem_write_Index_info(int Index,FILE *outfile)
 {
   if (memory_blocks[Index].status != S_UNALLOCATED)
-    fprintf(outfile,"block %d file %s(%d) : ptr: %p size %d, alloc size %d, status %s\n",
+    fprintf(outfile,"block %d file %s(%d) : size %d, alloc size %d, status %s\n",
            Index,memory_blocks[Index].file,memory_blocks[Index].line,
-           memory_blocks[Index].pointer,
            memory_blocks[Index].present_size,
            memory_blocks[Index].allocated_size,
            status_to_str(memory_blocks[Index].status));
index eef281b2f91590e390d71fc80e99db65c57a9e5f..60e31e6d44295fb8fcc6de7dc7876fc791a4e526 100644 (file)
@@ -1,4 +1,4 @@
-#if  (defined(NOMEMMAN) && !defined(MEM_MAN_MAIN) && defined(HAVE_MALLOC_H))
+#if  (defined(NOMEMMAN) && !defined(MEM_MAN_MAIN))
 #include <malloc.h>
 #else
 
index 67e55ebd508b8e661fc7206457cac7fd7a2d3276..99e697b470507797de5175191c377b2c509e12b7 100644 (file)
@@ -52,7 +52,7 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_a
 #ifndef SYNC_DNS
 
 static int fd_in = -1, fd_out = -1;
-static int child_pid = -1;
+static pid_t child_pid = -1;
 static int in_dns;
 
 /* this is the structure that is passed between the parent and child */
@@ -147,7 +147,7 @@ void start_async_dns(void)
                fd_out = fd2[1];
                close(fd1[1]);
                close(fd2[0]);
-               DEBUG(0,("started asyncdns process %d\n", child_pid));
+               DEBUG(0,("started asyncdns process %d\n", (int)child_pid));
                return;
        }
 
index 1471254b4ea2b733bd35998fa2fb4a02d94eeeb9..533c06351f1e3c11555b095f6b81c02d9c43dcd8 100644 (file)
@@ -1,7 +1,7 @@
 /*
-   Unix SMB/NetBIOS implementation.
+   Unix SMB/Netbios implementation.
    Version 1.9.
-   NBT NetBIOS routines and daemon - version 2
+   NBT netbios routines and daemon - version 2
    Copyright (C) Andrew Tridgell 1994-1998
    
    This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,6 @@ int ClientNMB       = -1;
 int ClientDGRAM     = -1;
 int global_nmb_port = -1;
 
-extern pstring myhostname;
 static pstring host_file;
 extern pstring global_myname;
 extern fstring global_myworkgroup;
@@ -86,6 +85,8 @@ static void sig_term(int sig)
 /**************************************************************************** **
  catch a sighup
  **************************************************************************** */
+static VOLATILE SIG_ATOMIC_T reload_after_sighup = False;
+
 static void sig_hup(int sig)
 {
   BlockSignals( True, SIGHUP );
@@ -95,9 +96,8 @@ static void sig_hup(int sig)
   write_browse_list( 0, True );
 
   dump_all_namelists();
-  reload_services( True );
 
-  set_samba_nb_type();
+  reload_after_sighup = True;
 
   BlockSignals(False,SIGHUP);
 
@@ -184,6 +184,67 @@ static void expire_names_and_servers(time_t t)
   expire_workgroups_and_servers(t);
 } /* expire_names_and_servers */
 
+
+/************************************************************************** **
+reload the list of network interfaces
+ ************************************************************************** */
+static void reload_interfaces(time_t t)
+{
+       static time_t lastt;
+       int n;
+       struct subnet_record *subrec;
+       extern BOOL rescan_listen_set;
+
+       if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return;
+       lastt = t;
+
+       if (!interfaces_changed()) return;
+
+       /* the list of probed interfaces has changed, we may need to add/remove
+          some subnets */
+       load_interfaces();
+
+       /* find any interfaces that need adding */
+       for (n=iface_count() - 1; n >= 0; n--) {
+               struct interface *iface = get_interface(n);
+               for (subrec=subnetlist; subrec; subrec=subrec->next) {
+                       if (ip_equal(iface->ip, subrec->myip) &&
+                           ip_equal(iface->nmask, subrec->mask_ip)) break;
+               }
+               if (!subrec) {
+                       /* it wasn't found! add it */
+                       DEBUG(2,("Found new interface %s\n", 
+                                inet_ntoa(iface->ip)));
+                       subrec = make_normal_subnet(iface);
+                       if (subrec) register_my_workgroup_one_subnet(subrec);
+               }
+       }
+
+       /* find any interfaces that need deleting */
+       for (subrec=subnetlist; subrec; subrec=subrec->next) {
+               for (n=iface_count() - 1; n >= 0; n--) {
+                       struct interface *iface = get_interface(n);
+                       if (ip_equal(iface->ip, subrec->myip) &&
+                           ip_equal(iface->nmask, subrec->mask_ip)) break;
+               }
+               if (n == -1) {
+                       /* oops, an interface has disapeared. This is
+                        tricky, we don't dare actually free the
+                        interface as it could be being used, so
+                        instead we just wear the memory leak and
+                        remove it from the list of interfaces without
+                        freeing it */
+                       DEBUG(2,("Deleting dead interface %s\n", 
+                                inet_ntoa(subrec->myip)));
+                       close_subnet(subrec);
+               }
+       }
+       
+       rescan_listen_set = True;
+}
+
+
+
 /**************************************************************************** **
   reload the services file
  **************************************************************************** */
@@ -395,6 +456,20 @@ static void process(void)
      * regularly sync with any other DMBs we know about 
      */
     sync_all_dmbs(t);
+
+    /*
+     * Reload the services file if we got a sighup.
+     */
+
+    if(reload_after_sighup) {
+           reload_services( True );
+           reopen_logs();
+           reload_interfaces(0);
+           reload_after_sighup = False;
+    }
+
+    /* check for new network interfaces */
+    reload_interfaces(t);
   }
 } /* process */
 
@@ -412,11 +487,11 @@ static BOOL open_sockets(BOOL isdaemon, int port)
    */
 
   if ( isdaemon )
-    ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0);
+    ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
   else
     ClientNMB = 0;
   
-  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0);
+  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
 
   if ( ClientNMB == -1 )
     return( False );
@@ -446,7 +521,7 @@ static BOOL init_structs(void)
 
   if (! *global_myname)
   {
-    fstrcpy( global_myname, myhostname );
+    fstrcpy( global_myname, myhostname() );
     p = strchr( global_myname, '.' );
     if (p)
       *p = 0;
@@ -509,7 +584,7 @@ static BOOL init_structs(void)
     *p = 0;
   strlower( local_machine );
 
-  DEBUG( 5, ("NetBIOS name list:-\n") );
+  DEBUG( 5, ("Netbios name list:-\n") );
   for( n=0; my_netbios_names[n]; n++ )
     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
 
@@ -521,20 +596,21 @@ static BOOL init_structs(void)
  **************************************************************************** */
 static void usage(char *pname)
 {
-  DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
-
-  printf( "Usage: %s [-n name] [-D] [-p port] [-d debuglevel] ", pname );
-  printf( "[-l log basename]\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 [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
+  printf( "       [-n name] [-p port] [-s configuration file] [-i scope]\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-h                    Print usage\n" );
+  printf( "\t-V                    Print version\n" );
+  printf( "\t-H hosts file         Load a netbios hosts file\n" );
+  printf( "\t-d debuglevel         Set the debuglevel\n" );
   printf( "\t-l log basename.      Basename for log/debug files\n" );
-  printf( "\t-n netbiosname.       " );
-  printf( "the netbios name to advertise for this host\n");
-  printf( "\t-H hosts file         load a netbios hosts file\n" );
-  printf( "\t-a                    append to log file (default)\n" );
-  printf( "\t-o                    overwrite log file, don't append\n" );
+  printf( "\t-n netbiosname.       Primary netbios name\n" );
+  printf( "\t-p port               Listen on the specified port\n" );
+  printf( "\t-s configuration file Configuration file name\n" );
+  printf( "\t-i scope              NetBIOS scope\n" );
   printf( "\n");
 } /* usage */
 
@@ -583,6 +659,11 @@ static void usage(char *pname)
   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
 
+#if defined(SIGFPE)
+  /* we are never interested in SIGFPE */
+  BlockSignals(True,SIGFPE);
+#endif
+
   /* Setup the signals that allow the debug log level
      to by dynamically changed. */
 
@@ -590,16 +671,16 @@ static void usage(char *pname)
      SIGUSR1 and SIGUSR2 to do debug level changes. */
 #ifndef MEM_MAN
 #if defined(SIGUSR1)
-       CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
+  CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
 #endif /* SIGUSR1 */
 
 #if defined(SIGUSR2)
-       CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
+  CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
 #endif /* SIGUSR2 */
 #endif /* MEM_MAN */
 
   while( EOF != 
-         (opt = getopt( argc, argv, "aos:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:" )) )
+         (opt = getopt( argc, argv, "Vaos:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:" )) )
     {
       switch (opt)
         {
@@ -646,9 +727,14 @@ static void usage(char *pname)
           usage(argv[0]);
           exit(0);
           break;
+        case 'V':
+         printf( "Version %s\n", VERSION );
+          exit(0);
+          break;
         default:
           if( !is_a_socket(0) )
           {
+           DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
             usage(argv[0]);
             exit(0);
           }
@@ -658,15 +744,9 @@ static void usage(char *pname)
 
   reopen_logs();
 
-  DEBUG( 1, ( "NetBIOS nameserver version %s started.\n", VERSION ) );
+  DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
 
-  if( !get_myname( myhostname, NULL) )
-  {
-    DEBUG( 0, ( "Unable to get my hostname - exiting.\n" ) );
-    return -1;
-  }
-
   if ( !reload_services(False) )
     return(-1);
 
@@ -677,10 +757,13 @@ static void usage(char *pname)
 
   reload_services( True );
 
-       if (!init_myworkgroup())
-       {
-               exit(1);
-       }
+  fstrcpy( global_myworkgroup, lp_workgroup() );
+
+  if (strequal(global_myworkgroup,"*"))
+  {
+    DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
+    exit(1);
+  }
 
   set_samba_nb_type();
 
@@ -696,6 +779,14 @@ static void usage(char *pname)
     become_daemon();
   }
 
+#ifndef SYNC_DNS
+  /* Setup the async dns. We do it here so it doesn't have all the other
+     stuff initialised and thus chewing memory and sockets */
+  if(lp_we_are_a_wins_server()) {
+         start_async_dns();
+  }
+#endif
+
   if (!directory_exist(lp_lockdir(), NULL)) {
          mkdir(lp_lockdir(), 0755);
   }
index cbef1db4b7ee7ed25a2c63bbc16eeb322508f79a..ae809607dc61310df4e9c488dfb6183dd228bc75 100644 (file)
@@ -157,6 +157,16 @@ in workgroup %s on subnet %s\n",
      */
     become_domain_master_browser_bcast(work->work_group);
   }
+  else
+  {
+    /*
+     * Now we are a domain master on a broadcast subnet, we need to add
+     * the WORKGROUP<1b> name to the unicast subnet so that we can answer
+     * unicast requests sent to this name. This bug wasn't found for a while
+     * as it is strange to have a DMB without using WINS. JRA.
+     */
+    insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
+  }
 }
 
 /****************************************************************************
index 12ce00df4f2eb495942c654f67e393e8aa6f2ee2..10d22431e9178e4cb3b4af062ee60a1623e05831 100644 (file)
@@ -99,7 +99,7 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
     return( NULL );
     }
 
-  bzero( (char *)browc, sizeof( *browc ) );
+  memset( (char *)browc, '\0', sizeof( *browc ) );
   
   /* For a new lmb entry we want to sync with it after one minute. This
      will allow it time to send out a local announce and build its
index eafcc79c0aad8acf0ade6a6e137d55c3df081dfb..b177fb524e9876a20d1c7f0835f8d776458657bd 100644 (file)
@@ -32,7 +32,7 @@ extern pstring global_myname;
 extern fstring global_myworkgroup;
 
 /* This is our local master browser list database. */
-extern struct ubi_dlList lmb_browserlist[];
+extern ubi_dlList lmb_browserlist[];
 
 /****************************************************************************
 As a domain master browser, do a sync with a local master browser.
@@ -128,7 +128,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
     return;
   }
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf;
   CVAL(p,0) = ANN_MasterAnnouncement;
   p++;
@@ -324,7 +324,7 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
     putip((char *)&work->dmb_addr, &ipzero);
 
   /* Now initiate the node status request. */
-  bzero((char *)&nmbname, sizeof(nmbname));
+  memset((char *)&nmbname, '\0',sizeof(nmbname));
   nmbname.name[0] = '*';
 
   /* Put the workgroup name into the userdata so we know
@@ -549,7 +549,7 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
   for(i = 0; i < rrec->rdlength / 6; i++)
   {
     /* Initiate the node status requests. */
-    bzero((char *)&nmbname, sizeof(nmbname));
+    memset((char *)&nmbname, '\0', sizeof(nmbname));
     nmbname.name[0] = '*';
 
     putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
index 8f876eab0c531737fea94f560c1f178806f7e2ae..8e1605dbba9f15bdcf6a0b9f10964a12b9397bbf 100644 (file)
@@ -46,7 +46,7 @@ static void send_election_dgram(struct subnet_record *subrec, char *workgroup_na
   DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
        workgroup_name, subrec->subnet_name ));
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf;
   CVAL(p,0) = ANN_Election; /* Election opcode. */
   p++;
@@ -135,6 +135,9 @@ void check_master_browser_exists(time_t t)
   struct subnet_record *subrec;
   char *workgroup_name = global_myworkgroup;
 
+  if (!lastrun)
+    lastrun = t;
+
   if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
     return;
 
index 41aaebd9b1be97544c8428b593e6532276ba3317..b8be579779f9de425da407a480bec67ecdfa2977 100644 (file)
@@ -546,10 +546,11 @@ static void send_backup_list_response(struct subnet_record *subrec,
   char outbuf[1024];
   char *p, *countptr;
   unsigned int count = 0;
-  int len;
+#if 0
   struct server_record *servrec;
+#endif
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
 
   DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
           work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
@@ -572,9 +573,20 @@ static void send_backup_list_response(struct subnet_record *subrec,
   p = skip_string(p,1);
 
   /* Look for backup browsers in this workgroup. */
+
+#if 0
+  /* we don't currently send become_backup requests so we should never
+     send any other servers names out as backups for our
+     workgroup. That's why this is commented out (tridge) */
+
+  /*
+   * NB. Note that the struct work_record here is not neccessarily
+   * attached to the subnet *subrec.
+   */
+
   for (servrec = work->serverlist; servrec; servrec = servrec->next)
   { 
-    len = PTR_DIFF(p, outbuf);
+    int len = PTR_DIFF(p, outbuf);
     if((sizeof(outbuf) - len) < 16)
       break;
 
@@ -596,11 +608,10 @@ static void send_backup_list_response(struct subnet_record *subrec,
 
     p = skip_string(p,1);
   }
+#endif
 
   SCVAL(countptr, 0, count);
 
-  len = PTR_DIFF(p, outbuf);
-
   DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
           send_to_name->name, inet_ntoa(sendto_ip), count));
 
@@ -630,6 +641,7 @@ void process_get_backup_list_request(struct subnet_record *subrec,
   uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
   int name_type = dgram->dest_name.name_type;
   char *workgroup_name = dgram->dest_name.name;
+  struct subnet_record *search_subrec = subrec;
 
   DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
            nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
@@ -646,13 +658,19 @@ void process_get_backup_list_request(struct subnet_record *subrec,
     return;
   }
 
-  if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
+  if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
   {
     DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
-subnet %s.\n", workgroup_name, subrec->subnet_name));
+subnet %s.\n", workgroup_name, search_subrec->subnet_name));
     return;
   }
 
+  /* 
+   * If the packet was sent to WORKGROUP<1b> instead
+   * of WORKGROUP<1d> then it was unicast to us a domain master
+   * browser. Change search subrec to unicast.
+   */
+
   if(name_type == 0x1b)
   {
     /* We must be a domain master browser in order to
@@ -664,6 +682,8 @@ subnet %s.\n", workgroup_name, subrec->subnet_name));
 and I am not a domain master browser.\n", workgroup_name));
       return;
     }
+
+    search_subrec = unicast_subnet;
   }
   else if (name_type == 0x1d)
   {
index dd5a23e0b0dd9a2b7b804c159fbe3b05bbbaa2b1..7c46204445c20487e1ce19c940764be0622b460d 100644 (file)
@@ -176,8 +176,9 @@ void process_name_refresh_request(struct subnet_record *subrec,
        and send an error reply back.
      */
     DEBUG(0,("process_name_refresh_request: unicast name registration request \
-received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
+received for name %s from IP %s on subnet %s.\n",
           nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+    DEBUG(0,("Error - should be sent to WINS server\n"));
     
     send_name_registration_response(FMT_ERR, 0, p);
     return;
@@ -366,7 +367,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
            strequal(qname, namerec->name.name)))
       {
         /* Start with the name. */
-        bzero(buf,18);
+        memset(buf,'\0',18);
         slprintf(buf, 17, "%-15.15s",namerec->name.name);
         strupper(buf);
         
@@ -421,7 +422,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
   
   /* We don't send any stats as they could be used to attack
      the protocol. */
-  bzero(buf,46);
+  memset(buf,'\0',46);
   
   buf += 46;
   
index 64cb8ea9e93182d1db1802f244dc9c3f62df98a9..c36df21e7b0e17faf8bd21c4fe3fb6369cc042c4 100644 (file)
@@ -43,6 +43,47 @@ static void my_name_register_failed(struct subnet_record *subrec,
             nmb_namestr(nmbname), subrec->subnet_name));
 }
 
+
+/****************************************************************************
+  Add my workgroup and my given names to one subnet
+  Also add the magic Samba names.
+  **************************************************************************/
+void register_my_workgroup_one_subnet(struct subnet_record *subrec)
+{
+       int i;
+
+       struct work_record *work;
+
+       /* Create the workgroup on the subnet. */
+       if((work = create_workgroup_on_subnet(subrec, global_myworkgroup, 
+                                             PERMANENT_TTL)) == NULL) {
+               DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
+Exiting.\n", global_myworkgroup, subrec->subnet_name));
+               return;
+       }
+
+       /* Each subnet entry, except for the wins_server_subnet has
+           the magic Samba names. */
+       add_samba_names_to_subnet(subrec);
+
+       /* Register all our names including aliases. */
+       for (i=0; my_netbios_names[i]; i++) {
+               register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
+                             NULL,
+                             my_name_register_failed, NULL);
+               register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
+                             NULL,
+                             my_name_register_failed, NULL);
+               register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
+                             NULL,
+                             my_name_register_failed, NULL);
+       }
+       
+       /* Initiate election processing, register the workgroup names etc. */
+       initiate_myworkgroup_startup(subrec, work);
+}
+
+
 /****************************************************************************
   Add my workgroup and my given names to the subnet lists.
   Also add the magic Samba names.
@@ -51,38 +92,13 @@ static void my_name_register_failed(struct subnet_record *subrec,
 BOOL register_my_workgroup_and_names(void)
 {
   struct subnet_record *subrec;
-  struct work_record *work;
   int i;
 
-  for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+  for(subrec = FIRST_SUBNET; 
+      subrec; 
+      subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
   {
-    /* Create the workgroup on the subnet. */
-    if((work = create_workgroup_on_subnet(subrec, global_myworkgroup, PERMANENT_TTL)) == NULL)
-    {
-      DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
-Exiting.\n", global_myworkgroup, subrec->subnet_name));
-      return False;
-    }
-
-    /* Each subnet entry, except for the wins_server_subnet has the magic Samba names. */
-    add_samba_names_to_subnet(subrec);
-
-    /* Register all our names including aliases. */
-    for (i=0; my_netbios_names[i]; i++) 
-    {
-      register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
-                    NULL,
-                    my_name_register_failed, NULL);
-      register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
-                    NULL,
-                    my_name_register_failed, NULL);
-      register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
-                    NULL,
-                    my_name_register_failed, NULL);
-    }
-
-    /* Initiate election processing, register the workgroup names etc. */
-    initiate_myworkgroup_startup(subrec, work);
+         register_my_workgroup_one_subnet(subrec);
   }
 
   /* If we are not a WINS client, we still need to add the magic Samba
@@ -180,6 +196,10 @@ void refresh_my_names(time_t t)
   {
     struct name_record *namerec;
          
+    /* B nodes don't send out name refresh requests, see RFC 1001, 15.5.1 */
+    if (subrec != unicast_subnet)
+      continue;
+          
     for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
          namerec;
          namerec = (struct name_record *)ubi_trNext( namerec ) )
index 0bc5fd875a7a42861eb91a25cb9a4cc1772bebc4..dbb8be1f2d5a4475e81bb27cde417d582581b721 100644 (file)
@@ -42,8 +42,6 @@ void set_samba_nb_type(void)
     samba_nb_type = NB_MFLAG;               /* samba is a 'hybrid' node type. */
   else
     samba_nb_type = NB_BFLAG;           /* samba is broadcast-only node type. */
-
-       DEBUG(10,("set_samba_nb_type: %x\n", samba_nb_type));
   } /* set_samba_nb_type */
 
 /* ************************************************************************** **
@@ -201,7 +199,7 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
     return( NULL );
   }
 
-  bzero( (char *)namerec, sizeof(*namerec) );
+  memset( (char *)namerec, '\0', sizeof(*namerec) );
   namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr) 
                                                * num_ips );
   if( NULL == namerec->data.ip )
index fae045882f24a8f22d691a38f312e5352d3b827d..8c4155484212a69864cf90bc5595440be55c9c03 100644 (file)
@@ -193,7 +193,7 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
     struct res_rec rrec;
     int i;
 
-    bzero((char *)&rrec, sizeof(struct res_rec));
+    memset((char *)&rrec, '\0', sizeof(struct res_rec));
 
     /* Fake up the needed res_rec just in case it's used. */
     rrec.rr_name = nmbname;
index 069e262987e086dc6dc24f4e2cef2e2726e4b503..1e819cc88f6b718a8dd132f33516066c7726c058 100644 (file)
@@ -54,6 +54,13 @@ static void register_name_response(struct subnet_record *subrec,
   /* Sanity check. Ensure that the answer name in the incoming packet is the
      same as the requested name in the outgoing packet. */
 
+  if(!question_name || !answer_name)
+  {
+    DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
+           question_name ? "question_name" : "answer_name" ));
+    return;
+  }
+
   if(!nmb_name_equal(question_name, answer_name))
   {
     DEBUG(0,("register_name_response: Answer name %s differs from question \
index 66c774a6e983a6f046927203ff2b43151a6d2208..0a7696a46631a1e26ada3206c8e37c96ca2eca80 100644 (file)
@@ -37,6 +37,9 @@ extern struct in_addr loopback_ip;
 
 static void queue_packet(struct packet_struct *packet);
 
+BOOL rescan_listen_set = False;
+
+
 /*******************************************************************
   The global packet linked-list. Incoming entries are 
   added to the end of this list. It is supposed to remain fairly 
@@ -90,6 +93,43 @@ void set_nb_flags(char *buf, uint16 nb_flags)
   *buf = '\0';
 }
 
+/***************************************************************************
+Dumps out the browse packet data.
+**************************************************************************/
+
+static void debug_browse_data(char *outbuf, int len)
+{
+  int i,j;
+
+  DEBUG( 4, ( "debug_browse_data():\n" ) );
+  for (i = 0; i < len; i+= 16)
+  {
+    DEBUGADD( 4, ( "%3x char ", i ) );
+
+    for (j = 0; j < 16; j++)
+    {
+      unsigned char x = outbuf[i+j];
+      if (x < 32 || x > 127) 
+        x = '.';
+           
+      if (i+j >= len)
+        break;
+      DEBUGADD( 4, ( "%c", x ) );
+    }
+
+    DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
+
+    for (j = 0; j < 16; j++)
+    {
+      if (i+j >= len) 
+        break;
+      DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
+    }
+
+    DEBUGADD( 4, ("\n") );
+  }
+}
+
 /***************************************************************************
   Generates the unique transaction identifier
 **************************************************************************/
@@ -143,7 +183,6 @@ static BOOL send_netbios_packet(struct packet_struct *p)
 
 static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
                                                             BOOL bcast,
-                                                            BOOL rec_des,
                                                             struct in_addr to_ip)
 {
   struct packet_struct *packet = NULL;
@@ -156,13 +195,13 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
     return NULL;
   }
     
-  bzero((char *)packet,sizeof(*packet));
+  memset((char *)packet,'\0',sizeof(*packet));
 
   nmb = &packet->packet.nmb;
 
   nmb->header.name_trn_id = generate_name_trn_id();
   nmb->header.response = False;
-  nmb->header.nm_flags.recursion_desired = rec_des;
+  nmb->header.nm_flags.recursion_desired = False;
   nmb->header.nm_flags.recursion_available = False;
   nmb->header.nm_flags.trunc = False;
   nmb->header.nm_flags.authoritative = False;
@@ -203,13 +242,17 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
     return False;
   }
 
-  bzero((char *)nmb->additional,sizeof(struct res_rec));
+  memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
 
   nmb->additional->rr_name  = nmb->question.question_name;
   nmb->additional->rr_type  = RR_TYPE_NB;
   nmb->additional->rr_class = RR_CLASS_IN;
 
-  nmb->additional->ttl = lp_max_ttl();
+  /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
+  if (nmb->header.nm_flags.bcast)
+    nmb->additional->ttl = PERMANENT_TTL;
+  else
+    nmb->additional->ttl = lp_max_ttl();
 
   nmb->additional->rdlength = 6;
 
@@ -431,12 +474,11 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
   struct packet_struct *p;
   struct response_record *rrec;
   BOOL bcast = (subrec == unicast_subnet) ? False : True;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
 
   if(assert_check_subnet(subrec))
     return NULL;
 
-  if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
+  if(( p = create_and_init_netbios_packet(nmbname, bcast, 
                      subrec->bcast_ip)) == NULL)
     return NULL;
 
@@ -481,7 +523,6 @@ struct response_record *queue_register_multihomed_name( struct subnet_record *su
   struct packet_struct *p;
   struct response_record *rrec;
   BOOL bcast = False;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
   BOOL ret;
      
   /* Sanity check. */
@@ -495,7 +536,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
   if(assert_check_subnet(subrec))
     return NULL;
      
-  if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
+  if(( p = create_and_init_netbios_packet(nmbname, bcast,
                              subrec->bcast_ip)) == NULL)
     return NULL;
 
@@ -542,14 +583,13 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
                           struct in_addr release_ip)
 {
   BOOL bcast = (subrec == unicast_subnet) ? False : True;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
   struct packet_struct *p;
   struct response_record *rrec;
 
   if(assert_check_subnet(subrec))
     return NULL;
 
-  if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
+  if(( p = create_and_init_netbios_packet(nmbname, bcast, 
                      subrec->bcast_ip)) == NULL)
     return NULL;
 
@@ -601,14 +641,13 @@ struct response_record *queue_refresh_name( struct subnet_record *subrec,
                           struct in_addr refresh_ip)
 {
   BOOL bcast = (subrec == unicast_subnet) ? False : True;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
   struct packet_struct *p;
   struct response_record *rrec;
 
   if(assert_check_subnet(subrec))
     return NULL;
 
-  if(( p = create_and_init_netbios_packet(&namerec->name, bcast,rec_des,
+  if(( p = create_and_init_netbios_packet(&namerec->name, bcast,
                      subrec->bcast_ip)) == NULL)
     return NULL;
 
@@ -650,7 +689,6 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
   struct packet_struct *p;
   struct response_record *rrec;
   BOOL bcast = True;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
 
   if ((subrec == unicast_subnet) || (subrec == wins_server_subnet))
     bcast = False;
@@ -658,7 +696,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
   if(assert_check_subnet(subrec))
     return NULL;
 
-  if(( p = create_and_init_netbios_packet(nmbname, bcast,rec_des,
+  if(( p = create_and_init_netbios_packet(nmbname, bcast,
                      subrec->bcast_ip)) == NULL)
     return NULL;
 
@@ -700,10 +738,8 @@ struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
   struct packet_struct *p;
   struct response_record *rrec;
   BOOL bcast = False;
-  BOOL rec_des = True;
 
-  if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
-               to_ip)) == NULL)
+  if(( p = create_and_init_netbios_packet(nmbname, bcast, to_ip)) == NULL)
     return NULL;
 
   if(initiate_name_query_packet_from_wins_server( p ) == False)
@@ -745,7 +781,6 @@ struct response_record *queue_node_status( struct subnet_record *subrec,
   struct packet_struct *p;
   struct response_record *rrec;
   BOOL bcast = False;
-  BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
 
   /* Sanity check. */
   if(subrec != unicast_subnet)
@@ -758,7 +793,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
   if(assert_check_subnet(subrec))
     return NULL;
 
-  if(( p = create_and_init_netbios_packet(nmbname, bcast,rec_des,
+  if(( p = create_and_init_netbios_packet(nmbname, bcast,
                              send_ip)) == NULL)
     return NULL;
 
@@ -895,10 +930,10 @@ for id %hu\n",
   nmb->header.nscount = 0;
   nmb->header.arcount = 0;
   
-  bzero((char*)&nmb->question,sizeof(nmb->question));
+  memset((char*)&nmb->question,'\0',sizeof(nmb->question));
   
   nmb->answers = &answers;
-  bzero((char*)nmb->answers,sizeof(*nmb->answers));
+  memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
   
   nmb->answers->rr_name  = orig_nmb->question.question_name;
   nmb->answers->rr_type  = orig_nmb->question.question_type;
@@ -1013,45 +1048,43 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scop
   {
     case ANN_HostAnnouncement:
     {
+      debug_browse_data(buf, len);
       process_host_announce(subrec, p, buf+1);
       break;
     }
     case ANN_DomainAnnouncement:
     {
+      debug_browse_data(buf, len);
       process_workgroup_announce(subrec, p, buf+1);
       break;
     }
     case ANN_LocalMasterAnnouncement:
     {
+      debug_browse_data(buf, len);
       process_local_master_announce(subrec, p, buf+1);
       break;
     }
     case ANN_AnnouncementRequest:
     {
+      debug_browse_data(buf, len);
       process_announce_request(subrec, p, buf+1);
       break;
     }
     case ANN_Election:
     {
+      debug_browse_data(buf, len);
       process_election(subrec, p, buf+1);
       break;
     }
     case ANN_GetBackupListReq:
     {
-
-      /* This is one occasion where we change a subnet that is
-        given to us. If the packet was sent to WORKGROUP<1b> instead
-        of WORKGROUP<1d> then it was unicast to us a domain master
-        browser. Change subrec to unicast.
-      */
-      if(dgram->dest_name.name_type == 0x1b)
-        subrec = unicast_subnet;
-
+      debug_browse_data(buf, len);
       process_get_backup_list_request(subrec, p, buf+1);
       break;
     }
     case ANN_GetBackupListResp:
     {
+      debug_browse_data(buf, len);
       /* We never send ANN_GetBackupListReq so we
          should never get these. */
       DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
@@ -1060,6 +1093,7 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
     }
     case ANN_ResetBrowserState:
     {
+      debug_browse_data(buf, len);
       process_reset_browser(subrec, p, buf+1);
       break;
     }
@@ -1069,6 +1103,7 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
          on the unicast subnet. */
       subrec = unicast_subnet;
 
+      debug_browse_data(buf, len);
       process_master_browser_announce(subrec, p, buf+1);
       break;
     }
@@ -1077,6 +1112,7 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
       /* 
        * We don't currently implement this. Log it just in case.
        */
+      debug_browse_data(buf, len);
       DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
 command ANN_BecomeBackup from %s IP %s to %s\n",
             subrec->subnet_name, nmb_namestr(&dgram->source_name),
@@ -1085,6 +1121,7 @@ command ANN_BecomeBackup from %s IP %s to %s\n",
     }
     default:
     {
+      debug_browse_data(buf, len);
       DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
 command code %d from %s IP %s to %s\n", 
             subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
@@ -1123,7 +1160,7 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scop
   {
     case ANN_HostAnnouncement:
     {
-      dump_data(4, buf, len);
+      debug_browse_data(buf, len);
       process_lm_host_announce(subrec, p, buf+1);
       break;
     }
@@ -1208,11 +1245,10 @@ static void process_dgram(struct packet_struct *p)
           nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
           inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
 
   if (len <= 0)
     return;
 
-  dump_data(100, buf2, len);
   /* Datagram packet received for the browser mailslot */
   if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
   {
@@ -1687,6 +1723,10 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
   }
 
   *listen_number = (count*2) + 2;
+
+  if (*ppset) free(*ppset);
+  if (*psock_array) free(*psock_array);
+
   *ppset = pset;
   *psock_array = sock_array;
  
@@ -1710,13 +1750,14 @@ BOOL listen_for_packets(BOOL run_election)
   int dns_fd;
 #endif
 
-  if(listen_set == NULL)
+  if(listen_set == NULL || rescan_listen_set)
   {
     if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
     {
       DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
       return True;
     }
+    rescan_listen_set = False;
   }
 
   memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
@@ -1749,7 +1790,7 @@ BOOL listen_for_packets(BOOL run_election)
   BlockSignals(False, SIGUSR2);
 #endif /* SIGUSR2 */
 
-  selrtn = sys_select(256,&fds,NULL, &timeout);
+  selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
 
   /* We can only take signals when we are in the select - block them again here. */
 
@@ -1864,7 +1905,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
   char *ptr,*p2;
   char tmp[4];
 
-  bzero((char *)&p,sizeof(p));
+  memset((char *)&p,'\0',sizeof(p));
 
   if(ismyip(dest_ip))
     loopback_this_packet = True;
@@ -1873,7 +1914,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
 
   /* DIRECT GROUP or UNIQUE datagram. */
   dgram->header.msg_type = unique ? 0x10 : 0x11; 
-  dgram->header.flags.node_type = M_NODE | 0x40;
+  dgram->header.flags.node_type = M_NODE;
   dgram->header.flags.first = True;
   dgram->header.flags.more = False;
   dgram->header.dgm_id = name_trn_id;
@@ -1920,7 +1961,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
                     nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
   DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
 
-  dump_data(4, buf, len);
+  debug_browse_data(buf, len);
 
   if(loopback_this_packet)
   {
index a515c2706d4c18893bd7ff16072135db7e61b789..279ab1c764fb05a6eb11581f30346b7948bbbe2d 100644 (file)
@@ -50,6 +50,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len,
   uint32 domainsidsize;
   char *getdc;
   char *uniuser; /* Unicode user name. */
+  pstring ascuser;
   char *unicomp; /* Unicode computer name. */
 
   memset(outbuf, 0, sizeof(outbuf));
@@ -117,7 +118,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
 
       q = align2(unicomp, buf);
 
-      q = skip_unibuf(q, buf+len-q);
+      q = skip_unicode_string(q, 1);
 
       ntversion = IVAL(q, 0);
       q += 4;
@@ -134,19 +135,17 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
 
       fstrcpy(reply_name,my_name);
       fstrcpy(q, reply_name);
+
       q = skip_string(q, 1); /* PDC name */
 
-      /* PDC and domain name */
-#if 0
-      if (strcmp(mailslot, NT_LOGON_MAILSLOT)==0)
-#endif
-      {
+      if (strcmp(mailslot, NT_LOGON_MAILSLOT)==0) {
         q = align2(q, buf);
 
-        q = ascii_to_unibuf(q, my_name, outbuf+sizeof(outbuf)-q-2);
-        q = ascii_to_unibuf(q, global_myworkgroup, outbuf+sizeof(outbuf)-q-2);
+        dos_PutUniCode(q, my_name, sizeof(pstring)); /* PDC name */
+        q = skip_unicode_string(q, 1); 
 
-       ntversion = 0x01;
+        dos_PutUniCode(q, global_myworkgroup,sizeof(pstring)); /* Domain name*/
+        q = skip_unicode_string(q, 1); 
 
         SIVAL(q, 0, ntversion);
         q += 4;
@@ -166,10 +165,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
 
       send_mailslot(True, getdc,
                   outbuf,PTR_DIFF(q,outbuf),
-                  my_name,
-                  0x0,
-                    dgram->source_name.name,
-                    dgram->source_name.name_type,
+                  dgram->dest_name.name,
+                  dgram->dest_name.name_type,
+                  dgram->source_name.name,
+                  dgram->source_name.name_type,
                   p->ip, *iface_ip(p->ip), p->port);  
       return;
     }
@@ -180,20 +179,13 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
 
       q += 2;
       unicomp = q;
-      uniuser = skip_unibuf(unicomp, buf+len-q);
-      getdc = skip_unibuf(uniuser, buf+len-q);
+      uniuser = skip_unicode_string(unicomp,1);
+      getdc = skip_unicode_string(uniuser,1);
       q = skip_string(getdc,1);
-      q += 4; /* skip Account Control Bits */
+      q += 4;
       domainsidsize = IVAL(q, 0);
       q += 4;
-
-       if (domainsidsize != 0)
-       {
-               q += domainsidsize;
-               q += 2;
-               q = align4(q, buf);
-       }
-
+      q += domainsidsize + 3;
       ntversion = IVAL(q, 0);
       q += 4;
       lmnttoken = SVAL(q, 0);
@@ -201,7 +193,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
       lm20token = SVAL(q, 0);
       q += 2;
 
-      DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %x\n", domainsidsize, ntversion));
+      DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
 
       /*
        * we respond regadless of whether the machine is in our password 
@@ -209,43 +201,28 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
        * Let's ignore the SID.
        */
 
+      pstrcpy(ascuser, dos_unistr(uniuser));
+      DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
+
       fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
       fstrcpy(reply_name+2,my_name); 
 
-       ntversion = 0x01;
-       lmnttoken = 0xffff;
-       lm20token = 0xffff;
-
-      if (DEBUGLVL(3))
-       {
-             fstring ascuser;
-             fstring asccomp;
-
-             unibuf_to_ascii(ascuser, uniuser, sizeof(ascuser)-1);
-             unibuf_to_ascii(asccomp, unicomp, sizeof(asccomp)-1);
-
-             DEBUGADD(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
-                         asccomp,inet_ntoa(p->ip), ascuser, reply_name,
-                         global_myworkgroup, SAMLOGON_R, lmnttoken));
-      }
+      DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
+              dos_unistr(unicomp),inet_ntoa(p->ip), ascuser, reply_name, global_myworkgroup,
+              SAMLOGON_R ,lmnttoken));
 
       /* Construct reply. */
 
       q = outbuf;
-       if (uniuser[0] == 0)
-       {
-               SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
-       }
-       else
-       {
-               SSVAL(q, 0, SAMLOGON_R);
-       }
+      SSVAL(q, 0, SAMLOGON_R);
       q += 2;
 
-      /* Logon server, trust account, domain */
-      q = ascii_to_unibuf(q, reply_name, outbuf+sizeof(outbuf)-q-2);
-      q = uni_strncpy(q, uniuser, outbuf+sizeof(outbuf)-q-2);
-      q = ascii_to_unibuf(q, lp_workgroup(), outbuf+sizeof(outbuf)-q-2);
+      dos_PutUniCode(q, reply_name,sizeof(pstring));
+      q = skip_unicode_string(q, 1);
+      unistrcpy(q, uniuser);
+      q = skip_unicode_string(q, 1); /* User name (workstation trust account) */
+      dos_PutUniCode(q, lp_workgroup(),sizeof(pstring));
+      q = skip_unicode_string(q, 1); /* Domain name. */
 
       SIVAL(q, 0, ntversion);
       q += 4;
@@ -258,10 +235,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
 
       send_mailslot(True, getdc,
                    outbuf,PTR_DIFF(q,outbuf),
-                  my_name,
-                  0x0,
-                    dgram->source_name.name,
-                    dgram->source_name.name_type,
+                   dgram->dest_name.name,
+                   dgram->dest_name.name_type,
+                   dgram->source_name.name,
+                   dgram->source_name.name_type,
                    p->ip, *iface_ip(p->ip), p->port);  
       break;
     }
index 0c698760bb6670b938a8912d5e347c91115176eb..fe294647732d492a03c3f5f31e16dea1178af636 100644 (file)
@@ -119,7 +119,7 @@ struct response_record *make_response_record( struct subnet_record *subrec,
     return NULL;
   }
 
-  bzero((char *)rrec, sizeof(*rrec));
+  memset((char *)rrec, '\0', sizeof(*rrec));
 
   rrec->response_id = nmb->header.name_trn_id;
 
index 38c8deafe72ecd75d7f0e0edf1793d8e6dcdc7a9..87115a1eb0de025908111394d3a472a2a604d3d4 100644 (file)
@@ -46,7 +46,7 @@ void send_browser_reset(int reset_type, char *to_name, int to_type, struct in_ad
   DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
        reset_type, to_name, to_type, inet_ntoa(to_ip) ));
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf;
   CVAL(p,0) = ANN_ResetBrowserState;
   p++;
@@ -73,7 +73,7 @@ void broadcast_announce_request(struct subnet_record *subrec, struct work_record
   DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
 to subnet %s\n", work->work_group, subrec->subnet_name));
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf;
   CVAL(p,0) = ANN_AnnouncementRequest;
   p++;
@@ -101,7 +101,7 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
   pstring outbuf;
   char *p;
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf+1;
 
   CVAL(outbuf,0) = announce_type;
@@ -142,7 +142,7 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
   pstring outbuf;
   char *p=outbuf;
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
 
   SSVAL(p,0,announce_type);
   SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
@@ -504,7 +504,7 @@ void announce_remote(time_t t)
   if (!*s)
     return;
 
-  comment = lp_serverstring();
+  comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
 
   for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) 
   {
@@ -587,7 +587,7 @@ for workgroup %s on subnet %s.\n", global_myworkgroup, FIRST_SUBNET->subnet_name
     return;
   } 
 
-  bzero(outbuf,sizeof(outbuf));
+  memset(outbuf,'\0',sizeof(outbuf));
   p = outbuf;
   CVAL(p,0) = ANN_MasterAnnouncement;
   p++;
index d30e8da64ce3705a5b22636e52d19d738f70cc96..41009bc68f0016fbcf899a4ac5c49fb05138629b 100644 (file)
@@ -156,7 +156,7 @@ workgroup %s. This is a bug.\n", name, work->work_group));
     return NULL;
   }
 
-  bzero((char *)servrec,sizeof(*servrec));
+  memset((char *)servrec,'\0',sizeof(*servrec));
  
   servrec->subnet = work->subnet;
  
@@ -399,7 +399,8 @@ void write_browse_list(time_t t, BOOL force_write)
     slprintf(tmp, sizeof(tmp)-1, "\"%s\"", my_netbios_names[i]);
     fprintf(fp, "%-25s ", tmp);
     fprintf(fp, "%08x ", stype);
-    slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", lp_serverstring());
+    slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", 
+            string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
     fprintf(fp, "%-30s", tmp);
     fprintf(fp, "\"%s\"\n", global_myworkgroup);
   }
index 527efa9dd83c0564f0be687eb350695d49bff1e1..37b50f85250b952a0d2af92868e36da546c47e44 100644 (file)
@@ -55,22 +55,7 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
 
 static void add_subnet(struct subnet_record *subrec)
 {
-  struct subnet_record *subrec2;
-
-  if (!subnetlist)
-  {
-    subnetlist = subrec;
-    subrec->prev = NULL;
-    subrec->next = NULL;
-    return;
-  }
-
-  for (subrec2 = subnetlist; subrec2->next; subrec2 = subrec2->next)
-    ;
-
-  subrec2->next = subrec;
-  subrec->next = NULL;
-  subrec->prev = subrec2;
+       DLIST_ADD(subnetlist, subrec);
 }
 
 /* ************************************************************************** **
@@ -96,19 +81,41 @@ static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
     Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
     Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
             memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
-            nmb_namestr(Iname), nmb_namestr(&NR->name), sizeof(struct nmb_name) );
+            nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
     }
 
   return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) ); 
   } /* namelist_entry_compare */
 
+
+/****************************************************************************
+stop listening on a subnet
+we don't free the record as we don't have proper reference counting for it
+yet and it may be in use by a response record
+  ****************************************************************************/
+void close_subnet(struct subnet_record *subrec)
+{
+       DLIST_REMOVE(subnetlist, subrec);
+
+       if (subrec->dgram_sock != -1) {
+               close(subrec->dgram_sock);
+               subrec->dgram_sock = -1;
+       }
+       if (subrec->nmb_sock != -1) {
+               close(subrec->nmb_sock);
+               subrec->nmb_sock = -1;
+       }
+}
+
+
+
 /****************************************************************************
   Create a subnet entry.
   ****************************************************************************/
 
 static struct subnet_record *make_subnet(char *name, enum subnet_type type,
-                                         struct in_addr myip, struct in_addr bcast_ip, 
-                                         struct in_addr mask_ip)
+                                        struct in_addr myip, struct in_addr bcast_ip, 
+                                        struct in_addr mask_ip)
 {
   struct subnet_record *subrec = NULL;
   int nmb_sock, dgram_sock;
@@ -130,7 +137,7 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
      * Fail the subnet creation if this fails.
      */
 
-    if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr)) == -1)
+    if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr,True)) == -1)
     {
       if( DEBUGLVL( 0 ) )
       {
@@ -142,7 +149,7 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
       return NULL;
     }
 
-    if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr)) == -1)
+    if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr,True)) == -1)
     {
       if( DEBUGLVL( 0 ) )
       {
@@ -170,7 +177,7 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
     return(NULL);
   }
   
-  bzero( (char *)subrec, sizeof(*subrec) );
+  memset( (char *)subrec, '\0', sizeof(*subrec) );
   (void)ubi_trInitTree( subrec->namelist,
                         namelist_entry_compare,
                         ubi_trOVERWRITE );
@@ -202,6 +209,23 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
   return subrec;
 }
 
+
+/****************************************************************************
+  Create a normal subnet
+**************************************************************************/
+struct subnet_record *make_normal_subnet(struct interface *iface)
+{
+       struct subnet_record *subrec;
+
+       subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
+                            iface->ip, iface->bcast, iface->nmask);
+       if (subrec) {
+               add_subnet(subrec);
+       }
+       return subrec;
+}
+
+
 /****************************************************************************
   Create subnet entries.
 **************************************************************************/
@@ -225,13 +249,9 @@ BOOL create_subnets(void)
 
   for (i = 0 ; i < num_interfaces; i++)
   {
-    struct subnet_record *subrec;
     struct interface *iface = get_interface(i);
 
-    if((subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
-                 iface->ip, iface->bcast,iface->nmask)) == NULL)
-      return False;
-    add_subnet(subrec);
+    if (!make_normal_subnet(iface)) return False;
   }
 
   /* 
index aab1e4349ca39b122dd76b964aead841f3a36f52..fb51be4d8f2306b2a67e96ecf1f1806dcad17516 100644 (file)
@@ -40,7 +40,7 @@ struct sync_record {
        fstring server;
        pstring fname;
        struct in_addr ip;
-       int pid;
+       pid_t pid;
 };
 
 /* a linked list of current sync connections */
@@ -92,7 +92,7 @@ static void sync_child(char *name, int nm_type,
                return;
        }
 
-       if (!cli_session_setup(&cli, local_machine, "", "", 1, "", 0, workgroup)) {
+       if (!cli_session_setup(&cli, "", "", 1, "", 0, workgroup)) {
                cli_shutdown(&cli);
                return;
        }
@@ -103,7 +103,7 @@ static void sync_child(char *name, int nm_type,
        }
 
        /* Fetch a workgroup list. */
-       cli_NetServerEnum(&cli, workgroup, 
+       cli_NetServerEnum(&cli, cli.server_domain?cli.server_domain:workgroup, 
                          local_type|SV_TYPE_DOMAIN_ENUM,
                          callback);
        
@@ -147,7 +147,7 @@ void sync_browse_lists(struct work_record *work,
 
        slprintf(s->fname, sizeof(pstring)-1,
                 "%s/sync.%d", lp_lockdir(), counter++);
-       string_sub(s->fname,"//", "/");
+       all_string_sub(s->fname,"//", "/", 0);
        
        DLIST_ADD(syncs, s);
 
index 43beb9acd85e32c9e0303e2a7a98e4abcd637901..1398ebd299a309be4ccda2dab2214cbdf6ec7224 100644 (file)
@@ -207,7 +207,7 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec,
           sizeof(struct packet_struct *)];
   struct userdata_struct *userdata = (struct userdata_struct *)ud;
 
-  bzero(ud, sizeof(ud));
+  memset(ud, '\0', sizeof(ud));
  
   userdata->copy_fn = wins_proxy_userdata_copy_fn;
   userdata->free_fn = wins_proxy_userdata_free_fn;
index 35ca5af62c4774ee5e3e9e360f1e769422e3b259..45e93351674289924ea277c96f72dda5b0c83e9c 100644 (file)
@@ -30,6 +30,41 @@ extern int DEBUGLEVEL;
 extern struct in_addr ipzero;
 
 
+/****************************************************************************
+possibly call the WINS hook external program when a WINS change is made
+*****************************************************************************/
+static void wins_hook(char *operation, struct name_record *namerec, int ttl)
+{
+       pstring command;
+       char *cmd = lp_wins_hook();
+       char *p;
+       int i;
+
+       if (!cmd || !*cmd) return;
+
+       for (p=namerec->name.name; *p; p++) {
+               if (!(isalnum((int)*p) || strchr("._-",*p))) {
+                       DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
+                       return;
+               }
+       }
+       
+       p = command;
+       p += slprintf(p, sizeof(command), "%s %s %s %02x %d", 
+                     cmd,
+                     operation, 
+                     namerec->name.name,
+                     namerec->name.name_type,
+                     ttl);
+
+       for (i=0;i<namerec->data.num_ips;i++) {
+               p += slprintf(p, sizeof(command) - (p-command), " %s", inet_ntoa(namerec->data.ip[i]));
+       }
+
+       DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
+       smbrun(command, NULL, False);
+}
+
 
 /****************************************************************************
 hash our interfaces and netbios names settings
@@ -147,11 +182,6 @@ BOOL initialise_wins(void)
 
   add_samba_names_to_subnet(wins_server_subnet);
 
-#ifndef SYNC_DNS
-  /* Setup the async dns. */
-  start_async_dns();
-#endif
-
   pstrcpy(fname,lp_lockdir());
   trim_string(fname,NULL,"/");
   pstrcat(fname,"/");
@@ -456,6 +486,7 @@ does not match group bit in WINS for this name.\n", nmb_namestr(question), group
      */
     update_name_ttl(namerec, ttl);
     send_wins_name_registration_response(0, ttl, p);
+    wins_hook("refresh", namerec, ttl);
     return;
   }
   else if(group)
@@ -636,7 +667,7 @@ void wins_process_name_registration_request(struct subnet_record *subrec,
   int ttl = get_ttl_from_packet(nmb);
   struct name_record *namerec = NULL;
   struct in_addr from_ip;
-  BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
+  BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
 
   putip((char *)&from_ip,&nmb->additional->rdata[2]);
 
@@ -715,7 +746,7 @@ to register name %s. Name already exists in WINS with source type %d.\n",
   if(!registering_group_name && (question->name_type == 0x1d))
   {
     DEBUG(3,("wins_process_name_registration_request: Ignoring request \
-to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
+to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
     send_wins_name_registration_response(0, ttl, p);
     return;
   }
@@ -785,6 +816,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
        */
       update_name_ttl(namerec, ttl);
       send_wins_name_registration_response(0, ttl, p);
+      wins_hook("refresh", namerec, ttl);
       return;
     }
   }
@@ -801,6 +833,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   {
     update_name_ttl( namerec, ttl );
     send_wins_name_registration_response( 0, ttl, p );
+    wins_hook("refresh", namerec, ttl);
     return;
   }
 
@@ -858,6 +891,9 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
 
   (void)add_name_to_subnet( subrec, question->name, question->name_type,
                             nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
+  if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+         wins_hook("add", namerec, ttl);
+  }
 
   send_wins_name_registration_response(0, ttl, p);
 }
@@ -916,6 +952,7 @@ a subsequent IP addess.\n", nmb_namestr(question_name) ));
     add_ip_to_name_record(namerec, from_ip);
   update_name_ttl(namerec, ttl);
   send_wins_name_registration_response(0, ttl, orig_reg_packet);
+  wins_hook("add", namerec, ttl);
 
   orig_reg_packet->locked = False;
   free_packet(orig_reg_packet);
@@ -1082,11 +1119,16 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
        * It's one of our names and one of our IP's. Ensure the IP is in the record and
        *  update the ttl.
        */
-      if(!find_ip_in_name_record(namerec, from_ip))
-        add_ip_to_name_record(namerec, from_ip);
-      update_name_ttl(namerec, ttl);
-      send_wins_name_registration_response(0, ttl, p);
-      return;
+           if(!find_ip_in_name_record(namerec, from_ip)) {
+                   add_ip_to_name_record(namerec, from_ip);
+                   wins_hook("add", namerec, ttl);
+           } else {
+                   wins_hook("refresh", namerec, ttl);
+           }
+
+           update_name_ttl(namerec, ttl);
+           send_wins_name_registration_response(0, ttl, p);
+           return;
     }
   }
 
@@ -1099,6 +1141,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   {
     update_name_ttl(namerec, ttl);
     send_wins_name_registration_response(0, ttl, p);
+    wins_hook("refresh", namerec, ttl);
     return;
   }
 
@@ -1158,6 +1201,10 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
   (void)add_name_to_subnet( subrec, question->name, question->name_type,
                             nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
 
+  if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
+         wins_hook("add", namerec, ttl);
+  }
+
   send_wins_name_registration_response(0, ttl, p);
 }
 
@@ -1253,7 +1300,7 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
   int ttl = 0;
   int i;
 
-  bzero(rdata,6);
+  memset(rdata,'\0',6);
 
   if(rcode == 0)
   {
@@ -1495,6 +1542,8 @@ release name %s as IP %s is not one of the known IP's for this name.\n",
   send_wins_name_release_response(0, p);
   remove_ip_from_name_record(namerec, from_ip);
 
+  wins_hook("delete", namerec, 0);
+
   /* 
    * Remove the name entirely if no IP addresses left.
    */
@@ -1552,7 +1601,7 @@ void wins_write_database(BOOL background)
   }
 
   slprintf(fname,sizeof(fname),"%s/%s", lp_lockdir(), WINS_LIST);
-  string_sub(fname,"//", "/");
+  all_string_sub(fname,"//", "/", 0);
   slprintf(fnamenew,sizeof(fnamenew),"%s.%u", fname, (unsigned int)getpid());
 
   if((fp = sys_fopen(fnamenew,"w")) == NULL)
index 0f66b140a818a768a4a6ddcc4dd5f28af37cf4b5..5514e78dc1c4088c0473bb3a87cd5accf019ef60 100644 (file)
@@ -43,26 +43,9 @@ int workgroup_count = 0; /* unique index key: one for each workgroup */
 
 static void add_workgroup(struct subnet_record *subrec, struct work_record *work)
 {
-  struct work_record *w2;
-
-  work->subnet = subrec;
-
-  if (!subrec->workgrouplist)
-  {
-    subrec->workgrouplist = work;
-    work->prev = NULL;
-    work->next = NULL;
-    return;
-  }
-  
-  for (w2 = subrec->workgrouplist; w2->next; w2 = w2->next)
-    ;
-  
-  w2->next = work;
-  work->next = NULL;
-  work->prev = w2;
-
-  subrec->work_changed = True;
+       work->subnet = subrec;
+       DLIST_ADD(subrec->workgrouplist, work);
+       subrec->work_changed = True;
 }
 
 /****************************************************************************
@@ -80,7 +63,7 @@ static struct work_record *create_workgroup(char *name, int ttl)
     DEBUG(0,("create_workgroup: malloc fail !\n"));
     return NULL;
   }
-  bzero((char *)work, sizeof(*work));
+  memset((char *)work, '\0', sizeof(*work));
  
   StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
   work->serverlist = NULL;
@@ -254,7 +237,8 @@ void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_reco
      if we are so configured. */
 
   if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
-      (subrec != wins_server_subnet) && lp_preferred_master())
+      (subrec != wins_server_subnet) && lp_preferred_master() &&
+      lp_local_master())
   {
     DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
 workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
@@ -283,7 +267,8 @@ workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
                    SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
    
     create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY,
-                PERMANENT_TTL, lp_serverstring());
+                              PERMANENT_TTL, 
+                              string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
     DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
 on subnet %s\n", name, subrec->subnet_name));
   }
index 82755d05a30d11c155a2bdf9c006f386e5084aa4..e24877e1241bb51f516dbf2c3ba341270cd2fb33 100644 (file)
@@ -116,21 +116,20 @@ typedef struct
   char *szLogFile;
   char *szConfigFile;
   char *szSMBPasswdFile;
-  char *szSMBPassGroupFile;
-  char *szSMBGroupFile;
-  char *szSMBAliasFile;
   char *szPasswordServer;
   char *szSocketOptions;
   char *szValidChars;
   char *szWorkGroup;
-  char *szTrustedDomains;
-  char *szTrustingDomains;
+  char *szDomainAdminGroup;
+  char *szDomainGuestGroup;
+  char *szDomainAdminUsers;
+  char *szDomainGuestUsers;
+  char *szDomainHostsallow; 
+  char *szDomainHostsdeny;
   char *szUsernameMap;
-  char *szAliasnameMap;
+#ifdef USING_GROUPNAME_MAP
   char *szGroupnameMap;
-  char *szBuiltinnameMap;
-  char *szBuiltinRidFile;
-  char *szNTusernameMap;
+#endif /* USING_GROUPNAME_MAP */
   char *szCharacterSet;
   char *szLogonScript;
   char *szLogonPath;
@@ -147,18 +146,18 @@ typedef struct
   char *szAnnounceVersion; /* This is initialised in init_globals */
   char *szNetbiosAliases;
   char *szDomainOtherSIDs;
+  char *szDomainGroups;
   char *szDriverFile;
   char *szNameResolveOrder;
-  char *szDfsMap;
-#ifdef WITH_LDAP
   char *szLdapServer;
   char *szLdapSuffix;
-  char *szLdapBindAs;
-  char *szLdapPasswdFile; 
-#endif /* WITH_LDAP */
+  char *szLdapFilter;
+  char *szLdapRoot;
+  char *szLdapRootPassword; 
   char *szPanicAction;
-  char *szNtForms;
-  char *szNtDriverFile;  
+  char *szAddUserScript;
+  char *szDelUserScript;
+  char *szWINSHook;
   int max_log_size;
   int mangled_stack;
   int max_xmit;
@@ -187,6 +186,8 @@ typedef struct
   int change_notify_timeout;
   int stat_cache_size;
   int map_to_guest;
+  int min_passwd_length;
+  int oplock_break_wait_time;
 #ifdef WITH_LDAP
   int ldap_port;
 #endif /* WITH_LDAP */
@@ -215,8 +216,6 @@ typedef struct
   BOOL bDomainLogons;
   BOOL bEncryptPasswords;
   BOOL bUpdateEncrypt;
-  BOOL bServerNTLMv2;
-  BOOL bClientNTLMv2;
   BOOL bStripDot;
   BOOL bNullPasswords;
   BOOL bLoadPrinters;
@@ -237,15 +236,14 @@ typedef struct
   BOOL bTimestampLogs;
   BOOL bNTSmbSupport;
   BOOL bNTPipeSupport;
+  BOOL bNTAclSupport;
   BOOL bStatCache;
   BOOL bKernelOplocks;
-#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
-  char *sMysqlDatabase;
-  char *sMysqlTable;
-  char *sMysqlUser;
-  char *sMysqlHost;
-  char *sMysqlPassFile;
-#endif
+  BOOL bAllowTrustedDomains;
+  BOOL bRestrictAnonymous;
+  BOOL bDebugHiresTimestamp;
+  BOOL bDebugPid;
+  BOOL bDebugUid;
 } global;
 
 static global Globals;
@@ -297,17 +295,23 @@ typedef struct
   char *writelist;
   char *volume;
   char *fstype;
-  char *vfsObjectFile;
-  struct vfs_options *vfsOptions;
   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;
@@ -330,6 +334,7 @@ typedef struct
   BOOL bStrictLocking;
   BOOL bShareModes;
   BOOL bOpLocks;
+  BOOL bLevel2OpLocks;
   BOOL bOnlyUser;
   BOOL bMangledNames;
   BOOL bWidelinks;
@@ -392,17 +397,23 @@ static service sDefault =
   NULL,    /* writelist */
   NULL,    /* volume */
   NULL,    /* fstype */
-  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 */
@@ -425,6 +436,7 @@ static service sDefault =
   False,  /* bStrictLocking */
   True,  /* bShareModes */
   True,  /* bOpLocks */
+  True, /* bLevel2OpLocks */
   False, /* bOnlyUser */
   True,  /* bMangledNames */
   True,  /* bWidelinks */
@@ -451,7 +463,6 @@ static int iNumServices = 0;
 static int iServiceIndex = 0;
 static BOOL bInGlobalSection = True;
 static BOOL bGlobalOnly = False;
-static int server_role;
 static int default_server_announce;
 
 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
@@ -462,10 +473,8 @@ 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_vfs_object(char *pszParmValue, char **ptr);
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr);
+static BOOL handle_client_code_page(char *pszParmValue,char **ptr);
 
-static void set_server_role(void);
 static void set_default_server_announce_type(void);
 
 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"}, 
@@ -481,14 +490,19 @@ 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_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
@@ -522,37 +536,29 @@ 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},
-  {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL,   NULL,  FLAG_BASIC},
+  {"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,                     NULL,   NULL,  FLAG_BASIC|FLAG_DOS_STRING},
+  {"netbios aliases",  P_STRING,  P_GLOBAL, &Globals.szNetbiosAliases,  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},
 
   {"Security Options", P_SEP, P_SEPARATOR},
-
   {"security",         P_ENUM,    P_GLOBAL, &Globals.security,          NULL,   enum_security, FLAG_BASIC},
   {"encrypt passwords",P_BOOL,    P_GLOBAL, &Globals.bEncryptPasswords, NULL,   NULL,  FLAG_BASIC},
   {"update encrypted", P_BOOL,    P_GLOBAL, &Globals.bUpdateEncrypt,    NULL,   NULL,  FLAG_BASIC},
-  {"server ntlmv2",    P_ENUM,    P_GLOBAL, &Globals.bServerNTLMv2,     NULL,   enum_bool_auto,  FLAG_BASIC},
-  {"client ntlmv2",    P_ENUM,    P_GLOBAL, &Globals.bClientNTLMv2,     NULL,   enum_bool_auto,  FLAG_BASIC},
-  {"use rhosts",       P_BOOL,    P_GLOBAL, &Globals.bUseRhosts,        NULL,   NULL,  0},
+  {"allow trusted domains",P_BOOL,P_GLOBAL, &Globals.bAllowTrustedDomains,NULL, NULL,  0},
+  {"alternate permissions",P_BOOL,P_LOCAL,  &sDefault.bAlternatePerm,   NULL,   NULL,  FLAG_GLOBAL|FLAG_DEPRECATED},
+  {"hosts equiv",      P_STRING,  P_GLOBAL, &Globals.szHostsEquiv,      NULL,   NULL,  0},
+  {"min passwd length",     P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL,   NULL,  0},
+  {"min password length",   P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL,   NULL,  0},
   {"map to guest",     P_ENUM,    P_GLOBAL, &Globals.map_to_guest,      NULL,   enum_map_to_guest, 0},
   {"null passwords",   P_BOOL,    P_GLOBAL, &Globals.bNullPasswords,    NULL,   NULL,  0},
   {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL,   NULL,  0},
   {"smb passwd file",  P_STRING,  P_GLOBAL, &Globals.szSMBPasswdFile,   NULL,   NULL,  0},
-#if USE_SMBFILE_DB
-  {"smb passgrp file", P_STRING,  P_GLOBAL, &Globals.szSMBPassGroupFile, NULL,   NULL,  0},
-#endif
-#if USE_SMBGROUP_DB
-  {"smb group file",   P_STRING,  P_GLOBAL, &Globals.szSMBGroupFile,    NULL,   NULL,  0},
-  {"smb alias file",   P_STRING,  P_GLOBAL, &Globals.szSMBAliasFile,    NULL,   NULL,  0},
-#endif
-  {"hosts equiv",      P_STRING,  P_GLOBAL, &Globals.szHostsEquiv,      NULL,   NULL,  0},
   {"root directory",   P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
   {"root dir",         P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
   {"root",             P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL,   NULL,  0},
@@ -563,43 +569,47 @@ 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},
-  {"alternate permissions",P_BOOL,P_LOCAL,  &sDefault.bAlternatePerm,   NULL,   NULL,  FLAG_GLOBAL|FLAG_DEPRECATED},
-  {"revalidate",       P_BOOL,    P_LOCAL,  &sDefault.bRevalidate,      NULL,   NULL,  FLAG_GLOBAL},
-  {"username",         P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL,   NULL,  FLAG_GLOBAL},
+  {"restrict anonymous", P_BOOL,  P_GLOBAL, &Globals.bRestrictAnonymous,NULL,   NULL,  0},
+  {"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},
+  {"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
   {"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
-
   {"ssl",              P_BOOL,    P_GLOBAL, &Globals.sslEnabled,        NULL,   NULL,  0 },
   {"ssl hosts",        P_STRING,  P_GLOBAL, &Globals.sslHostsRequire,   NULL,   NULL,  0 },
   {"ssl hosts resign", P_STRING,  P_GLOBAL, &Globals.sslHostsResign,   NULL,   NULL,  0} ,
@@ -617,7 +627,6 @@ static struct parm_struct parm_table[] =
 #endif        /* WITH_SSL */
 
   {"Logging Options", P_SEP, P_SEPARATOR},
-
   {"log level",        P_INTEGER, P_GLOBAL, &DEBUGLEVEL,                NULL,   NULL,  FLAG_BASIC},
   {"debuglevel",       P_INTEGER, P_GLOBAL, &DEBUGLEVEL,                NULL,   NULL,  0},
   {"syslog",           P_INTEGER, P_GLOBAL, &Globals.syslog,            NULL,   NULL,  0},
@@ -626,168 +635,162 @@ static struct parm_struct parm_table[] =
   {"max log size",     P_INTEGER, P_GLOBAL, &Globals.max_log_size,      NULL,   NULL,  0},
   {"timestamp logs",   P_BOOL,    P_GLOBAL, &Globals.bTimestampLogs,    NULL,   NULL,  0},
   {"debug timestamp",  P_BOOL,    P_GLOBAL, &Globals.bTimestampLogs,    NULL,   NULL,  0},
-  {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL,   NULL,  FLAG_GLOBAL},
+  {"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|FLAG_SHARE|FLAG_PRINT},
 
   {"Protocol Options", P_SEP, P_SEPARATOR},
-
   {"protocol",         P_ENUM,    P_GLOBAL, &Globals.maxprotocol,       NULL,   enum_protocol, 0},
   {"read bmpx",        P_BOOL,    P_GLOBAL, &Globals.bReadbmpx,         NULL,   NULL,  0},
   {"read raw",         P_BOOL,    P_GLOBAL, &Globals.bReadRaw,          NULL,   NULL,  0},
   {"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 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},
   {"max xmit",         P_INTEGER, P_GLOBAL, &Globals.max_xmit,          NULL,   NULL,  0},
-  {"name resolve order",  P_STRING,  P_GLOBAL, &Globals.szNameResolveOrder,  NULL,   NULL, 0},
+  {"name resolve order",P_STRING, P_GLOBAL, &Globals.szNameResolveOrder,NULL,   NULL, 0},
   {"max packet",       P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL,   NULL,  0},
   {"packet size",      P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL,   NULL,  0},
   {"max ttl",          P_INTEGER, P_GLOBAL, &Globals.max_ttl,           NULL,   NULL,  0},
   {"max wins ttl",     P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl,      NULL,   NULL,  0},
   {"min wins ttl",     P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl,      NULL,   NULL,  0},
-  {"time server",      P_BOOL,    P_GLOBAL, &Globals.bTimeServer,      NULL,   NULL,  0},
+  {"time server",      P_BOOL,    P_GLOBAL, &Globals.bTimeServer,          NULL,   NULL,  0},
 
   {"Tuning Options", P_SEP, P_SEPARATOR},
-
   {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL,   NULL,  0},
   {"deadtime",         P_INTEGER, P_GLOBAL, &Globals.deadtime,          NULL,   NULL,  0},
   {"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},
-  {"print ok",         P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  0},
+  {"printer driver file", P_STRING,  P_GLOBAL, &Globals.szDriverFile,   NULL,   NULL,  FLAG_PRINT},
+  {"print ok",         P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL,   NULL,  FLAG_PRINT},
   {"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},
-  {"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},
+  {"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},
+
 
   {"Filename Handling", P_SEP, P_SEPARATOR},
   {"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},
+  {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page,   NULL,  0},
+  {"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},
-
-  {"trusted domains",   P_STRING, P_GLOBAL, &Globals.szTrustedDomains,  NULL,   NULL,  0},
-  {"trusting domains",  P_STRING, P_GLOBAL, &Globals.szTrustingDomains, NULL,   NULL,  0},
-  {"local group map",   P_STRING, P_GLOBAL, &Globals.szAliasnameMap,     NULL,   NULL,  0},
-  {"domain group map",  P_STRING, P_GLOBAL, &Globals.szGroupnameMap,     NULL,   NULL,  0},
-  {"builtin group map", P_STRING, P_GLOBAL, &Globals.szBuiltinnameMap,   NULL,   NULL,  0},
-  {"builtin rid file",  P_STRING, P_GLOBAL, &Globals.szBuiltinRidFile,   NULL,   NULL,  0},
-  {"domain user map",   P_STRING, P_GLOBAL, &Globals.szNTusernameMap,    NULL,   NULL,  0},
+  {"domain groups",    P_STRING,  P_GLOBAL, &Globals.szDomainGroups,    NULL,   NULL,  0},
+  {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL,   NULL,  0},
+  {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL,   NULL,  0},
+  {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL,   NULL,  0},
+  {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL,   NULL,  0},
+#ifdef USING_GROUPNAME_MAP
+  {"groupname map",     P_STRING, P_GLOBAL, &Globals.szGroupnameMap,     NULL,   NULL,  0},
+#endif /* USING_GROUPNAME_MAP */
   {"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},
+  {"preferred master", P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   NULL,  FLAG_BASIC},
+  {"prefered master",  P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL,   NULL,  0},
   {"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},
+  {"domain master",    P_BOOL,    P_GLOBAL, &Globals.bDomainMaster,     NULL,   NULL,  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},
-
   {"dns proxy",        P_BOOL,    P_GLOBAL, &Globals.bDNSproxy,         NULL,   NULL,  0},
   {"wins proxy",       P_BOOL,    P_GLOBAL, &Globals.bWINSproxy,        NULL,   NULL,  0},
   {"wins server",      P_STRING,  P_GLOBAL, &Globals.szWINSserver,      NULL,   NULL,  FLAG_BASIC},
   {"wins support",     P_BOOL,    P_GLOBAL, &Globals.bWINSsupport,      NULL,   NULL,  FLAG_BASIC},
+  {"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},
   {"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},
 
 #ifdef WITH_LDAP
   {"Ldap Options", P_SEP, P_SEPARATOR},
-
   {"ldap server",      P_STRING,  P_GLOBAL, &Globals.szLdapServer,      NULL,   NULL,  0},
   {"ldap port",        P_INTEGER, P_GLOBAL, &Globals.ldap_port,         NULL,   NULL,  0},
   {"ldap suffix",      P_STRING,  P_GLOBAL, &Globals.szLdapSuffix,      NULL,   NULL,  0},
-  {"ldap bind as",     P_STRING,  P_GLOBAL, &Globals.szLdapBindAs,      NULL,   NULL,  0},
-  {"ldap passwd file", P_STRING,  P_GLOBAL, &Globals.szLdapPasswdFile,  NULL,   NULL,  0},
+  {"ldap filter",      P_STRING,  P_GLOBAL, &Globals.szLdapFilter,      NULL,   NULL,  0},
+  {"ldap root",        P_STRING,  P_GLOBAL, &Globals.szLdapRoot,        NULL,   NULL,  0},
+  {"ldap root passwd", P_STRING,  P_GLOBAL, &Globals.szLdapRootPassword,NULL,   NULL,  0},
 #endif /* WITH_LDAP */
 
-#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
-  {"MySQL Options", P_SEP, P_SEPARATOR},
-  {"mysql host",       P_STRING, P_GLOBAL, &Globals.sMysqlHost,        NULL,   NULL,  0},
-  {"mysql user",       P_STRING, P_GLOBAL, &Globals.sMysqlUser,        NULL,   NULL,  0},
-  {"mysql pass file",  P_STRING, P_GLOBAL, &Globals.sMysqlPassFile,    NULL,   NULL,  0},
-  {"mysql database",   P_STRING, P_GLOBAL, &Globals.sMysqlDatabase,    NULL,   NULL,  0},
-  {"mysql table",      P_STRING, P_GLOBAL, &Globals.sMysqlTable,       NULL,   NULL,  0},
-#endif /* MYSQL */
 
   {"Miscellaneous Options", P_SEP, P_SEPARATOR},
-
   {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL,   NULL,  0},
   {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL,   NULL,  FLAG_HIDE},
   {"preload",          P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL,   NULL,  0},
@@ -809,31 +812,29 @@ 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,  0},
+  {"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,  0},
+  {"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},
+  {"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}, 
   {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL,   NULL, 0}
 };
 
@@ -850,7 +851,7 @@ static void init_globals(void)
   if (!done_init)
     {
       int i;
-      bzero((void *)&Globals,sizeof(Globals));
+      memset((void *)&Globals,'\0',sizeof(Globals));
 
       for (i = 0; parm_table[i].label; i++) 
        if ((parm_table[i].type == P_STRING ||
@@ -869,20 +870,14 @@ static void init_globals(void)
   DEBUG(3,("Initialising global parameters\n"));
 
   string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
-#if USE_SMBFILE_DB
-  string_set(&Globals.szSMBPassGroupFile, SMB_PASSGRP_FILE);
-#endif
-#if USE_SMBGROUP_DB
-  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*");
+  /*
+   * Allow the default PASSWD_CHAT to be overridden in local.h.
+   */
+  string_set(&Globals.szPasswdChat,DEFAULT_PASSWD_CHAT);
   string_set(&Globals.szWorkGroup, WORKGROUP);
   string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
   string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
   string_set(&Globals.szDriverFile, DRIVERFILE);
-  string_set(&Globals.szNtForms, FORMSFILE);
-  string_set(&Globals.szNtDriverFile, NTDRIVERSDIR);
   string_set(&Globals.szLockDir, LOCKDIR);
   string_set(&Globals.szRootdir, "/");
   string_set(&Globals.szSmbrun, SMBRUN);
@@ -921,13 +916,15 @@ 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;
   Globals.bSyslogOnly = False;
   Globals.bTimestampLogs = True;
-  Globals.os_level = 32;
+  Globals.bDebugHiresTimestamp = False;
+  Globals.bDebugPid = False;
+  Globals.bDebugUid = False;
   Globals.max_ttl = 60*60*24*3; /* 3 days default. */
   Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
   Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
@@ -938,7 +935,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;
@@ -956,8 +953,12 @@ 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.bRestrictAnonymous = False;
   Globals.map_to_guest = 0; /* By Default, "Never" */
+  Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
+  Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */
 
 #ifdef WITH_LDAP
   /* default values for ldap */
@@ -967,31 +968,21 @@ 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;
   Globals.sslCompatibility = False;
 #endif        /* WITH_SSL */
 
-/* NTLMv2 */
-
-  Globals.bClientNTLMv2 = False; 
-  Globals.bServerNTLMv2 = False; 
-
 /* these parameters are set to defaults that are more appropriate
    for the increasing samba install base:
 
@@ -1004,9 +995,10 @@ static void init_globals(void)
 
 */
 
-  Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
+  Globals.os_level = 20;
+  Globals.bPreferredMaster = False;
   Globals.bLocalMaster = True;
-  Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
+  Globals.bDomainMaster = False;
   Globals.bDomainLogons = False;
   Globals.bBrowseList = True;
   Globals.bWINSsupport = False;
@@ -1020,13 +1012,7 @@ static void init_globals(void)
    */
   Globals.bKernelOplocks = True;
 
-#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
-  string_set(&Globals.sMysqlHost,"localhost");
-  string_set(&Globals.sMysqlUser,"root");
-  string_set(&Globals.sMysqlPassFile,NULL);
-  string_set(&Globals.sMysqlDatabase,"samba");
-  string_set(&Globals.sMysqlTable,"smbpasswd");
-#endif
+  Globals.bAllowTrustedDomains = True;
 
   /*
    * This must be done last as it checks the value in 
@@ -1056,20 +1042,19 @@ 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");
       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_initial(&sDefault.szLpqcommand,"/usr/bin/lpstat -o%p");
+      string_initial(&sDefault.szLprmcommand,"/usr/bin/cancel %p-%j");
+      string_initial(&sDefault.szPrintcommand,"/usr/bin/lp -d%p -oraw %s; rm %s");
+      string_initial(&sDefault.szQueuepausecommand, "/usr/bin/disable %p");
+      string_initial(&sDefault.szQueueresumecommand, "/usr/bin/enable %p");
       break;
 
     case PRINT_SYSV:
@@ -1077,14 +1062,14 @@ static void init_locals(void)
       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
+#ifdef HPUX
+      string_initial(&sDefault.szQueuepausecommand, "disable %p");
+      string_initial(&sDefault.szQueueresumecommand, "enable %p");
+#else /* 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");
 #endif /* SYSV */
       break;
 
@@ -1111,14 +1096,14 @@ convenience routine to grab string parameters into a rotating buffer,
 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 size_t buflen[10];
   static int next = -1;  
   char *ret;
   int i;
-  int len = s?strlen(s):0;
+  size_t len = s?strlen(s):0;
 
   if (next == -1) {
     /* initialisation */
@@ -1134,7 +1119,8 @@ static char *lp_string(char *s)
 
   if (buflen[next] != len) {
     buflen[next] = len;
-    if (bufs[next]) free(bufs[next]);
+    if (bufs[next])
+      free(bufs[next]);
     bufs[next] = (char *)malloc(len);
     if (!bufs[next]) {
       DEBUG(0,("out of memory in lp_string()"));
@@ -1148,7 +1134,7 @@ static char *lp_string(char *s)
   if (!s) 
     *ret = 0;
   else
-    StrCpy(ret,s);
+    StrnCpy(ret,s,len-1);
 
   trim_string(ret, "\"", "\"");
 
@@ -1180,20 +1166,10 @@ static char *lp_string(char *s)
 #define FN_LOCAL_INTEGER(fn_name,val) \
  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
 
-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)
 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
-#if USE_SMBFILE_DB
-FN_GLOBAL_STRING(lp_smb_passgrp_file,&Globals.szSMBPassGroupFile)
-#endif
-#if USE_SMBGROUP_DB
-FN_GLOBAL_STRING(lp_smb_group_file,&Globals.szSMBGroupFile)
-FN_GLOBAL_STRING(lp_smb_alias_file,&Globals.szSMBAliasFile)
-#endif
 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
@@ -1207,14 +1183,10 @@ FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
 FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
-FN_GLOBAL_STRING(lp_trusted_domains,&Globals.szTrustedDomains)
-FN_GLOBAL_STRING(lp_trusting_domains,&Globals.szTrustingDomains)
 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
-FN_GLOBAL_STRING(lp_aliasname_map,&Globals.szAliasnameMap)
+#ifdef USING_GROUPNAME_MAP
 FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
-FN_GLOBAL_STRING(lp_builtinname_map,&Globals.szBuiltinnameMap)
-FN_GLOBAL_STRING(lp_builtinrid_file,&Globals.szBuiltinRidFile)
-FN_GLOBAL_STRING(lp_ntusrname_map,&Globals.szNTusernameMap)
+#endif /* USING_GROUPNAME_MAP */
 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 
 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath) 
 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive) 
@@ -1229,15 +1201,22 @@ 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_nt_forms,&Globals.szNtForms)
-FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile)
-FN_GLOBAL_STRING(lp_dfs_map,&Globals.szDfsMap)
+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_domain_groups,&Globals.szDomainGroups)
+FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
+FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
+FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
+FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
 
 #ifdef WITH_LDAP
 FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
 FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
-FN_GLOBAL_STRING(lp_ldap_bind_as,&Globals.szLdapBindAs);
-FN_GLOBAL_STRING(lp_ldap_passwd_file,&Globals.szLdapPasswdFile);
+FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
+FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
+FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
 #endif /* WITH_LDAP */
 
 #ifdef WITH_SSL
@@ -1262,7 +1241,9 @@ FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
+FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
+FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
@@ -1273,10 +1254,11 @@ FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
 FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
-FN_GLOBAL_BOOL(lp_client_ntlmv2,&Globals.bClientNTLMv2)
-FN_GLOBAL_BOOL(lp_server_ntlmv2,&Globals.bServerNTLMv2)
 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
 FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
+FN_GLOBAL_BOOL(lp_debug_hires_timestamp,&Globals.bDebugHiresTimestamp)
+FN_GLOBAL_BOOL(lp_debug_pid,&Globals.bDebugPid)
+FN_GLOBAL_BOOL(lp_debug_uid,&Globals.bDebugUid)
 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
@@ -1287,7 +1269,10 @@ 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_allow_trusted_domains,&Globals.bAllowTrustedDomains)
+FN_GLOBAL_BOOL(lp_restrict_anonymous,&Globals.bRestrictAnonymous)
 
 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
@@ -1315,6 +1300,8 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
 FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
 FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
 FN_GLOBAL_INTEGER(lp_map_to_guest,&Globals.map_to_guest)
+FN_GLOBAL_INTEGER(lp_min_passwd_length,&Globals.min_passwd_length)
+FN_GLOBAL_INTEGER(lp_oplock_break_wait_time,&Globals.oplock_break_wait_time)
 
 #ifdef WITH_LDAP
 FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
@@ -1351,7 +1338,6 @@ 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)
 static FN_LOCAL_STRING(lp_volume,volume)
 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
@@ -1359,6 +1345,8 @@ FN_LOCAL_STRING(lp_hide_files,szHideFiles)
 FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
 
+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)
@@ -1379,6 +1367,7 @@ FN_LOCAL_BOOL(lp_locking,bLocking)
 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
 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)
@@ -1394,24 +1383,23 @@ 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_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)
 
-#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
-FN_GLOBAL_STRING(lp_mysql_host,&Globals.sMysqlHost)
-FN_GLOBAL_STRING(lp_mysql_user,&Globals.sMysqlUser)
-FN_GLOBAL_STRING(lp_mysql_passfile,&Globals.sMysqlPassFile)
-FN_GLOBAL_STRING(lp_mysql_db,&Globals.sMysqlDatabase)
-FN_GLOBAL_STRING(lp_mysql_table,&Globals.sMysqlTable)
-#endif
 
 
 /* local prototypes */
@@ -1433,7 +1421,7 @@ initialise a service to the defaults
 ***************************************************************************/
 static void init_service(service *pservice)
 {
-  bzero((char *)pservice,sizeof(service));
+  memset((char *)pservice,'\0',sizeof(service));
   copy_service(pservice,&sDefault,NULL);
 }
 
@@ -1508,9 +1496,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);
 }
 
@@ -1892,80 +1881,6 @@ BOOL lp_file_list_changed(void)
   return(False);
 }
 
-/***************************************************************************
-  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;
-}
-
-/***************************************************************************
-  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;
-}
-
 /***************************************************************************
   handle the interpretation of the coding system parameter
   *************************************************************************/
@@ -1977,19 +1892,41 @@ 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
 ***************************************************************************/
+
 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
 { 
   string_set(ptr,pszParmValue);
@@ -2004,10 +1941,10 @@ static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
   return(True);
 }
 
-
 /***************************************************************************
 handle the include operation
 ***************************************************************************/
+
 static BOOL handle_include(char *pszParmValue,char **ptr)
 { 
   pstring fname;
@@ -2081,10 +2018,10 @@ static void init_copymap(service *pservice)
   if (pservice->copymap) free(pservice->copymap);
   pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
   if (!pservice->copymap)
-    DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
-
-  for (i=0;i<NUMPARAMETERS;i++)
-    pservice->copymap[i] = True;
+    DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS));
+  else
+    for (i=0;i<NUMPARAMETERS;i++)
+      pservice->copymap[i] = True;
 }
 
 
@@ -2176,19 +2113,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;
 
@@ -2256,7 +2201,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:
@@ -2404,7 +2349,7 @@ Display the contents of the global structure.
 static void dump_globals(FILE *f)
 {
        int i;
-       fprintf(f, "# Global parameters\n");
+       fprintf(f, "# Global parameters\n[global]\n");
        
        for (i=0;parm_table[i].label;i++)
                if (parm_table[i].class == P_GLOBAL &&
@@ -2559,7 +2504,7 @@ static void lp_add_auto_services(char *str)
        homes = lp_servicenumber(HOMES_NAME);
        
        for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
-               char *home = get_unixhome_dir(p);
+               char *home = get_user_home_dir(p);
                
                if (lp_servicenumber(p) >= 0) continue;
                
@@ -2688,7 +2633,6 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
   if (add_ipc)
          lp_add_ipc();
 
-  set_server_role();
   set_default_server_announce_type();
 
   bLoaded = True;
@@ -2706,6 +2650,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
 ***************************************************************************/
@@ -2717,7 +2669,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;
 
@@ -2729,15 +2681,21 @@ 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);
+}
+
+/***************************************************************************
+Display the contents of one service in human-readable form.
+***************************************************************************/
+void lp_dump_one(FILE *f, BOOL show_defaults, int snum)
+{
+   if (VALID(snum))
+     {
+       if (iSERVICE(snum).szService[0] == '\0')
+        return;
+       dump_a_service(pSERVICE(snum), f);
+     }
 }
 
 
@@ -2773,113 +2731,22 @@ 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.
 ********************************************************************/
 static void set_default_server_announce_type(void)
 {
-       default_server_announce = 0;
-       default_server_announce |= SV_TYPE_WORKSTATION;
-       default_server_announce |= SV_TYPE_SERVER;
-       default_server_announce |= SV_TYPE_SERVER_UNIX;
-       default_server_announce |= SV_TYPE_PRINTQ_SERVER;
-
-       switch (lp_announce_as())
-       {
-               case ANNOUNCE_AS_NT:
-               {
-                       default_server_announce |= SV_TYPE_SERVER_NT;
-                       default_server_announce |= SV_TYPE_NT;
-                       break;
-               }
-               case ANNOUNCE_AS_WIN95:
-               {
-                       default_server_announce |= SV_TYPE_WIN95_PLUS;
-                       break;
-               }
-               case ANNOUNCE_AS_WFW:
-               {
-                       default_server_announce |= SV_TYPE_WFW;
-                       break;
-               }
-               default:
-               {
-                       break;
-               }
-       }
-
-       switch (lp_server_role())
-       {
-               case ROLE_DOMAIN_MEMBER:
-               {
-                       default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
-                       break;
-               }
-               case ROLE_DOMAIN_PDC:
-               {
-                       default_server_announce |= SV_TYPE_DOMAIN_CTRL;
-                       break;
-               }
-               case ROLE_DOMAIN_BDC:
-               {
-                       default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
-                       break;
-               }
-               case ROLE_DOMAIN_NONE:
-               default:
-               {
-                       break;
-               }
-       }
-
-       if (lp_time_server())
-       {
-               default_server_announce |= SV_TYPE_TIME_SOURCE;
-       }
+  default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
+                              SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
+  if(lp_announce_as() == ANNOUNCE_AS_NT_SERVER)
+    default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
+  if(lp_announce_as() == ANNOUNCE_AS_NT_WORKSTATION)
+    default_server_announce |= SV_TYPE_NT;
+  else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
+    default_server_announce |= SV_TYPE_WIN95_PLUS;
+  else if(lp_announce_as() == ANNOUNCE_AS_WFW)
+    default_server_announce |= SV_TYPE_WFW;
+  default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
 }
 
 
@@ -3002,38 +2869,38 @@ 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 7bdbdab320e6cc0e1bc4bc934b19b1f0ff178d21..43fea00a64443c142acba8ad61ba8b3114458d93 100644 (file)
@@ -1,9 +1,8 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 2.0.
+   Version 1.9.
    LDAP protocol helper functions for SAMBA
    Copyright (C) Jean François Micouleau 1998
-   Copyright (C) Matthew Chapman 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
    
 */
 
-#include "includes.h"
-
 #ifdef WITH_LDAP
 
+#include "includes.h"
+
 #include <lber.h>
 #include <ldap.h>
 
+#define ADD_USER 1
+#define MODIFY_USER 2
+
 extern int DEBUGLEVEL;
 
-/* Internal state */
-LDAP *ldap_struct;
-LDAPMessage *ldap_results;
-LDAPMessage *ldap_entry;
+/*******************************************************************
+ open a connection to the ldap serve.
+******************************************************************/    
+static BOOL ldap_open_connection(LDAP **ldap_struct)
+{
+       if ( (*ldap_struct = ldap_open(lp_ldap_server(),lp_ldap_port()) ) == NULL)
+       {
+               DEBUG( 0, ( "The LDAP server is not responding !\n" ) );
+               return( False );
+       }
+       DEBUG(2,("ldap_open_connection: connection opened\n"));
+       return (True);
+}
+
 
-/* LDAP password */
-static pstring ldap_secret;
+/*******************************************************************
+ connect anonymously to the ldap server.
+ FIXME: later (jfm)
+******************************************************************/    
+static BOOL ldap_connect_anonymous(LDAP *ldap_struct)
+{
+       if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
+       {
+               DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) );
+               return(False);
+       }
+       return (True);
+}
 
 
 /*******************************************************************
-  Open connections to the LDAP server.
- ******************************************************************/   
+ connect to the ldap server under system privileg.
+******************************************************************/    
+static BOOL ldap_connect_system(LDAP *ldap_struct)
+{
+       if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
+       {
+               DEBUG( 0, ( "Couldn't bind to the LDAP server!\n" ) );
+               return(False);
+       }
+       DEBUG(2,("ldap_connect_system: succesful connection to the LDAP server\n"));
+       return (True);
+}
 
-BOOL ldap_connect(void)
+/*******************************************************************
+ connect to the ldap server under a particular user.
+******************************************************************/    
+static BOOL ldap_connect_user(LDAP *ldap_struct, char *user, char *password)
 {
-       int err;
+       if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
+       {
+               DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) );
+               return(False);
+       }
+       DEBUG(2,("ldap_connect_user: succesful connection to the LDAP server\n"));
+       return (True);
+}
 
-       if (!(ldap_struct = ldap_open(lp_ldap_server(), lp_ldap_port()))) {
-               DEBUG(0, ("open: %s\n", strerror(errno)));
-               return (False);
+/*******************************************************************
+ run the search by name.
+******************************************************************/    
+static BOOL ldap_search_one_user(LDAP *ldap_struct, char *filter, LDAPMessage **result)
+{      
+       int scope = LDAP_SCOPE_ONELEVEL;
+       int rc;
+               
+       DEBUG(2,("ldap_search_one_user: searching for:[%s]\n", filter));
+               
+       rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, result);
+
+       if (rc ! = LDAP_SUCCESS )
+       {
+               DEBUG( 0, ( "Problem during the LDAP search\n" ) );
+               return(False);
        }
+       return (True);
+}
 
-       err = ldap_simple_bind_s(ldap_struct, lp_ldap_bind_as(), ldap_secret);
-       if (err != LDAP_SUCCESS) {
-               DEBUG(0, ("bind: %s\n", ldap_err2string(err)));
-               return (False);
+/*******************************************************************
+ run the search by name.
+******************************************************************/    
+static BOOL ldap_search_one_user_by_name(LDAP *ldap_struct, char *user, LDAPMessage **result)
+{      
+       pstring filter;
+       /*
+          in the filter expression, replace %u with the real name
+          so in ldap filter, %u MUST exist :-)
+       */      
+       pstrcpy(filter,lp_ldap_filter());
+       pstring_sub(filter,"%u",user);
+       
+       if ( !ldap_search_one_user(ldap_struct, filter, result) )
+       {
+               return(False);
        }
+       return (True);
+}
 
-       DEBUG(2,("Connected to LDAP server\n"));
+/*******************************************************************
+ run the search by uid.
+******************************************************************/    
+static BOOL ldap_search_one_user_by_uid(LDAP *ldap_struct, int uid, LDAPMessage **result)
+{      
+       pstring filter;
+       
+       slprintf(filter, sizeof(pstring)-1, "uidAccount = %d", uid);
+       
+       if ( !ldap_search_one_user(ldap_struct, filter, result) )
+       {       
+               return(False);
+       }
        return (True);
 }
 
 /*******************************************************************
-  close connections to the LDAP server.
- ******************************************************************/   
+ search an attribute and return the first value found.
+******************************************************************/
+static void get_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char *attribute, char *value)
+{
+       char **valeurs;
+       
+       if ( (valeurs = ldap_get_values(ldap_struct, entry, attribute)) ! = NULL) 
+       {
+               pstrcpy(value, valeurs[0]);
+               ldap_value_free(valeurs);
+               DEBUG(3,("get_single_attribute: [%s] = [%s]\n", attribute, value));     
+       }
+       else
+       {
+               value = NULL;
+       }
+}
 
-void ldap_disconnect(void)
+/*******************************************************************
+ check if the returned entry is a sambaAccount objectclass.
+******************************************************************/    
+static BOOL ldap_check_user(LDAP *ldap_struct, LDAPMessage *entry)
 {
-       if(!ldap_struct)
-               return;
+       BOOL sambaAccount = False;
+       char **valeur;
+       int i;
 
-       if(ldap_results) {
-               ldap_msgfree(ldap_results);
-               ldap_results = NULL; }
+       DEBUG(2,("ldap_check_user: "));
+       valeur = ldap_get_values(ldap_struct, entry, "objectclass");
+       if (valeur! = NULL)
+       {
+               for (i = 0;valeur[i]! = NULL;i++)
+               {
+                       if (!strcmp(valeur[i],"sambaAccount")) sambaAccount = True;
+               }
+       }
+       DEBUG(2,("%s\n",sambaAccount?"yes":"no"));
+       ldap_value_free(valeur);
+       return (sambaAccount);
+}
 
-       ldap_unbind(ldap_struct);
-       ldap_struct = NULL;
+/*******************************************************************
+ check if the returned entry is a sambaTrust objectclass.
+******************************************************************/    
+static BOOL ldap_check_trust(LDAP *ldap_struct, LDAPMessage *entry)
+{
+       BOOL sambaTrust = False;
+       char **valeur;
+       int i;
        
-       DEBUG(2,("Connection closed\n"));
+       DEBUG(2,("ldap_check_trust: "));
+       valeur = ldap_get_values(ldap_struct, entry, "objectclass");
+       if (valeur! = NULL)
+       {
+               for (i = 0;valeur[i]! = NULL;i++)
+               {
+                       if (!strcmp(valeur[i],"sambaTrust")) sambaTrust = True;
+               }
+       }       
+       DEBUG(2,("%s\n",sambaTrust?"yes":"no"));
+       ldap_value_free(valeur);        
+       return (sambaTrust);
 }
 
-
 /*******************************************************************
-  Search the directory using a given filter.
- ******************************************************************/   
+ retrieve the user's info and contruct a smb_passwd structure.
+******************************************************************/
+static void ldap_get_smb_passwd(LDAP *ldap_struct,LDAPMessage *entry, 
+                          struct smb_passwd *user)
+{      
+       static pstring user_name;
+       static pstring user_pass;
+       static pstring temp;
+       static unsigned char smblmpwd[16];
+       static unsigned char smbntpwd[16];
 
-BOOL ldap_search_for(char *filter)
-{
-       int err;
+       pdb_init_smb(user);
 
-       DEBUG(2,("Searching in [%s] for [%s]\n", lp_ldap_suffix(), filter));
+       memset((char *)smblmpwd, '\0', sizeof(smblmpwd));
+       memset((char *)smbntpwd, '\0', sizeof(smbntpwd));
 
-       err = ldap_search_s(ldap_struct, lp_ldap_suffix(), LDAP_SCOPE_ONELEVEL,
-                         filter, NULL, 0, &ldap_results);
+       get_single_attribute(ldap_struct, entry, "cn", user_name);
+       DEBUG(2,("ldap_get_smb_passwd: user: %s\n",user_name));
+               
+#ifdef LDAP_PLAINTEXT_PASSWORD
+       get_single_attribute(ldap_struct, entry, "userPassword", temp);
+       nt_lm_owf_gen(temp, user->smb_nt_passwd, user->smb_passwd);
+       memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
+#else
+       get_single_attribute(ldap_struct, entry, "unicodePwd", temp);
+       pdb_gethexpwd(temp, smbntpwd);          
+       memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
 
-       if(err != LDAP_SUCCESS) {
-               DEBUG(0, ("search: %s\n", ldap_err2string(err)));
-       }
+       get_single_attribute(ldap_struct, entry, "dBCSPwd", temp);
+       pdb_gethexpwd(temp, smblmpwd);          
+       memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
+#endif
+       
+       get_single_attribute(ldap_struct, entry, "userAccountControl", temp);
+       user->acct_ctrl = pdb_decode_acct_ctrl(temp);
 
-       DEBUG(2, ("%d matching entries found\n",
-                 ldap_count_entries(ldap_struct, ldap_results)));
+       get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-       ldap_entry = ldap_first_entry(ldap_struct, ldap_results);
-       return (True);
-}
+       get_single_attribute(ldap_struct, entry, "rid", temp);
 
-BOOL ldap_search_by_name(const char *user)
-{
-       fstring filter;
+       /* the smb (unix) ids are not stored: they are created */
+       user->smb_userid = pdb_user_rid_to_uid (atoi(temp));
 
-       slprintf(filter, sizeof(filter)-1,
-                "(&(uid=%s)(objectclass=sambaAccount))", user);
-       return ldap_search_for(filter);
+       if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) )
+       {
+               DEBUG(0,("Inconsistency in the LDAP database\n"));
+       }
+       if (user->acct_ctrl & ACB_NORMAL)
+       {
+               user->smb_name      = user_name;
+               user->smb_passwd    = smblmpwd;
+               user->smb_nt_passwd = smbntpwd;
+       }
 }
 
-BOOL ldap_search_by_uid(int uid)
-{
-       fstring filter;
+/*******************************************************************
+ retrieve the user's info and contruct a sam_passwd structure.
+
+ calls ldap_get_smb_passwd function first, though, to save code duplication.
+
+******************************************************************/
+static void ldap_get_sam_passwd(LDAP *ldap_struct, LDAPMessage *entry, 
+                          struct sam_passwd *user)
+{      
+       static pstring user_name;
+       static pstring fullname;
+       static pstring home_dir;
+       static pstring dir_drive;
+       static pstring logon_script;
+       static pstring profile_path;
+       static pstring acct_desc;
+       static pstring workstations;
+       static pstring temp;
+       static struct smb_passwd pw_buf;
+
+       pdb_init_sam(user);
+
+       ldap_get_smb_passwd(ldap_struct, entry, &pw_buf);
        
-       slprintf(filter, sizeof(filter)-1, 
-                "(&(uidNumber=%d)(objectclass=sambaAccount))", uid);
-       return ldap_search_for(filter);
-}
+       user->pass_last_set_time    = pw_buf.pass_last_set_time;
 
+       get_single_attribute(ldap_struct, entry, "logonTime", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-/*******************************************************************
-  Get the first value of an attribute.
- ******************************************************************/
+       get_single_attribute(ldap_struct, entry, "logoffTime", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-BOOL ldap_get_attribute(char *attribute, char *value)
-{
-       char **values;
-       
-       if(!(values = ldap_get_values(ldap_struct, ldap_entry, attribute)))
-               return (False);
+       get_single_attribute(ldap_struct, entry, "kickoffTime", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-       pstrcpy(value, values[0]);
-       ldap_value_free(values);
-       DEBUG(3, ("get: [%s] = [%s]\n", attribute, value));
-       
-       return (True);
-}
+       get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
+       get_single_attribute(ldap_struct, entry, "pwdCanChange", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-/*******************************************************************
-  Construct an smb_passwd structure
- ******************************************************************/
-struct smb_passwd *ldap_getpw(void)
-{
-       static struct smb_passwd smbpw;
-       static pstring unix_name;
-       static pstring nt_name;
-       static unsigned char smblmpwd[16];
-       static unsigned char smbntpwd[16];
-       pstring temp;
+       get_single_attribute(ldap_struct, entry, "pwdMustChange", temp);
+       user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
 
-       if(!ldap_entry)
-               return NULL;
+       user->smb_name = pw_buf.smb_name;
 
-       if(!ldap_get_attribute("uid", unix_name)) {
-               DEBUG(0,("Missing uid\n"));
-               return NULL; }
-       smbpw.unix_name = unix_name;
+       DEBUG(2,("ldap_get_sam_passwd: user: %s\n", user_name));
+               
+       get_single_attribute(ldap_struct, entry, "userFullName", fullname);
+       user->full_name = fullname;
 
-       DEBUG(2,("Retrieving account [%s]\n",unix_name));
+       get_single_attribute(ldap_struct, entry, "homeDirectory", home_dir);
+       user->home_dir = home_dir;
 
-       if(!ldap_get_attribute("uidNumber", temp)) {
-               DEBUG(0,("Missing uidNumber\n"));
-               return NULL; }
-       smbpw.unix_uid = atoi(temp);
+       get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive);
+       user->dir_drive = dir_drive;
 
-        if(!ldap_get_attribute("ntuid", nt_name)) {
-               DEBUG(0,("Missing ntuid\n"));
-               return NULL; }
-       smbpw.nt_name = nt_name;
+       get_single_attribute(ldap_struct, entry, "scriptPath", logon_script);
+       user->logon_script = logon_script;
 
-       if(!ldap_get_attribute("rid", temp)) {
-               DEBUG(0,("Missing rid\n"));
-               return NULL; }
-       smbpw.user_rid = strtol(temp, NULL, 16);
+       get_single_attribute(ldap_struct, entry, "profilePath", profile_path);
+       user->profile_path = profile_path;
 
-       if(ldap_get_attribute("acctFlags", temp))
-               smbpw.acct_ctrl = pwdb_decode_acct_ctrl(temp);
-       else
-               smbpw.acct_ctrl = ACB_NORMAL;
+       get_single_attribute(ldap_struct, entry, "comment", acct_desc);
+       user->acct_desc = acct_desc;
 
-       if(ldap_get_attribute("lmPassword", temp)) {
-               pwdb_gethexpwd(temp, smblmpwd, NULL);
-               smbpw.smb_passwd = smblmpwd;
-       } else {
-               smbpw.smb_passwd = NULL;
-               smbpw.acct_ctrl |= ACB_DISABLED;
-       }
+       get_single_attribute(ldap_struct, entry, "userWorkstations", workstations);
+       user->workstations = workstations;
 
-       if(ldap_get_attribute("ntPassword", temp)) {
-               pwdb_gethexpwd(temp, smbntpwd, NULL);
-               smbpw.smb_nt_passwd = smbntpwd;
-       } else {
-               smbpw.smb_nt_passwd = NULL;
-       }
+       user->unknown_str = NULL; /* don't know, yet! */
+       user->munged_dial = NULL; /* "munged" dial-back telephone number */
 
-       if(ldap_get_attribute("pwdLastSet", temp))
-               smbpw.pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-       else
-               smbpw.pass_last_set_time = (time_t)(-1);
+       get_single_attribute(ldap_struct, entry, "rid", temp);
+       user->user_rid = atoi(temp);
 
-       return &smbpw;
-}
+       get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
+       user->group_rid = atoi(temp);
+
+       /* the smb (unix) ids are not stored: they are created */
+       user->smb_userid = pw_buf.smb_userid;
+       user->smb_grpid = group_rid_to_uid(user->group_rid);
+
+       user->acct_ctrl = pw_buf.acct_ctrl;
 
+       user->unknown_3 = 0xffffff; /* don't know */
+       user->logon_divs = 168; /* hours per week */
+       user->hours_len = 21; /* 21 times 8 bits = 168 */
+       memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+       user->unknown_5 = 0x00020000; /* don't know */
+       user->unknown_5 = 0x000004ec; /* don't know */
+
+       if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) )
+       {
+               DEBUG(0,("Inconsistency in the LDAP database\n"));
+       }
+
+       if (!(user->acct_ctrl & ACB_NORMAL))
+       {
+               DEBUG(0,("User's acct_ctrl bits not set to ACT_NORMAL in LDAP database\n"));
+               return;
+       }
+}
 
 /************************************************************************
-  Adds a modification to a LDAPMod queue.
- ************************************************************************/
+ Routine to manage the LDAPMod structure array
+ manage memory used by the array, by each struct, and values
 
- void ldap_make_mod(LDAPMod ***modlist,int modop, char *attribute, char *value)
+************************************************************************/
+static void make_a_mod(LDAPMod ***modlist,int modop, char *attribute, char *value)
 {
        LDAPMod **mods;
        int i;
        int j;
-
-       DEBUG(3, ("set: [%s] = [%s]\n", attribute, value));
        
        mods = *modlist;
        
-       if (mods == NULL) {
-               mods = (LDAPMod **)malloc(sizeof(LDAPMod *));
+       if (mods == NULL)
+       {
+               mods = (LDAPMod **)malloc( sizeof(LDAPMod *) );
+               if (mods == NULL)
+               {
+                       DEBUG(0,("make_a_mod: out of memory!\n"));
+                       return;
+               }
                mods[0] = NULL;
        }
        
-       for (i = 0; mods[i] != NULL; ++i) {
-               if (mods[i]->mod_op == modop && 
-                   !strcasecmp(mods[i]->mod_type, attribute)) {
+       for ( i = 0; mods[ i ] ! = NULL; ++i )
+       {
+               if ( mods[ i ]->mod_op == modop && 
+                   !strcasecmp( mods[ i ]->mod_type, attribute ) )
+               {
                        break;
                }
        }
        
-       if (mods[i] == NULL) {
-               mods = (LDAPMod **)realloc(mods, (i+2) * sizeof(LDAPMod *));
-               mods[i] = (LDAPMod *)malloc(sizeof(LDAPMod));
+       if (mods[i] == NULL)
+       {
+               mods = (LDAPMod **)realloc( mods,  (i+2) * sizeof( LDAPMod * ) );       
+               if (mods == NULL)
+               {
+                       DEBUG(0,("make_a_mod: out of memory!\n"));
+                       return;
+               }
+               mods[i] = (LDAPMod *)malloc( sizeof( LDAPMod ) );
+               if (mods[i] == NULL)
+               {
+                       DEBUG(0,("make_a_mod: out of memory!\n"));
+                       return;
+               }
                mods[i]->mod_op = modop;
                mods[i]->mod_values = NULL;
-               mods[i]->mod_type = strdup(attribute);
+               mods[i]->mod_type = strdup( attribute );
                mods[i+1] = NULL;
        }
 
-       if (value) {
+       if (value ! = NULL )
+       {
                j = 0;
-               if (mods[i]->mod_values) {
-                       for (; mods[i]->mod_values[j]; j++);
+               if ( mods[ i ]->mod_values ! = NULL )
+               {
+                       for ( ; mods[ i ]->mod_values[ j ] ! = NULL; j++ );
                }
-               mods[i]->mod_values = (char **)realloc(mods[i]->mod_values,
-                                                 (j+2) * sizeof(char *));
-               mods[i]->mod_values[j] = strdup(value);
-               mods[i]->mod_values[j+1] = NULL;
+               mods[ i ]->mod_values = (char **)realloc(mods[ i ]->mod_values,
+                                                         (j+2) * sizeof( char * ));
+               if ( mods[ i ]->mod_values == NULL)
+               {
+                       DEBUG(0, "make_a_mod: Memory allocation failure!\n");
+                       return;
+               }
+               mods[ i ]->mod_values[ j ] = strdup(value);     
+               mods[ i ]->mod_values[ j + 1 ] = NULL;          
        }
-
        *modlist = mods;
 }
 
-
 /************************************************************************
-  Queues the necessary modifications to save a smb_passwd structure
- ************************************************************************/
+ Add or modify an entry. Only the smb struct values
 
- void ldap_smbpwmods(struct smb_passwd *newpwd, LDAPMod ***mods, int operation)
+*************************************************************************/
+static BOOL modadd_ldappwd_entry(struct smb_passwd *newpwd, int flag)
 {
-       fstring temp;
-       int i;
+       
+       /* assume the struct is correct and filled
+          that's the job of passdb.c to check */
+       int scope = LDAP_SCOPE_ONELEVEL;
+       int rc;
+       char *smb_name;
+       int trust = False;
+       int ldap_state;
+       pstring filter;
+       pstring dn;
+       pstring lmhash;
+       pstring nthash;
+       pstring rid;
+       pstring lst;
+       pstring temp;
 
-       *mods = NULL;
-       if(operation == LDAP_MOD_ADD) { /* immutable attributes */
-             ldap_make_mod(mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
+       LDAP *ldap_struct;
+       LDAPMessage *result;
+       LDAPMod **mods;
+       
+       smb_name = newpwd->smb_name;
 
-             ldap_make_mod(mods, LDAP_MOD_ADD, "uid", newpwd->unix_name);
-             slprintf(temp, sizeof(temp)-1, "%d", newpwd->unix_uid);
-             ldap_make_mod(mods, LDAP_MOD_ADD, "uidNumber", temp);
+       if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+       {
+               return False;
+       }
 
-             ldap_make_mod(mods, LDAP_MOD_ADD, "ntuid", newpwd->nt_name);
-             slprintf(temp, sizeof(temp)-1, "%x", newpwd->user_rid);
-             ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
+       if (!ldap_connect_system(ldap_struct)) /* connect as system account */
+       {
+               ldap_unbind(ldap_struct);
+               return False;
+       }
+       
+       if (smb_name[strlen(smb_name)-1] == '$' )
+       {
+               smb_name[strlen(smb_name)-1] = '\0';
+               trust = True;
        }
 
-       if (newpwd->smb_passwd) {
-             for( i = 0; i < 16; i++) {
-                    slprintf(&temp[2*i], 3, "%02X", newpwd->smb_passwd[i]);
-             }
-             ldap_make_mod(mods, operation, "lmPassword", temp);
+       slprintf(filter, sizeof(filter)-1,
+                "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))",
+                smb_name);
+       
+       rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result);
+
+       switch (flag)
+       {
+               case ADD_USER:
+               {
+                       if (ldap_count_entries(ldap_struct, result) ! = 0)
+                       {
+                               DEBUG(0,("User already in the base, with samba properties\n"));         
+                               ldap_unbind(ldap_struct);
+                               return False;
+                       }
+                       ldap_state = LDAP_MOD_ADD;
+                       break;
+               }
+               case MODIFY_USER:
+               {
+                       if (ldap_count_entries(ldap_struct, result) ! = 1)
+                       {
+                               DEBUG(0,("No user to modify !\n"));             
+                               ldap_unbind(ldap_struct);
+                               return False;
+                       }
+                       ldap_state = LDAP_MOD_REPLACE;
+                       break;
+               }
+               default:
+               {
+                       DEBUG(0,("How did you come here? \n"));         
+                       ldap_unbind(ldap_struct);
+                       return False;
+                       break;
+               }
        }
+       slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() );
 
-       if (newpwd->smb_nt_passwd) {
-             for( i = 0; i < 16; i++) {
-                    slprintf(&temp[2*i], 3, "%02X", newpwd->smb_nt_passwd[i]);
-             }
-             ldap_make_mod(mods, operation, "ntPassword", temp);
+       if (newpwd->smb_passwd ! = NULL)
+       {
+               int i;
+               for( i = 0; i < 16; i++)
+               {
+                       slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_passwd[i]);
+               }
+       
        }
+       else
+       {
+               if (newpwd->acct_ctrl & ACB_PWNOTREQ)
+               {
+                       slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+               }
+               else
+               {
+                       slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+               }
+       }
+       slprintf(lmhash, sizeof(lmhash)-1, "%s", temp);
 
-       newpwd->pass_last_set_time = time(NULL);
-       slprintf(temp, sizeof(temp)-1, "%08X", newpwd->pass_last_set_time);
-       ldap_make_mod(mods, operation, "pwdLastSet", temp);
+       if (newpwd->smb_nt_passwd ! = NULL)
+       {
+               int i;
+               for( i = 0; i < 16; i++)
+               {
+                       slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_nt_passwd[i]);
+               }
+       
+       }
+       else
+       {
+               if (newpwd->acct_ctrl & ACB_PWNOTREQ)
+               {
+                       slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+               }
+               else
+               {
+                       slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+               }
+       }
+       slprintf(nthash, sizeof(nthash)-1, "%s", temp);
 
-       ldap_make_mod(mods, operation, "acctFlags",
-                           pwdb_encode_acct_ctrl(newpwd->acct_ctrl,
-                                  NEW_PW_FORMAT_SPACE_PADDED_LEN));
-}
+       slprintf(rid, sizeof(rid)-1, "%d", uid_to_user_rid(newpwd->smb_userid) );
+       slprintf(lst, sizeof(lst)-1, "%08X", newpwd->pass_last_set_time);
+       
+       mods = NULL; 
 
+       if (trust)
+       {
+               make_a_mod(&mods, ldap_state, "objectclass", "sambaTrust");
+               make_a_mod(&mods, ldap_state, "netbiosTrustName", smb_name);
+               make_a_mod(&mods, ldap_state, "trustPassword", nthash);
+       }
+       else
+       {
+               make_a_mod(&mods, ldap_state, "objectclass", "sambaAccount");
+               make_a_mod(&mods, ldap_state, "dBCSPwd", lmhash);
+               make_a_mod(&mods, ldap_state, "uid", smb_name);
+               make_a_mod(&mods, ldap_state, "unicodePwd", nthash);
+       }
+       
+       make_a_mod(&mods, ldap_state, "cn", smb_name);
+       
+       make_a_mod(&mods, ldap_state, "rid", rid);
+       make_a_mod(&mods, ldap_state, "pwdLastSet", lst);
+       make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+       
+       switch(flag)
+       {
+               case ADD_USER:
+               {
+                       ldap_add_s(ldap_struct, dn, mods);
+                       DEBUG(2,("modadd_ldappwd_entry: added: cn = %s in the LDAP database\n",smb_name));
+                       break;
+               }
+               case MODIFY_USER:
+               {
+                       ldap_modify_s(ldap_struct, dn, mods);
+                       DEBUG(2,("modadd_ldappwd_entry: changed: cn = %s in the LDAP database_n",smb_name));
+                       break;
+               }
+               default:
+               {
+                       DEBUG(2,("modadd_ldappwd_entry: How did you come here? \n"));           
+                       ldap_unbind(ldap_struct);
+                       return False;
+                       break;
+               }
+       }
+       
+       ldap_mods_free(mods, 1);
+       
+       ldap_unbind(ldap_struct);
+       
+       return True;
+}
 
 /************************************************************************
-  Commit changes to a directory entry.
- *************************************************************************/
- BOOL ldap_makemods(char *attribute, char *value, LDAPMod **mods, BOOL add)
+ Add or modify an entry. everything except the smb struct
+
+*************************************************************************/
+static BOOL modadd_ldap21pwd_entry(struct sam_passwd *newpwd, int flag)
 {
+       
+       /* assume the struct is correct and filled
+          that's the job of passdb.c to check */
+       int scope = LDAP_SCOPE_ONELEVEL;
+       int rc;
+       char *smb_name;
+       int trust = False;
+       int ldap_state;
        pstring filter;
-       char *dn;
-       int entries;
-       int err = 0;
-       BOOL rc;
-
-       slprintf(filter, sizeof(filter)-1, "%s=%s", attribute, value);
+       pstring dn;
+       pstring lmhash;
+       pstring nthash;
+       pstring rid;
+       pstring lst;
+       pstring temp;
 
-       if (!ldap_connect())
-               return (False);
+       LDAP *ldap_struct;
+       LDAPMessage *result;
+       LDAPMod **mods;
+       
+       smb_name = newpwd->smb_name;
 
-       ldap_search_for(filter);
+       if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
+       {
+               return False;
+       }
 
-       if (ldap_entry)
+       if (!ldap_connect_system(ldap_struct)) /* connect as system account */
        {
-               dn = ldap_get_dn(ldap_struct, ldap_entry);
-               err = ldap_modify_s(ldap_struct, dn, mods);
-               free(dn);
+               ldap_unbind(ldap_struct);
+               return False;
        }
-       else if (add)
+       
+       if (smb_name[strlen(smb_name)-1] == '$' )
        {
-               pstrcat(filter, ", ");
-               pstrcat(filter, lp_ldap_suffix());
-               err = ldap_add_s(ldap_struct, filter, mods);
+               smb_name[strlen(smb_name)-1] = '\0';
+               trust = True;
        }
 
-       if (err == LDAP_SUCCESS)
+       slprintf(filter, sizeof(filter)-1,
+                "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))",
+                smb_name);
+       
+       rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result);
+
+       switch (flag)
        {
-               DEBUG(2,("Updated entry [%s]\n", value));
-               rc = True;
-       } else {
-               DEBUG(0,("update: %s\n", ldap_err2string(err)));
-               rc = False;
+               case ADD_USER:
+               {
+                       if (ldap_count_entries(ldap_struct, result) ! = 1)
+                       {
+                               DEBUG(2,("User already in the base, with samba properties\n"));         
+                               ldap_unbind(ldap_struct);
+                               return False;
+                       }
+                       ldap_state = LDAP_MOD_ADD;
+                       break;
+               }
+
+               case MODIFY_USER:
+               {
+                       if (ldap_count_entries(ldap_struct, result) ! = 1)
+                       {
+                               DEBUG(2,("No user to modify !\n"));             
+                               ldap_unbind(ldap_struct);
+                               return False;
+                       }
+                       ldap_state = LDAP_MOD_REPLACE;
+                       break;
+               }
+
+               default:
+               {
+                       DEBUG(2,("How did you come here? \n"));         
+                       ldap_unbind(ldap_struct);
+                       return False;
+                       break;
+               }
        }
+       slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() );
+       
+       mods = NULL; 
 
-       ldap_disconnect();
+       if (trust)
+       {
+       }
+       else
+       {
+       }
+       
+       make_a_mod(&mods, ldap_state, "cn", smb_name);
+       
+       make_a_mod(&mods, ldap_state, "rid", rid);
+       make_a_mod(&mods, ldap_state, "pwdLastSet", lst);
+       make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl,NEW_PW_FORMAT_SPACE_PADDED_LEN));
+       
+       ldap_modify_s(ldap_struct, dn, mods);
+       
        ldap_mods_free(mods, 1);
-       return rc;
+       
+       ldap_unbind(ldap_struct);
+       
+       return True;
 }
 
+/************************************************************************
+ Routine to add an entry to the ldap passwd file.
+
+ do not call this function directly.  use passdb.c instead.
+
+*************************************************************************/
+static BOOL add_ldappwd_entry(struct smb_passwd *newpwd)
+{
+       return (modadd_ldappwd_entry(newpwd, ADD_USER) );
+}
 
 /************************************************************************
-  Return next available RID, starting from 1000
- ************************************************************************/
+ Routine to search the ldap passwd file for an entry matching the username.
+ and then modify its password entry. We can't use the startldappwent()/
+ getldappwent()/endldappwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out password or NO PASS
 
-BOOL ldap_allocaterid(uint32 *rid)
+ do not call this function directly.  use passdb.c instead.
+
+************************************************************************/
+static BOOL mod_ldappwd_entry(struct smb_passwd *pwd, BOOL override)
 {
-       pstring newdn;
-       fstring rid_str;
-       LDAPMod **mods;
-       char *dn;
-       int err;
+       return (modadd_ldappwd_entry(pwd, MODIFY_USER) );
+}
 
-       DEBUG(2, ("Allocating new RID\n"));
+/************************************************************************
+ Routine to add an entry to the ldap passwd file.
 
-       if (!ldap_connect())
-               return (False);
+ do not call this function directly.  use passdb.c instead.
 
-       ldap_search_for("(&(id=root)(objectClass=sambaConfig))");
+*************************************************************************/
+static BOOL add_ldap21pwd_entry(struct sam_passwd *newpwd)
+{      
+       return( modadd_ldappwd_entry(newpwd, ADD_USER)?
+       modadd_ldap21pwd_entry(newpwd, ADD_USER):False);
+}
 
-       if (ldap_entry && ldap_get_attribute("nextrid", rid_str))
-               *rid = strtol(rid_str, NULL, 16);
-       else
-               *rid = 1000;
+/************************************************************************
+ Routine to search the ldap passwd file for an entry matching the username.
+ and then modify its password entry. We can't use the startldappwent()/
+ getldappwent()/endldappwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out password or NO PASS
 
-       mods = NULL;
-       if(!ldap_entry)
-       {
-               ldap_make_mod(&mods, LDAP_MOD_ADD, "objectClass",
-                             "sambaConfig");
-               ldap_make_mod(&mods, LDAP_MOD_ADD, "id", "root");
-       }
+ do not call this function directly.  use passdb.c instead.
+
+************************************************************************/
+static BOOL mod_ldap21pwd_entry(struct sam_passwd *pwd, BOOL override)
+{
+       return( modadd_ldappwd_entry(pwd, MODIFY_USER)?
+       modadd_ldap21pwd_entry(pwd, MODIFY_USER):False);
+}
+
+struct ldap_enum_info
+{
+       LDAP *ldap_struct;
+       LDAPMessage *result;
+       LDAPMessage *entry;
+};
+
+static struct ldap_enum_info ldap_ent;
+
+/***************************************************************
+ Start to enumerate the ldap passwd list. Returns a void pointer
+ to ensure no modification outside this module.
+
+ do not call this function directly.  use passdb.c instead.
 
-       slprintf(rid_str, sizeof(fstring)-1, "%x", (*rid) + 1);
-       ldap_make_mod(&mods, LDAP_MOD_REPLACE, "nextrid", rid_str);
+ ****************************************************************/
+static void *startldappwent(BOOL update)
+{
+       int scope = LDAP_SCOPE_ONELEVEL;
+       int rc;
 
-       if (ldap_entry)
+       pstring filter;
+
+       if (!ldap_open_connection(&ldap_ent.ldap_struct)) /* open a connection to the server */
        {
-                dn = ldap_get_dn(ldap_struct, ldap_entry);
-                err = ldap_modify_s(ldap_struct, dn, mods);
-                free(dn);
-       } else {
-               pstrcpy(newdn, "id=root, ");
-               pstrcat(newdn, lp_ldap_suffix());
-               ldap_add_s(ldap_struct, newdn, mods);
+               return NULL;
        }
 
-       ldap_disconnect();
+       if (!ldap_connect_system(ldap_ent.ldap_struct)) /* connect as system account */
+       {
+               return NULL;
+       }
 
-       if(err != LDAP_SUCCESS)
+       /* when the class is known the search is much faster */
+       switch (0)
        {
-               DEBUG(0,("nextrid update: %s\n", ldap_err2string(err)));
-               return (False);
+               case 1:
+               {
+                       pstrcpy(filter, "objectclass = sambaAccount");
+                       break;
+               }
+               case 2:
+               {
+                       pstrcpy(filter, "objectclass = sambaTrust");
+                       break;
+               }
+               default:
+               {
+                       pstrcpy(filter, "(|(objectclass = sambaTrust)(objectclass = sambaAccount))");
+                       break;
+               }
        }
 
-       return (True);
+       rc = ldap_search_s(ldap_ent.ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &ldap_ent.result);
+
+       DEBUG(2,("%d entries in the base!\n", ldap_count_entries(ldap_ent.ldap_struct, ldap_ent.result) ));
+
+       ldap_ent.entry = ldap_first_entry(ldap_ent.ldap_struct, ldap_ent.result);
+
+       return &ldap_ent;
 }
 
+/*************************************************************************
+ Routine to return the next entry in the ldap passwd list.
 
-/***************************************************************
-  Begin/end account enumeration.
- ****************************************************************/
+ do not call this function directly.  use passdb.c instead.
 
-static void *ldap_enumfirst(BOOL update)
+ *************************************************************************/
+static struct smb_passwd *getldappwent(void *vp)
 {
-       if (!ldap_connect())
-               return NULL;
+       static struct smb_passwd user;
+       struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
 
-       ldap_search_for("objectclass=sambaAccount");
+       ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry);
 
-       return ldap_struct;
+       if (ldap_vp->entry ! = NULL)
+       {
+               ldap_get_smb_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user);
+               return &user;
+       }
+       return NULL;
 }
 
-static void ldap_enumclose(void *vp)
-{
-       ldap_disconnect();
-}
+/*************************************************************************
+ Routine to return the next entry in the ldap passwd list.
 
+ do not call this function directly.  use passdb.c instead.
 
-/*************************************************************************
-  Save/restore the current position in a query
  *************************************************************************/
-
-static SMB_BIG_UINT ldap_getdbpos(void *vp)
+static struct sam_passwd *getldap21pwent(void *vp)
 {
-       return (SMB_BIG_UINT)((ulong)ldap_entry);
-}
+       static struct sam_passwd user;
+       struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
 
-static BOOL ldap_setdbpos(void *vp, SMB_BIG_UINT tok)
-{
-       ldap_entry = (LDAPMessage *)((ulong)tok);
-       return (True);
+       ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry);
+
+       if (ldap_vp->entry ! = NULL)
+       {
+               ldap_get_sam_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user);
+               return &user;
+       }
+       return NULL;
 }
 
+/***************************************************************
+ End enumeration of the ldap passwd list.
 
-/*************************************************************************
-  Return smb_passwd information.
- *************************************************************************/
+ do not call this function directly.  use passdb.c instead.
 
-static struct smb_passwd *ldap_getpwbynam(const char *name)
+****************************************************************/
+static void endldappwent(void *vp)
 {
-       struct smb_passwd *ret;
-
-       if(!ldap_connect())
-               return NULL;
+       struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
+       ldap_msgfree(ldap_vp->result);
+       ldap_unbind(ldap_vp->ldap_struct);
+}
 
-       ldap_search_by_name(name);
-       ret = ldap_getpw();
+/*************************************************************************
+ Return the current position in the ldap passwd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
 
-       ldap_disconnect();
-       return ret;
-}
+ do not call this function directly.  use passdb.c instead.
 
-static struct smb_passwd *ldap_getpwbyuid(uid_t userid)
+*************************************************************************/
+static SMB_BIG_UINT getldappwpos(void *vp)
 {
-       struct smb_passwd *ret;
+       return (SMB_BIG_UINT)0;
+}
 
-       if(!ldap_connect())
-               return NULL;
+/*************************************************************************
+ Set the current position in the ldap passwd list from SMB_BIG_UINT.
+ This must be treated as an opaque token.
 
-       ldap_search_by_uid(userid);
-       ret = ldap_getpw();
+ do not call this function directly.  use passdb.c instead.
 
-       ldap_disconnect();
-       return ret;
+*************************************************************************/
+static BOOL setldappwpos(void *vp, SMB_BIG_UINT tok)
+{
+       return False;
 }
 
-static struct smb_passwd *ldap_getcurrentpw(void *vp)
-{
-       struct smb_passwd *ret;
+/*
+ * Ldap derived functions.
+ */
 
-       ret = ldap_getpw();
-       ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
-       return ret;
+static struct smb_passwd *getldappwnam(char *name)
+{
+  return pdb_sam_to_smb(iterate_getsam21pwnam(name));
 }
 
+static struct smb_passwd *getldappwuid(uid_t smb_userid)
+{
+  return pdb_sam_to_smb(iterate_getsam21pwuid(smb_userid));
+}
 
-/************************************************************************
-  Modify user information given an smb_passwd struct.
- *************************************************************************/
-static BOOL ldap_addpw(struct smb_passwd *newpwd)
+static struct smb_passwd *getldappwrid(uint32 user_rid)
 {
-       LDAPMod **mods;
+  return pdb_sam_to_smb(iterate_getsam21pwuid(pdb_user_rid_to_uid(user_rid)));
+}
 
-       if (!newpwd || !ldap_allocaterid(&newpwd->user_rid))
-               return (False);
+static struct smb_passwd *getldappwent(void *vp)
+{
+  return pdb_sam_to_smb(getldap21pwent(vp));
+}
 
-       ldap_smbpwmods(newpwd, &mods, LDAP_MOD_ADD);
-       return ldap_makemods("uid", newpwd->unix_name, mods, True);
+static BOOL add_ldappwd_entry(struct smb_passwd *newpwd)
+{
+  return add_ldap21pwd_entry(pdb_smb_to_sam(newpwd));
 }
 
-static BOOL ldap_modpw(struct smb_passwd *pwd, BOOL override)
+static BOOL mod_ldappwd_entry(struct smb_passwd* pwd, BOOL override)
 {
-       LDAPMod **mods;
+  return mod_ldap21pwd_entry(pdb_smb_to_sam(pwd), override);
+}
 
-       if (!pwd)
-               return (False);
+static struct sam_disp_info *getldapdispnam(char *name)
+{
+       return pdb_sam_to_dispinfo(getldap21pwnam(name));
+}
 
-       ldap_smbpwmods(pwd, &mods, LDAP_MOD_REPLACE);
-       return ldap_makemods("uid", pwd->unix_name, mods, False);
+static struct sam_disp_info *getldapdisprid(uint32 rid)
+{
+       return pdb_sam_to_dispinfo(getldap21pwrid(rid));
 }
 
+static struct sam_disp_info *getldapdispent(void *vp)
+{
+       return pdb_sam_to_dispinfo(getldap21pwent(vp));
+}
 
-static struct smb_passdb_ops ldap_ops =
+static struct sam_passwd *getldap21pwuid(uid_t uid)
 {
-       ldap_enumfirst,
-       ldap_enumclose,
-       ldap_getdbpos,
-       ldap_setdbpos,
+       return pdb_smb_to_sam(iterate_getsam21pwuid(pdb_uid_to_user_rid(uid)));
+}
 
-       ldap_getpwbynam,
-       ldap_getpwbyuid,
-       ldap_getcurrentpw,
-       ldap_addpw,
-       ldap_modpw
+static struct passdb_ops ldap_ops =
+{
+       startldappwent,
+       endldappwent,
+       getldappwpos,
+       setldappwpos,
+       getldappwnam,
+       getldappwuid,
+       getldappwrid,
+       getldappwent,
+       add_ldappwd_entry,
+       mod_ldappwd_entry,
+       getldap21pwent,
+       iterate_getsam21pwnam,       /* From passdb.c */
+       iterate_getsam21pwuid,       /* From passdb.c */
+       iterate_getsam21pwrid,       /* From passdb.c */
+       add_ldap21pwd_entry,
+       mod_ldap21pwd_entry,
+       getldapdispnam,
+       getldapdisprid,
+       getldapdispent
 };
 
-struct smb_passdb_ops *ldap_initialise_password_db(void)
+struct passdb_ops *ldap_initialize_password_db(void)
 {
-       FILE *pwdfile;
-       char *pwdfilename;
-       char *p;
-
-       pwdfilename = lp_ldap_passwd_file();
-
-       if(pwdfilename[0]) {
-               if(pwdfile = sys_fopen(pwdfilename, "r")) {
-                       fgets(ldap_secret, sizeof(ldap_secret), pwdfile);
-                       if(p = strchr(ldap_secret, '\n'))
-                               *p = 0;
-                       fclose(pwdfile);
-               } else {
-                       DEBUG(0,("Failed to open LDAP passwd file\n"));
-               }
-       }
-
-       return &ldap_ops;
+  return &ldap_ops;
 }
 
 #else
- void ldap_dummy_function(void);
- void ldap_dummy_function(void) { } /* stop some compilers complaining */
+ void dummy_function(void);
+ void dummy_function(void) { } /* stop some compilers complaining */
 #endif
index f554958adebd2c7bd232184b97a0240fb346aa1e..27409eca4cd4fdfbcb1ba85b495765d06ec756f5 100644 (file)
  * Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "includes.h"
+
 #ifdef WITH_NISPLUS
 
-#include "includes.h"
+#ifdef BROKEN_NISPLUS_INCLUDE_FILES
+
+/*
+ * The following lines are needed due to buggy include files
+ * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
+ * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
+ * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
+ * an enum in /usr/include/rpcsvc/nis.h.
+ */
+
+#if defined(GROUP)
+#undef GROUP
+#endif
+
+#if defined(GROUP_OBJ)
+#undef GROUP_OBJ
+#endif
+
+#endif
+
 #include <rpcsvc/nis.h>
 
 extern int      DEBUGLEVEL;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
 
-static int gotalarm;
+static VOLATILE SIG_ATOMIC_T gotalarm;
 
 /***************************************************************
 
@@ -154,9 +177,218 @@ static void get_single_attribute(nis_object *new_obj, int col,
                len = entry_len;
        }
 
-       safe_strcpy(val, len, ENTRY_VAL(new_obj, col));
+       safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
 }
 
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ object.
+ ************************************************************************/
+static BOOL make_sam_from_nisp_object(struct sam_passwd *pw_buf, nis_object *obj)
+{
+       int uidval;
+       static pstring user_name;
+       static pstring full_name;
+       static pstring home_dir;
+       static pstring home_drive;
+       static pstring logon_script;
+       static pstring profile_path;
+       static pstring acct_desc;
+       static pstring workstations;
+       static pstring temp;
+       static unsigned char smbpwd[16];
+       static unsigned char smbntpwd[16];
+       
+       char *p;
+
+       pdb_init_sam(pw_buf);
+       pw_buf->acct_ctrl = ACB_NORMAL;
+
+       pstrcpy(user_name, ENTRY_VAL(obj, NPF_NAME));
+       pw_buf->smb_name      = user_name;
+
+       uidval = atoi(ENTRY_VAL(obj, NPF_UID));
+       pw_buf->smb_userid    = uidval;         
+
+       /* Check the lanman password column. */
+       p = (char *)ENTRY_VAL(obj, NPF_LMPWD);
+       if (*p == '*' || *p == 'X') {
+         /* Password deliberately invalid - end here. */
+         DEBUG(10, ("make_sam_from_nisp_object: entry invalidated for user %s\n", user_name));
+         pw_buf->smb_nt_passwd = NULL;
+         pw_buf->smb_passwd = NULL;
+         pw_buf->acct_ctrl |= ACB_DISABLED;
+         return True;
+       }
+       if (!strncasecmp(p, "NO PASSWORD", 11)) {
+         pw_buf->smb_passwd = NULL;
+         pw_buf->acct_ctrl |= ACB_PWNOTREQ;
+       } else {
+         if (strlen(p) != 32 || !pdb_gethexpwd(p, smbpwd))
+           {
+             DEBUG(0, ("make_sam_from_nisp_object: malformed LM pwd entry.\n"));
+             return False;
+           }
+       }
+
+       pw_buf->smb_passwd    = smbpwd;
+
+       /* Check the NT password column. */
+       p = ENTRY_VAL(obj, NPF_NTPWD);
+       if (*p != '*' && *p != 'X') {
+         if (strlen(p) != 32 || !pdb_gethexpwd(p, smbntpwd))
+           {
+             DEBUG(0, ("make_smb_from_nisp_object: malformed NT pwd entry\n"));
+             return False;
+           }
+         pw_buf->smb_nt_passwd = smbntpwd;
+       }
+
+       p = (char *)ENTRY_VAL(obj, NPF_ACB);
+       if (*p == '[')
+         {
+           pw_buf->acct_ctrl = pdb_decode_acct_ctrl(p);
+           
+           /* Must have some account type set. */
+           if(pw_buf->acct_ctrl == 0)
+             pw_buf->acct_ctrl = ACB_NORMAL;
+           
+           /* Now try and get the last change time. */
+           if(*p == ']')
+             p++;
+           if(*p == ':') {
+             p++;
+             if(*p && (StrnCaseCmp(p, "LCT-", 4)==0)) {
+               int i;
+               p += 4;
+               for(i = 0; i < 8; i++) {
+                 if(p[i] == '\0' || !isxdigit(p[i]))
+                   break;
+               }
+               if(i == 8) {
+                 /*
+                  * p points at 8 characters of hex digits - 
+                  * read into a time_t as the seconds since
+                  * 1970 that the password was last changed.
+                  */
+                 pw_buf->pass_last_set_time = (time_t)strtol(p, NULL, 16);
+               }
+             }
+           }
+       } else {
+         /* 'Old' style file. Fake up based on user name. */
+         /*
+          * Currently trust accounts are kept in the same
+          * password file as 'normal accounts'. If this changes
+          * we will have to fix this code. JRA.
+          */
+         if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
+           pw_buf->acct_ctrl &= ~ACB_NORMAL;
+           pw_buf->acct_ctrl |= ACB_WSTRUST;
+         }
+       }
+
+       get_single_attribute(obj, NPF_SMB_GRPID, temp, sizeof(pstring));
+       pw_buf->smb_grpid = atoi(temp);
+
+       get_single_attribute(obj, NPF_USER_RID, temp, sizeof(pstring));
+       pw_buf->user_rid = (strlen(temp) > 0) ?
+         strtol(temp, NULL, 16) : pdb_uid_to_user_rid (pw_buf->smb_userid);
+
+       if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$') {
+         
+         /* XXXX hack to get standard_sub_basic() to use sam logon username */
+         /* possibly a better way would be to do a become_user() call */
+         pstrcpy(samlogon_user, pw_buf->smb_name);
+         sam_logon_in_ssb = True;
+         
+         get_single_attribute(obj, NPF_GROUP_RID, temp, sizeof(pstring));
+         pw_buf->group_rid = (strlen(temp) > 0) ?
+           strtol(temp, NULL, 16) : pdb_gid_to_group_rid (pw_buf->smb_grpid);
+         
+         get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
+#if 1
+         /* It seems correct to use the global values - but in that case why
+          * do we want these NIS+ entries anyway ??
+          */
+         pstrcpy(logon_script , lp_logon_script       ());
+         pstrcpy(profile_path , lp_logon_path         ());
+         pstrcpy(home_drive   , lp_logon_drive        ());
+         pstrcpy(home_dir     , lp_logon_home         ());
+#else
+         get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script, sizeof(pstring));
+         get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
+         get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
+         get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
+#endif
+         get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
+         get_single_attribute(obj, NPF_WORKSTATIONS, workstations, sizeof(pstring));
+         
+         sam_logon_in_ssb = False;
+
+       } else {
+         
+         pw_buf->group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+         
+         pstrcpy(full_name    , "");
+         pstrcpy(logon_script , "");
+         pstrcpy(profile_path , "");
+         pstrcpy(home_drive   , "");
+         pstrcpy(home_dir     , "");
+         pstrcpy(acct_desc    , "");
+         pstrcpy(workstations , "");
+       }
+
+       pw_buf->full_name    = full_name;
+       pw_buf->home_dir     = home_dir;
+       pw_buf->dir_drive    = home_drive;
+       pw_buf->logon_script = logon_script;
+       pw_buf->profile_path = profile_path;
+       pw_buf->acct_desc    = acct_desc;
+       pw_buf->workstations = workstations;
+
+       pw_buf->unknown_str = NULL; /* don't know, yet! */
+       pw_buf->munged_dial = NULL; /* "munged" dial-back telephone number */
+
+       pw_buf->unknown_3 = 0xffffff; /* don't know */
+       pw_buf->logon_divs = 168; /* hours per week */
+       pw_buf->hours_len = 21; /* 21 times 8 bits = 168 */
+       memset(pw_buf->hours, 0xff, pw_buf->hours_len); /* available at all hours */
+       pw_buf->unknown_5 = 0x00020000; /* don't know */
+       pw_buf->unknown_6 = 0x000004ec; /* don't know */
+
+       return True;
+}
+
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ result.
+ ************************************************************************/
+static BOOL make_sam_from_nisresult(struct sam_passwd *pw_buf, nis_result *result)
+{
+       if (pw_buf == NULL || result == NULL) return False;
+
+       if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
+       {
+               DEBUG(0, ("make_sam_from_nisresult: NIS+ lookup failure: %s\n",
+                          nis_sperrno(result->status)));
+               return False;
+       }
+
+       /* User not found. */
+       if (NIS_RES_NUMOBJ(result) <= 0)
+       {
+               DEBUG(10, ("make_sam_from_nisresult: user not found in NIS+\n"));
+               return False;
+       }
+
+       if (NIS_RES_NUMOBJ(result) > 1)
+       {
+               DEBUG(10, ("make_sam_from_nisresult: WARNING: Multiple entries for user in NIS+ table!\n"));
+       }
+
+       /* Grab the first hit. */
+       return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
+      }
+
 /***************************************************************
  calls nis_list, returns results.
  ****************************************************************/
@@ -205,21 +437,36 @@ static void *startnisppwent(BOOL update)
 ****************************************************************/
 static void endnisppwent(void *vp)
 {
+  struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
+  nis_freeresult(res->result);
+  DEBUG(7,("endnisppwent: freed enumeration list\n"));
 }
 
 /*************************************************************************
  Routine to return the next entry in the nisplus passwd list.
- this function is a nice, messy combination of reading:
- - the nisplus passwd file
- - the unix password database
- - nisp.conf options (not done at present).
 
  do not call this function directly.  use passdb.c instead.
 
  *************************************************************************/
 static struct sam_passwd *getnisp21pwent(void *vp)
 {
-       return NULL;
+  struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
+  static struct sam_passwd pw_buf;
+  int which;
+  BOOL ret;
+  
+  if (res == NULL || (int)(res->enum_entry) < 0 ||
+      (int)(res->enum_entry) > (NIS_RES_NUMOBJ(res->result) - 1)) {
+    ret = False;
+  } else {
+    which = (int)(res->enum_entry);
+    ret = make_sam_from_nisp_object(&pw_buf,
+                &NIS_RES_OBJECT(res->result)[which]);
+    if (ret && which < (NIS_RES_NUMOBJ(res->result) - 1))
+      (int)(res->enum_entry)++;
+  }
+  
+  return ret ? &pw_buf : NULL;
 }
 
 /*************************************************************************
@@ -231,7 +478,8 @@ static struct sam_passwd *getnisp21pwent(void *vp)
 *************************************************************************/
 static SMB_BIG_UINT getnisppwpos(void *vp)
 {
-       return (SMB_BIG_UINT)0;
+  struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
+  return (SMB_BIG_UINT)(res->enum_entry);
 }
 
 /*************************************************************************
@@ -243,7 +491,13 @@ static SMB_BIG_UINT getnisppwpos(void *vp)
 *************************************************************************/
 static BOOL setnisppwpos(void *vp, SMB_BIG_UINT tok)
 {
-       return False;
+  struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
+  if (tok < (NIS_RES_NUMOBJ(res->result) - 1)) {
+    res->enum_entry = tok;
+    return True;
+  } else {
+    return False;
+  }
 }
 
 /*************************************************************************
@@ -255,7 +509,7 @@ static void set_single_attribute(nis_object *new_obj, int col,
        if (new_obj == NULL) return;
 
        ENTRY_VAL(new_obj, col) = val;
-       ENTRY_LEN(new_obj, col) = len;
+       ENTRY_LEN(new_obj, col) = len+1;
 
        if (flags != 0)
        {
@@ -295,12 +549,12 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        fstring pwdlchg_t;
        fstring pwdmchg_t;
 
-       bzero(logon_t  , sizeof(logon_t  ));
-       bzero(logoff_t , sizeof(logoff_t ));
-       bzero(kickoff_t, sizeof(kickoff_t));
-       bzero(pwdlset_t, sizeof(pwdlset_t));
-       bzero(pwdlchg_t, sizeof(pwdlchg_t));
-       bzero(pwdmchg_t, sizeof(pwdmchg_t));
+       memset((char *)logon_t  , '\0', sizeof(logon_t  ));
+       memset((char *)logoff_t , '\0', sizeof(logoff_t ));
+       memset((char *)kickoff_t, '\0', sizeof(kickoff_t));
+       memset((char *)pwdlset_t, '\0', sizeof(pwdlset_t));
+       memset((char *)pwdlchg_t, '\0', sizeof(pwdlchg_t));
+       memset((char *)pwdmchg_t, '\0', sizeof(pwdmchg_t));
 
        pfile = lp_smb_passwd_file();
 
@@ -308,19 +562,17 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        result = nisp_get_nis_list(nisname);
        if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
        {
-               DEBUG(3, ( "add_nisppwd_entry: nis_list failure: %s: %s\n",
+               DEBUG(3, ( "add_nis21ppwd_entry: nis_list failure: %s: %s\n",
                            nisname,  nis_sperrno(result->status)));
-               nis_freeresult(nis_user);
                nis_freeresult(result);
                return False;
        }   
 
        if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
        {
-               DEBUG(3, ("add_nisppwd_entry: User already exists in NIS+ password db: %s\n",
+               DEBUG(3, ("add_nisp21pwd_entry: User already exists in NIS+ password db: %s\n",
                            pfile));
                nis_freeresult(result);
-               nis_freeresult(nis_user);
                return False;
        }
 
@@ -328,10 +580,9 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        /* User not found. */
        if (!add_user)
        {
-               DEBUG(3, ("add_nisppwd_entry: User not found in NIS+ password db: %s\n",
+               DEBUG(3, ("add_nisp21pwd_entry: User not found in NIS+ password db: %s\n",
                            pfile));
                nis_freeresult(result);
-               nis_freeresult(nis_user);
                return False;
        }
 
@@ -341,9 +592,8 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        if (tblresult->status != NIS_SUCCESS)
        {
                nis_freeresult(result);
-               nis_freeresult(nis_user);
                nis_freeresult(tblresult);
-               DEBUG(3, ( "add_nisppwd_entry: nis_lookup failure: %s\n",
+               DEBUG(3, ( "add_nisp21pwd_entry: nis_lookup failure: %s\n",
                            nis_sperrno(tblresult->status)));
                return False;
        }
@@ -361,22 +611,37 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len = NIS_RES_OBJECT(tblresult)->zo_data.objdata_u.ta_data.ta_maxcol;
        new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val = calloc(new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len, sizeof(entry_col));
 
-       pwdb_sethexpwd(smb_passwd   , newpwd->smb_passwd   , newpwd->acct_ctrl);
-       pwdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
+       if (new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val == NULL)
+       {
+               DEBUG(0, ("add_nisp21pwd_entry: memory allocation failure\n"));
+               nis_freeresult(result);
+               nis_freeresult(tblresult);
+               return False;
+       }
+
+       pdb_sethexpwd(smb_passwd   , newpwd->smb_passwd   , newpwd->acct_ctrl);
+       pdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
+
+       newpwd->pass_last_set_time = (time_t)time(NULL);
+       newpwd->logon_time = (time_t)-1;
+       newpwd->logoff_time = (time_t)-1;
+       newpwd->kickoff_time = (time_t)-1;
+       newpwd->pass_can_change_time = (time_t)-1;
+       newpwd->pass_must_change_time = (time_t)-1;
 
-       pwdb_set_logon_time      (logon_t  , sizeof(logon_t  ), newpwd->logon_time           );
-       pwdb_set_logoff_time     (logoff_t , sizeof(logoff_t ), newpwd->logoff_time          );
-       pwdb_set_kickoff_time    (kickoff_t, sizeof(kickoff_t), newpwd->kickoff_time         );
-       pwdb_set_last_set_time   (pwdlset_t, sizeof(pwdlset_t), newpwd->pass_last_set_time   ); 
-       pwdb_set_can_change_time (pwdlchg_t, sizeof(pwdlchg_t), newpwd->pass_can_change_time ); 
-       pwdb_set_must_change_time(pwdmchg_t, sizeof(pwdmchg_t), newpwd->pass_must_change_time); 
+       slprintf(logon_t,   13, "LNT-%08X", (uint32)newpwd->logon_time);
+       slprintf(logoff_t,  13, "LOT-%08X", (uint32)newpwd->logoff_time);
+       slprintf(kickoff_t, 13, "KOT-%08X", (uint32)newpwd->kickoff_time);
+       slprintf(pwdlset_t, 13, "LCT-%08X", (uint32)newpwd->pass_last_set_time);
+       slprintf(pwdlchg_t, 13, "CCT-%08X", (uint32)newpwd->pass_can_change_time);
+       slprintf(pwdmchg_t, 13, "MCT-%08X", (uint32)newpwd->pass_must_change_time);
 
-       slprintf(uid, sizeof(uid), "%u", newpwd->unix_uid);
+       slprintf(uid, sizeof(uid), "%u", newpwd->smb_userid);
        slprintf(user_rid, sizeof(user_rid), "0x%x", newpwd->user_rid);
        slprintf(smb_grpid, sizeof(smb_grpid), "%u", newpwd->smb_grpid);
        slprintf(group_rid, sizeof(group_rid), "0x%x", newpwd->group_rid);
 
-       safe_strcpy(acb, pwdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)); 
+       safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)-1); 
 
        set_single_attribute(&new_obj, NPF_NAME          , newpwd->smb_name     , strlen(newpwd->smb_name)     , 0);
        set_single_attribute(&new_obj, NPF_UID           , uid                  , strlen(uid)                  , 0);
@@ -392,6 +657,7 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        set_single_attribute(&new_obj, NPF_PWDLSET_T     , pwdlset_t            , strlen(pwdlset_t)            , 0);
        set_single_attribute(&new_obj, NPF_PWDLCHG_T     , pwdlchg_t            , strlen(pwdlchg_t)            , 0);
        set_single_attribute(&new_obj, NPF_PWDMCHG_T     , pwdmchg_t            , strlen(pwdmchg_t)            , 0);
+#if 0
        set_single_attribute(&new_obj, NPF_FULL_NAME     , newpwd->full_name    , strlen(newpwd->full_name)    , 0);
        set_single_attribute(&new_obj, NPF_HOME_DIR      , newpwd->home_dir     , strlen(newpwd->home_dir)     , 0);
        set_single_attribute(&new_obj, NPF_DIR_DRIVE     , newpwd->dir_drive    , strlen(newpwd->dir_drive)    , 0);
@@ -400,26 +666,24 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
        set_single_attribute(&new_obj, NPF_ACCT_DESC     , newpwd->acct_desc    , strlen(newpwd->acct_desc)    , 0);
        set_single_attribute(&new_obj, NPF_WORKSTATIONS  , newpwd->workstations , strlen(newpwd->workstations) , 0);
        set_single_attribute(&new_obj, NPF_HOURS         , newpwd->hours        , newpwd->hours_len            , 0);
+#endif
 
        obj = &new_obj;
 
        addresult = nis_add_entry(pfile, obj, ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
 
-       nis_freeresult(nis_user);
-       if (tblresult)
-       {
-               nis_freeresult(tblresult);
-       }
 
        if (addresult->status != NIS_SUCCESS)
        {
-               DEBUG(3, ( "add_nisppwd_entry: NIS+ table update failed: %s\n",
+               DEBUG(3, ( "add_nisp21pwd_entry: NIS+ table update failed: %s\n",
                            nisname, nis_sperrno(addresult->status)));
+               nis_freeresult(tblresult);
                nis_freeresult(addresult);
                nis_freeresult(result);
                return False;
        }
 
+       nis_freeresult(tblresult);
        nis_freeresult(addresult);
        nis_freeresult(result);
 
@@ -439,73 +703,198 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
 ************************************************************************/
 static BOOL mod_nisp21pwd_entry(struct sam_passwd* pwd, BOOL override)
 {
-       return False;
+  char *oldnislmpwd, *oldnisntpwd, *oldnisacb, *oldnislct, *user_name;
+  char lmpwd[33], ntpwd[33], lct[13];
+  nis_result *result, *addresult;
+  nis_object *obj;
+  fstring acb;
+  pstring nisname;
+  BOOL got_pass_last_set_time, ret;
+  int i;
+  
+  if (!*lp_smb_passwd_file())
+    {
+      DEBUG(0, ("mod_getnisp21pwd_entry: no SMB password file set\n"));
+      return False;
+    }
+  
+  DEBUG(10, ("mod_getnisp21pwd_entry: search by name: %s\n", pwd->smb_name));
+  DEBUG(10, ("mod_getnisp21pwd_entry: using NIS+ table %s\n", lp_smb_passwd_file()));
+  
+  slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", pwd->smb_name, lp_smb_passwd_file());
+  
+  /* Search the table. */
+  gotalarm = 0;
+  CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+  alarm(5);
+  
+  result = nis_list(nisname, FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP, NULL, NULL);
+  
+  alarm(0);
+  CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
+  
+  if (gotalarm)
+    {
+      DEBUG(0,("mod_getnisp21pwd_entry: NIS+ lookup time out\n"));
+      nis_freeresult(result);
+      return False;
+    }
+  
+  if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
+    /* User not found. */
+    DEBUG(0,("mod_getnisp21pwd_entry: user not found in NIS+\n"));
+    nis_freeresult(result);
+    return False;
+  }
+
+  DEBUG(6,("mod_getnisp21pwd_entry: entry exists\n"));
+  
+  obj = NIS_RES_OBJECT(result);
+  
+  user_name = ENTRY_VAL(obj, NPF_NAME);
+  oldnislmpwd = ENTRY_VAL(obj, NPF_LMPWD);
+  oldnisntpwd = ENTRY_VAL(obj, NPF_NTPWD);
+  oldnisacb = ENTRY_VAL(obj, NPF_ACB);
+  oldnislct = ENTRY_VAL(obj, NPF_PWDLSET_T);
+  
+  
+  if (!override && (*oldnislmpwd == '*' || *oldnislmpwd == 'X' ||
+                   *oldnisntpwd == '*' || *oldnisntpwd == 'X')) {
+    /* Password deliberately invalid - end here. */
+    DEBUG(10, ("mod_nisp21pwd_entry: entry invalidated for user %s\n", user_name));
+    nis_freeresult(result);
+    return False;
+  }
+
+  if (strlen(oldnislmpwd) != 32 || strlen(oldnisntpwd) != 32) {
+    DEBUG(0, ("mod_nisp21pwd_entry: malformed password entry (incorrect length)\n"));
+    nis_freeresult(result);
+    return False;
+  }
+
+
+
+  /* 
+   * Now check if the account info and the password last
+   * change time is available.
+   */
+
+  /*
+   * If both NT and lanman passwords are provided - reset password
+   * not required flag.
+   */
+
+  if(pwd->smb_passwd != NULL || pwd->smb_nt_passwd != NULL) {
+    /* Require password in the future (should ACB_DISABLED also be reset?) */
+    pwd->acct_ctrl &= ~(ACB_PWNOTREQ);
+  }
+
+  if (*oldnisacb == '[') {
+    
+    i = 0;
+    acb[i++] = oldnisacb[i];
+    while(i < (sizeof(fstring) - 2) && (oldnisacb[i] != ']'))
+      acb[i] = oldnisacb[i++];
+    
+    acb[i++] = ']';
+    acb[i++] = '\0';
+    
+    if (i == NEW_PW_FORMAT_SPACE_PADDED_LEN) {
+      /*
+       * We are using a new format, space padded
+       * acct ctrl field. Encode the given acct ctrl
+       * bits into it.
+       */
+      fstrcpy(acb, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+    } else {
+      /*
+       * If using the old format and the ACB_DISABLED or
+       * ACB_PWNOTREQ are set then set the lanman and NT passwords to NULL
+       * here as we have no space to encode the change.
+       */
+      if(pwd->acct_ctrl & (ACB_DISABLED|ACB_PWNOTREQ)) {
+        pwd->smb_passwd = NULL;
+        pwd->smb_nt_passwd = NULL;
+      }
+    }
+    
+    /* Now do the LCT stuff. */
+    if (StrnCaseCmp(oldnislct, "LCT-", 4) == 0) {
+      
+      for(i = 0; i < 8; i++) {
+       if(oldnislct[i+4] == '\0' || !isxdigit(oldnislct[i+4]))
+         break;
+      }
+      if (i == 8) {
+       /*
+        * p points at 8 characters of hex digits -
+        * read into a time_t as the seconds since
+        * 1970 that the password was last changed.
+        */
+       got_pass_last_set_time = True;
+      } /* i == 8 */
+    } /* StrnCaseCmp() */
+
+  } /* p == '[' */
+
+  /* Entry is correctly formed. */
+
+
+
+  /* Create the 32 byte representation of the new p16 */
+  if(pwd->smb_passwd != NULL) {
+    for (i = 0; i < 16; i++) {
+      slprintf(&lmpwd[i*2], 32, "%02X", (uchar) pwd->smb_passwd[i]);
+    }
+  } else {
+    if(pwd->acct_ctrl & ACB_PWNOTREQ)
+      fstrcpy(lmpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+    else
+      fstrcpy(lmpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+  }
+
+  /* Add on the NT md4 hash */
+  if (pwd->smb_nt_passwd != NULL) {
+    for (i = 0; i < 16; i++) {
+      slprintf(&ntpwd[i*2], 32, "%02X", (uchar) pwd->smb_nt_passwd[i]);
+    }
+  } else {
+    if(pwd->acct_ctrl & ACB_PWNOTREQ)
+      fstrcpy(ntpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
+    else
+      fstrcpy(ntpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+  }
+  
+  pwd->pass_last_set_time = time(NULL);
+
+  if(got_pass_last_set_time) {
+    slprintf(lct, 12, "LCT-%08X", (uint32)pwd->pass_last_set_time);
+  }
+
+  set_single_attribute(obj, NPF_LMPWD,     lmpwd, strlen(lmpwd), EN_CRYPT);
+  set_single_attribute(obj, NPF_NTPWD,     ntpwd, strlen(ntpwd), EN_CRYPT);
+  set_single_attribute(obj, NPF_ACB,       acb,   strlen(acb),   0);
+  set_single_attribute(obj, NPF_PWDLSET_T, lct,   strlen(lct),   0);
+
+  addresult =
+    nis_add_entry(lp_smb_passwd_file(), obj, 
+                 ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
+  
+  if(addresult->status != NIS_SUCCESS) {
+    DEBUG(0, ("mod_nisp21pwd_entry: NIS+ table update failed: %s %s\n", nisname, nis_sperrno(addresult->status)));
+    nis_freeresult(addresult);
+    nis_freeresult(result);
+    return False;
+  }
+    
+  DEBUG(6,("mod_nisp21pwd_entry: password changed\n"));
+
+  nis_freeresult(addresult);
+  nis_freeresult(result);
+  
+  return True;
 }
  
-/************************************************************************
- makes a struct sam_passwd from a NIS+ result.
- ************************************************************************/
-static BOOL make_sam_from_nisp(struct sam_passwd *pw_buf, nis_result *result)
-{
-       int uidval;
-       static pstring  user_name;
-       static unsigned char smbpwd[16];
-       static unsigned char smbntpwd[16];
-       nis_object *obj;
-       uchar *p;
-
-       if (pw_buf == NULL || result == NULL) return False;
-
-       pwdb_init_sam(pw_buf);
-
-       if (result->status != NIS_SUCCESS)
-       {
-               DEBUG(0, ("make_smb_from_nisp: NIS+ lookup failure: %s\n",
-                          nis_sperrno(result->status)));
-               return False;
-       }
-
-       /* User not found. */
-       if (NIS_RES_NUMOBJ(result) <= 0)
-       {
-               DEBUG(10, ("make_smb_from_nisp: user not found in NIS+\n"));
-               return False;
-       }
-
-       if (NIS_RES_NUMOBJ(result) > 1)
-       {
-               DEBUG(10, ("make_smb_from_nisp: WARNING: Multiple entries for user in NIS+ table!\n"));
-       }
-
-       /* Grab the first hit. */
-       obj = &NIS_RES_OBJECT(result)[0];
-
-       /* Check the lanman password column. */
-       p = (uchar *)ENTRY_VAL(obj, NPF_LMPWD);
-       if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbpwd))
-       {
-               DEBUG(0, ("make_smb_from_nisp: malformed LM pwd entry.\n"));
-               return False;
-       }
-
-       /* Check the NT password column. */
-       p = (uchar *)ENTRY_VAL(obj, NPF_NTPWD);
-       if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbntpwd))
-       {
-               DEBUG(0, ("make_smb_from_nisp: malformed NT pwd entry\n"));
-               return False;
-       }
-
-       strncpy(user_name, ENTRY_VAL(obj, NPF_NAME), sizeof(user_name));
-       uidval = atoi(ENTRY_VAL(obj, NPF_UID));
-
-       pw_buf->smb_name      = user_name;
-       pw_buf->unix_uid    = uidval;           
-       pw_buf->smb_passwd    = smbpwd;
-       pw_buf->smb_nt_passwd = smbntpwd;
-
-       return True;
-}
 
 /*************************************************************************
  Routine to search the nisplus passwd file for an entry matching the username
@@ -524,8 +913,8 @@ static struct sam_passwd *getnisp21pwnam(char *name)
                return NULL;
        }
 
-       DEBUG(10, ("getnisppwnam: search by name: %s\n", name));
-       DEBUG(10, ("getnisppwnam: using NIS+ table %s\n", lp_smb_passwd_file()));
+       DEBUG(10, ("getnisp21pwnam: search by name: %s\n", name));
+       DEBUG(10, ("getnisp21pwnam: using NIS+ table %s\n", lp_smb_passwd_file()));
 
        slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", name, lp_smb_passwd_file());
 
@@ -541,12 +930,12 @@ static struct sam_passwd *getnisp21pwnam(char *name)
 
        if (gotalarm)
        {
-               DEBUG(0,("getnisppwnam: NIS+ lookup time out\n"));
+               DEBUG(0,("getnisp21pwnam: NIS+ lookup time out\n"));
                nis_freeresult(result);
                return NULL;
        }
 
-       ret = make_sam_from_nisp(&pw_buf, result);
+       ret = make_sam_from_nisresult(&pw_buf, result);
        nis_freeresult(result);
 
        return ret ? &pw_buf : NULL;
@@ -565,7 +954,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
 
        if (!*lp_smb_passwd_file())
        {
-               DEBUG(0, ("No SMB password file set\n"));
+               DEBUG(0, ("getnisp21pwrid: no SMB password file set\n"));
                return NULL;
        }
 
@@ -591,7 +980,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
                return NULL;
        }
 
-       ret = make_sam_from_nisp(&pw_buf, result);
+       ret = make_sam_from_nisresult(&pw_buf, result);
        nis_freeresult(result);
 
        return ret ? &pw_buf : NULL;
@@ -603,52 +992,52 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
 
 static struct smb_passwd *getnisppwent(void *vp)
 {
-       return pwdb_sam_to_smb(getnisp21pwent(vp));
+       return pdb_sam_to_smb(getnisp21pwent(vp));
 }
 
 static BOOL add_nisppwd_entry(struct smb_passwd *newpwd)
 {
-       return add_nisp21pwd_entry(pwdb_smb_to_sam(newpwd));
+       return add_nisp21pwd_entry(pdb_smb_to_sam(newpwd));
 }
 
 static BOOL mod_nisppwd_entry(struct smb_passwd* pwd, BOOL override)
 {
-       return mod_nisp21pwd_entry(pwdb_smb_to_sam(pwd), override);
+       return mod_nisp21pwd_entry(pdb_smb_to_sam(pwd), override);
 }
 
 static struct smb_passwd *getnisppwnam(char *name)
 {
-       return pwdb_sam_to_smb(getnisp21pwnam(name));
+       return pdb_sam_to_smb(getnisp21pwnam(name));
 }
 
-static struct sam_passwd *getnisp21pwuid(uid_t unix_uid)
+static struct sam_passwd *getnisp21pwuid(uid_t smb_userid)
 {
-       return getnisp21pwrid(pwdb_uid_to_user_rid(unix_uid));
+       return getnisp21pwrid(pdb_uid_to_user_rid(smb_userid));
 }
 
-static struct smb_passwd *getnisppwrid(uid_t user_rid)
+static struct smb_passwd *getnisppwrid(uint32 user_rid)
 {
-       return pwdb_sam_to_smb(getnisp21pwuid(pwdb_user_rid_to_uid(user_rid)));
+       return pdb_sam_to_smb(getnisp21pwuid(pdb_user_rid_to_uid(user_rid)));
 }
 
-static struct smb_passwd *getnisppwuid(uid_t unix_uid)
+static struct smb_passwd *getnisppwuid(uid_t smb_userid)
 {
-       return pwdb_sam_to_smb(getnisp21pwuid(unix_uid));
+       return pdb_sam_to_smb(getnisp21pwuid(smb_userid));
 }
 
 static struct sam_disp_info *getnispdispnam(char *name)
 {
-       return pwdb_sam_to_dispinfo(getnisp21pwnam(name));
+       return pdb_sam_to_dispinfo(getnisp21pwnam(name));
 }
 
 static struct sam_disp_info *getnispdisprid(uint32 rid)
 {
-       return pwdb_sam_to_dispinfo(getnisp21pwrid(rid));
+       return pdb_sam_to_dispinfo(getnisp21pwrid(rid));
 }
 
 static struct sam_disp_info *getnispdispent(void *vp)
 {
-       return pwdb_sam_to_dispinfo(getnisp21pwent(vp));
+       return pdb_sam_to_dispinfo(getnisp21pwent(vp));
 }
 
 static struct passdb_ops nispasswd_ops = {
@@ -673,7 +1062,7 @@ static struct passdb_ops nispasswd_ops = {
   getnispdispent
 };
 
-struct passdb_ops *nisplus_initialise_password_db(void)
+struct passdb_ops *nisplus_initialize_password_db(void)
 {
   return &nispasswd_ops;
 }
@@ -693,7 +1082,7 @@ static void useful_code(void) {
 
        if (nis_user->status != NIS_SUCCESS || NIS_RES_NUMOBJ(nis_user) <= 0)
        {
-               DEBUG(3, ("add_nisppwd_entry: Unable to get NIS+ passwd entry for user: %s.\n",
+               DEBUG(3, ("useful_code: Unable to get NIS+ passwd entry for user: %s.\n",
                        nis_sperrno(nis_user->status)));
                return False;
        }
index 7effbfef8dd87ee1a9397c2af25267fd804de6c4..11ce0d754e8ab06b806281fe89d3e5e186134344 100644 (file)
@@ -32,7 +32,7 @@ static char this_salt[100]="";
 static char this_crypted[100]="";
 
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
 /*******************************************************************
 check on PAM authentication
 ********************************************************************/
@@ -136,6 +136,10 @@ static BOOL pam_auth(char *user,char *password)
 
 
 #ifdef WITH_AFS
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
 /*******************************************************************
 check on AFS authentication
 ********************************************************************/
@@ -158,6 +162,7 @@ static BOOL afs_auth(char *user,char *password)
                                       &reason) == 0) {
                return(True);
        }
+       DEBUG(1,("AFS authentication for \"%s\" failed (%s)\n", user, reason));
        return(False);
 }
 #endif
@@ -165,6 +170,9 @@ static BOOL afs_auth(char *user,char *password)
 
 #ifdef WITH_DFS
 
+#include <dce/dce_error.h>
+#include <dce/sec_login.h>
+
 /*****************************************************************
  This new version of the DFS_AUTH code was donated by Karsten Muuss
  <muuss@or.uni-bonn.de>. It fixes the following problems with the
@@ -195,6 +203,7 @@ static BOOL dfs_auth(char *user,char *password)
        sec_passwd_rec_t passwd_rec;
        sec_login_auth_src_t auth_src = sec_login_auth_src_network;
        unsigned char dce_errstr[dce_c_error_string_len];
+       gid_t egid;
 
        if (dcelogin_atmost_once) return(False);
 
@@ -322,14 +331,16 @@ static BOOL dfs_auth(char *user,char *password)
         * back to being root on error though. JRA.
         */
        
-       if (setregid(-1, pw->pw_gid) != 0) {
+       egid = getegid();
+
+       if (set_effective_gid(pw->pw_gid) != 0) {
                DEBUG(0,("Can't set egid to %d (%s)\n", 
                         pw->pw_gid, strerror(errno)));
                return False;
        }
 
-       if (setreuid(-1, pw->pw_uid) != 0) {
-               setgid(0);
+       if (set_effective_uid(pw->pw_uid) != 0) {
+               set_effective_gid(egid);
                DEBUG(0,("Can't set euid to %d (%s)\n", 
                         pw->pw_uid, strerror(errno)));
                return False;
@@ -340,24 +351,17 @@ static BOOL dfs_auth(char *user,char *password)
                                     &my_dce_sec_context,
                                     &err) == 0) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
                         user,dce_errstr));
-               return(False);
+               goto err;
        }
 
        sec_login_get_pwent(my_dce_sec_context, 
                            (sec_login_passwd_t*)&pw, &err);
        if (err != error_status_ok ) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        passwd_rec.version_number = sec_passwd_c_version_none;
@@ -370,24 +374,16 @@ static BOOL dfs_auth(char *user,char *password)
                                    &auth_src, &err);
        if (err != error_status_ok ) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
                         user,dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        sec_login_certify_identity(my_dce_sec_context, &err);
        if (err != error_status_ok) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        if (auth_src != sec_login_auth_src_network) { 
@@ -401,10 +397,7 @@ static BOOL dfs_auth(char *user,char *password)
                         user,dce_errstr));
                
                sec_login_purge_context(&my_dce_sec_context, &err);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        sec_login_get_pwent(my_dce_sec_context, 
@@ -412,11 +405,7 @@ static BOOL dfs_auth(char *user,char *password)
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
@@ -434,21 +423,24 @@ static BOOL dfs_auth(char *user,char *password)
        sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
        
-       setuid(0);
-       setgid(0);
+       set_effective_uid(0);
+       set_effective_gid(0);
        
        DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time))));
        
        dcelogin_atmost_once = 1;
        return (True);
+
+err:
+
+       /* Go back to root, JRA. */
+       set_effective_uid(0);
+       set_effective_gid(egid);
+       return(False);
 }
 
 void dfs_unlogin(void)
@@ -467,6 +459,9 @@ void dfs_unlogin(void)
 #endif
 
 #ifdef KRB5_AUTH
+
+#include <krb5.h>
+
 /*******************************************************************
 check on Kerberos authentication
 ********************************************************************/
@@ -614,6 +609,7 @@ static char *osf1_bigcrypt(char *password,char *salt1)
        
        StrnCpy(salt,salt1,2);
        StrnCpy(result,salt1,2);
+       result[2]='\0';
 
        for (i=0; i<parts;i++) {
                p1 = crypt(p2,salt);
@@ -680,7 +676,7 @@ core of password checking routine
 static BOOL password_check(char *password)
 {
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
        /* This falls through if the password check fails
           - if HAVE_CRYPT is not defined this causes an error msg
           saying Warning - no crypt available
@@ -691,23 +687,23 @@ static BOOL password_check(char *password)
           Hence we make a direct return to avoid a second chance!!!
        */
        return (pam_auth(this_user,password));
-#endif
+#endif /* WITH_PAM */
        
 #ifdef WITH_AFS
        if (afs_auth(this_user,password)) return(True);
-#endif
+#endif /* WITH_AFS */
        
 #ifdef WITH_DFS
        if (dfs_auth(this_user,password)) return(True);
-#endif 
+#endif /* WITH_DFS */
 
 #ifdef KRB5_AUTH
        if (krb5_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB5_AUTH */
 
 #ifdef KRB4_AUTH
        if (krb4_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB4_AUTH */
 
 #ifdef OSF1_ENH_SEC
        {
@@ -718,26 +714,42 @@ static BOOL password_check(char *password)
          }
          return ret;
        }
-#endif
+#endif /* OSF1_ENH_SEC */
 
 #ifdef ULTRIX_AUTH
        return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif
+#endif /* ULTRIX_AUTH */
 
 #ifdef LINUX_BIGCRYPT
        return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif
+#endif /* LINUX_BIGCRYPT */
+
+#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
+
+       /*
+        * Some systems have bigcrypt in the C library but might not
+        * actually use it for the password hashes (HPUX 10.20) is
+        * a noteable example. So we try bigcrypt first, followed
+        * by crypt.
+        */
+
+       if(strcmp(bigcrypt(password,this_salt),this_crypted) == 0)
+               return True;
+       else 
+               return (strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
+#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 
 #ifdef HAVE_BIGCRYPT
        return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_BIGCRYPT */
 
 #ifndef HAVE_CRYPT
        DEBUG(1,("Warning - no crypt available\n"));
        return(False);
-#else
+#else /* HAVE_CRYPT */
        return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_CRYPT */
+#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 }
 
 
@@ -753,13 +765,12 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
 {
        pstring pass2;
        int level = lp_passwordlevel();
-       const struct passwd *pass;
+       struct passwd *pass;
 
        if (password) password[pwlen] = 0;
 
 #if DEBUG_PASSWORD
-       DEBUG(100,("checking user=[%s] pass=",user));
-       dump_data(100, password, strlen(password));
+       DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
 #endif
 
        if (!password) {
@@ -785,12 +796,76 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
                return(False);
        }
 
+#ifdef HAVE_GETSPNAM
+       {
+               struct spwd *spass;
+
+               /* many shadow systems require you to be root to get
+                  the password, in most cases this should already be
+                  the case when this function is called, except
+                  perhaps for IPC password changing requests */
+
+               spass = getspnam(pass->pw_name);
+               if (spass && spass->sp_pwdp) {
+                       pstrcpy(pass->pw_passwd,spass->sp_pwdp);
+               }
+       }
+#elif defined(IA_UINFO)
+       {
+               /* Need to get password with SVR4.2's ia_ functions
+                  instead of get{sp,pw}ent functions. Required by
+                  UnixWare 2.x, tested on version
+                  2.1. (tangent@cyberport.com) */
+               uinfo_t uinfo;
+               if (ia_openinfo(pass->pw_name, &uinfo) != -1) {
+                       ia_get_logpwd(uinfo, &(pass->pw_passwd));
+               }
+       }
+#endif
+
+#ifdef HAVE_GETPRPWNAM
+       {
+               struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
+               if (pr_pw && pr_pw->ufld.fd_encrypt)
+                       pstrcpy(pass->pw_passwd,pr_pw->ufld.fd_encrypt);
+       }
+#endif
+
+#ifdef OSF1_ENH_SEC
+       {
+               struct pr_passwd *mypasswd;
+               DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",
+                        user));
+               mypasswd = getprpwnam (user);
+               if (mypasswd) { 
+                       fstrcpy(pass->pw_name,mypasswd->ufld.fd_name);
+                       fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
+               } else {
+                       DEBUG(5,("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
+                                user));
+               }
+       }
+#endif
+
+#ifdef ULTRIX_AUTH
+       {
+               AUTHORIZATION *ap = getauthuid(pass->pw_uid);
+               if (ap) {
+                       fstrcpy(pass->pw_passwd, ap->a_password);
+                       endauthent();
+               }
+       }
+#endif
+
        /* extract relevant info */
        fstrcpy(this_user,pass->pw_name);  
        fstrcpy(this_salt,pass->pw_passwd);
+
+#if defined(HAVE_TRUNCATED_SALT)
        /* crypt on some platforms (HPUX in particular)
           won't work with more than 2 salt characters. */
        this_salt[2] = 0;
+#endif
        
        fstrcpy(this_crypted,pass->pw_passwd);
        
index 6579d14351246b977d8daf85b9d7e0889dc236c5..c0a20f34204c3bc7b3814bd5fa1acc2fe445f89c 100644 (file)
 #include "nterr.h"
 
 extern int DEBUGLEVEL;
+
+/*
+ * This is set on startup - it defines the SID for this
+ * machine, and therefore the SAM database for which it is
+ * responsible.
+ */
+
 extern DOM_SID global_sam_sid;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
 
 /*
  * NOTE. All these functions are abstracted into a structure
@@ -42,58 +51,62 @@ extern DOM_SID global_sam_sid;
  * functions in a first pass, as struct sam_passwd contains more
  * information, needed by the NT Domain support.
  * 
- * an API writer is expected to create either one set (struct smb_passwd) or
- * the other (struct sam_passwd) OR both, and optionally also to write display
- * info routines * (struct sam_disp_info).  functions which the API writer
- * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y)
- * such that API users can call any function and still get valid results.
- *
- * the password API does NOT fill in the gaps if you set an API function
- * to NULL: it will deliberately attempt to call the NULL function.
+ * a full example set of derivative functions are listed below.  an API
+ * writer is expected to cut/paste these into their module, replace
+ * either one set (struct smb_passwd) or the other (struct sam_passwd)
+ * OR both, and optionally also to write display info routines
+ * (struct sam_disp_info).  lkcl
  *
  */
 
-static struct smb_passdb_ops *pwdb_ops;
+static struct passdb_ops *pdb_ops;
 
 /***************************************************************
- Initialise the password db operations.
+ Initialize the password db operations.
 ***************************************************************/
 
-BOOL initialise_password_db(void)
+BOOL initialize_password_db(void)
 {
-  if (pwdb_ops)
+  if (pdb_ops)
   {
     return True;
   }
 
 #ifdef WITH_NISPLUS
-  pwdb_ops =  nisplus_initialise_password_db();
+  pdb_ops =  nisplus_initialize_password_db();
 #elif defined(WITH_LDAP)
-  pwdb_ops = ldap_initialise_password_db();
-#elif defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
-  pwdb_ops = mysql_initialise_password_db();
-#elif defined(USE_SMBPASS_DB)
-  pwdb_ops = file_initialise_password_db();
+  pdb_ops = ldap_initialize_password_db();
+#else 
+  pdb_ops = file_initialize_password_db();
 #endif 
 
-  return (pwdb_ops != NULL);
+  return (pdb_ops != NULL);
 }
 
 /*
  * Functions that return/manipulate a struct smb_passwd.
  */
 
+/************************************************************************
+ Utility function to search smb passwd by rid.  
+*************************************************************************/
+
+struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid)
+{
+       return iterate_getsmbpwuid(pdb_user_rid_to_uid(user_rid));
+}
+
 /************************************************************************
  Utility function to search smb passwd by uid.  use this if your database
  does not have search facilities.
 *************************************************************************/
 
-struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid)
+struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
 {
        struct smb_passwd *pwd = NULL;
        void *fp = NULL;
 
-       DEBUG(10, ("search by unix_uid: %x\n", (int)unix_uid));
+       DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
 
        /* Open the smb password database - not for update. */
        fp = startsmbpwent(False);
@@ -104,13 +117,12 @@ struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid)
                return NULL;
        }
 
-       while ((pwd = getsmbpwent(fp)) != NULL && pwd->unix_uid != unix_uid)
-       {
-       }
+       while ((pwd = getsmbpwent(fp)) != NULL && pwd->smb_userid != smb_userid)
+      ;
 
        if (pwd != NULL)
        {
-               DEBUG(10, ("found by unix_uid: %x\n", (int)unix_uid));
+               DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
        }
 
        endsmbpwent(fp);
@@ -122,7 +134,7 @@ struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid)
  does not have search facilities.
 *************************************************************************/
 
-struct smb_passwd *iterate_getsmbpwnam(const char *name)
+struct smb_passwd *iterate_getsmbpwnam(char *name)
 {
        struct smb_passwd *pwd = NULL;
        void *fp = NULL;
@@ -138,10 +150,8 @@ struct smb_passwd *iterate_getsmbpwnam(const char *name)
                return NULL;
        }
 
-       while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->unix_name, name))
-       {
-               DEBUG(10, ("iterate: %s 0x%x\n", pwd->unix_name, pwd->unix_uid));
-       }
+       while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->smb_name, name))
+      ;
 
        if (pwd != NULL)
        {
@@ -165,7 +175,7 @@ struct smb_passwd *iterate_getsmbpwnam(const char *name)
 
 void *startsmbpwent(BOOL update)
 {
-  return pwdb_ops->startsmbpwent(update);
+  return pdb_ops->startsmbpwent(update);
 }
 
 /***************************************************************
@@ -180,17 +190,7 @@ void *startsmbpwent(BOOL update)
 
 void endsmbpwent(void *vp)
 {
-  pwdb_ops->endsmbpwent(vp);
-}
-
-SMB_BIG_UINT getsmbpwpos(void *vp)
-{
-  return pwdb_ops->getsmbpwpos(vp);
-}
-
-BOOL setsmbpwpos(void *vp, SMB_BIG_UINT tok)
-{
-  return pwdb_ops->setsmbpwpos(vp, tok);
+  pdb_ops->endsmbpwent(vp);
 }
 
 /*************************************************************************
@@ -199,7 +199,7 @@ BOOL setsmbpwpos(void *vp, SMB_BIG_UINT tok)
 
 struct smb_passwd *getsmbpwent(void *vp)
 {
-       return pwdb_smb_map_names(pwdb_ops->getsmbpwent(vp));
+       return pdb_ops->getsmbpwent(vp);
 }
 
 /************************************************************************
@@ -208,12 +208,7 @@ struct smb_passwd *getsmbpwent(void *vp)
 
 BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
 {
-       struct smb_passwd *mapped = pwdb_smb_map_names(newpwd);
-       if (mapped)
-       {
-               return pwdb_ops->add_smbpwd_entry(mapped);
-       }
-       return False;
+       return pdb_ops->add_smbpwd_entry(newpwd);
 }
 
 /************************************************************************
@@ -227,121 +222,985 @@ BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
 
 BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
 {
-       struct smb_passwd *mapped = pwdb_smb_map_names(pwd);
-       if (mapped)
-       {
-               return pwdb_ops->mod_smbpwd_entry(mapped, override);
-       }
-       return False;
+       return pdb_ops->mod_smbpwd_entry(pwd, override);
 }
 
 /************************************************************************
  Routine to search smb passwd by name.
 *************************************************************************/
 
-struct smb_passwd *getsmbpwnam(const char *name)
+struct smb_passwd *getsmbpwnam(char *name)
 {
-       return pwdb_smb_map_names(pwdb_ops->getsmbpwnam(name));
+       return pdb_ops->getsmbpwnam(name);
+}
+
+/************************************************************************
+ Routine to search smb passwd by user rid.
+*************************************************************************/
+
+struct smb_passwd *getsmbpwrid(uint32 user_rid)
+{
+       return pdb_ops->getsmbpwrid(user_rid);
 }
 
 /************************************************************************
  Routine to search smb passwd by uid.
 *************************************************************************/
 
-struct smb_passwd *getsmbpwuid(uid_t unix_uid)
+struct smb_passwd *getsmbpwuid(uid_t smb_userid)
 {
-       return pwdb_smb_map_names(pwdb_ops->getsmbpwuid(unix_uid));
+       return pdb_ops->getsmbpwuid(smb_userid);
+}
+
+/*
+ * Functions that manupulate a struct sam_passwd.
+ */
+
+/************************************************************************
+ Utility function to search sam passwd by name.  use this if your database
+ does not have search facilities.
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwnam(char *name)
+{
+       struct sam_passwd *pwd = NULL;
+       void *fp = NULL;
+
+       DEBUG(10, ("search by name: %s\n", name));
+
+       /* Open the smb password database - not for update. */
+       fp = startsmbpwent(False);
+
+       if (fp == NULL)
+       {
+               DEBUG(0, ("unable to open sam password database.\n"));
+               return NULL;
+       }
+
+       while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name))
+       {
+               DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
+       }
+
+       if (pwd != NULL)
+       {
+               DEBUG(10, ("found by name: %s\n", name));
+       }
+
+       endsmbpwent(fp);
+       return pwd;
+}
+
+/************************************************************************
+ Utility function to search sam passwd by rid.  use this if your database
+ does not have search facilities.
+
+ search capability by both rid and uid are needed as the rid <-> uid
+ mapping may be non-monotonic.  
+
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
+{
+       struct sam_passwd *pwd = NULL;
+       void *fp = NULL;
+
+       DEBUG(10, ("search by rid: %x\n", rid));
+
+       /* Open the smb password file - not for update. */
+       fp = startsmbpwent(False);
+
+       if (fp == NULL)
+       {
+               DEBUG(0, ("unable to open sam password database.\n"));
+               return NULL;
+       }
+
+       while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
+       {
+               DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
+       }
+
+       if (pwd != NULL)
+       {
+               DEBUG(10, ("found by user_rid: %x\n", rid));
+       }
+
+       endsmbpwent(fp);
+       return pwd;
+}
+
+/************************************************************************
+ Utility function to search sam passwd by uid.  use this if your database
+ does not have search facilities.
+
+ search capability by both rid and uid are needed as the rid <-> uid
+ mapping may be non-monotonic.  
+
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
+{
+       struct sam_passwd *pwd = NULL;
+       void *fp = NULL;
+
+       DEBUG(10, ("search by uid: %x\n", (int)uid));
+
+       /* Open the smb password file - not for update. */
+       fp = startsmbpwent(False);
+
+       if (fp == NULL)
+       {
+               DEBUG(0, ("unable to open sam password database.\n"));
+               return NULL;
+       }
+
+       while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
+      ;
+
+       if (pwd != NULL)
+       {
+               DEBUG(10, ("found by smb_userid: %x\n", (int)uid));
+       }
+
+       endsmbpwent(fp);
+       return pwd;
+}
+
+/*************************************************************************
+ Routine to return a display info structure, by rid
+ *************************************************************************/
+struct sam_disp_info *getsamdisprid(uint32 rid)
+{
+       return pdb_ops->getsamdisprid(rid);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the sam passwd list.
+ *************************************************************************/
+
+struct sam_passwd *getsam21pwent(void *vp)
+{
+       return pdb_ops->getsam21pwent(vp);
+}
+
+
+/************************************************************************
+ Routine to search sam passwd by name.
+*************************************************************************/
+
+struct sam_passwd *getsam21pwnam(char *name)
+{
+       return pdb_ops->getsam21pwnam(name);
+}
+
+/************************************************************************
+ Routine to search sam passwd by rid.  
+*************************************************************************/
+
+struct sam_passwd *getsam21pwrid(uint32 rid)
+{
+       return pdb_ops->getsam21pwrid(rid);
+}
+
+
+/**********************************************************
+ **********************************************************
+
+ utility routines which are likely to be useful to all password
+ databases
+
+ **********************************************************
+ **********************************************************/
+
+/*************************************************************
+ initialises a struct sam_disp_info.
+ **************************************************************/
+
+static void pdb_init_dispinfo(struct sam_disp_info *user)
+{
+       if (user == NULL) return;
+       memset((char *)user, '\0', sizeof(*user));
 }
 
 /*************************************************************
  initialises a struct smb_passwd.
  **************************************************************/
-void pwdb_init_smb(struct smb_passwd *user)
+
+void pdb_init_smb(struct smb_passwd *user)
 {
        if (user == NULL) return;
-       bzero(user, sizeof(*user));
+       memset((char *)user, '\0', sizeof(*user));
        user->pass_last_set_time    = (time_t)-1;
-       user->unix_uid = (uid_t)-1;
-       user->user_rid = 0xffffffff;
 }
 
 /*************************************************************
- fills in missing details.  one set of details _must_ exist.
+ initialises a struct sam_passwd.
+ **************************************************************/
+void pdb_init_sam(struct sam_passwd *user)
+{
+       if (user == NULL) return;
+       memset((char *)user, '\0', sizeof(*user));
+       user->logon_time            = (time_t)-1;
+       user->logoff_time           = (time_t)-1;
+       user->kickoff_time          = (time_t)-1;
+       user->pass_last_set_time    = (time_t)-1;
+       user->pass_can_change_time  = (time_t)-1;
+       user->pass_must_change_time = (time_t)-1;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the sam passwd list.
+ *************************************************************************/
+
+struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user)
+{
+       static struct sam_disp_info disp_info;
+
+       if (user == NULL) return NULL;
+
+       pdb_init_dispinfo(&disp_info);
+
+       disp_info.smb_name  = user->smb_name;
+       disp_info.full_name = user->full_name;
+       disp_info.user_rid  = user->user_rid;
+
+       return &disp_info;
+}
+
+/*************************************************************
+ converts a sam_passwd structure to a smb_passwd structure.
+ **************************************************************/
+
+struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
+{
+       static struct smb_passwd pw_buf;
+
+       if (user == NULL) return NULL;
+
+       pdb_init_smb(&pw_buf);
+
+       pw_buf.smb_userid         = user->smb_userid;
+       pw_buf.smb_name           = user->smb_name;
+       pw_buf.smb_passwd         = user->smb_passwd;
+       pw_buf.smb_nt_passwd      = user->smb_nt_passwd;
+       pw_buf.acct_ctrl          = user->acct_ctrl;
+       pw_buf.pass_last_set_time = user->pass_last_set_time;
+
+       return &pw_buf;
+}
+
+
+/*************************************************************
+ converts a smb_passwd structure to a sam_passwd structure.
  **************************************************************/
-struct smb_passwd *pwdb_smb_map_names(struct smb_passwd *smb)
+
+struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
 {
-       DOM_NAME_MAP gmep;
-       BOOL found = False;
-       DOM_SID sid;
-       static fstring unix_name;
-       static fstring nt_name;
+       static struct sam_passwd pw_buf;
+
+       if (user == NULL) return NULL;
+
+       pdb_init_sam(&pw_buf);
+
+       pw_buf.smb_userid         = user->smb_userid;
+       pw_buf.smb_name           = user->smb_name;
+       pw_buf.smb_passwd         = user->smb_passwd;
+       pw_buf.smb_nt_passwd      = user->smb_nt_passwd;
+       pw_buf.acct_ctrl          = user->acct_ctrl;
+       pw_buf.pass_last_set_time = user->pass_last_set_time;
+
+       return &pw_buf;
+}
+
+/**********************************************************
+ Encode the account control bits into a string.
+ length = length of string to encode into (including terminating
+ null). length *MUST BE MORE THAN 2* !
+ **********************************************************/
+
+char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
+{
+  static fstring acct_str;
+  size_t i = 0;
+
+  acct_str[i++] = '[';
+
+  if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
+  if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
+  if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
+  if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T'; 
+  if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
+  if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
+  if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
+  if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
+  if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
+  if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
+  if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
+
+  for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
 
-       if (smb == NULL)
+  i = length - 2;
+  acct_str[i++] = ']';
+  acct_str[i++] = '\0';
+
+  return acct_str;
+}     
+
+/**********************************************************
+ Decode the account control bits from a string.
+
+ this function breaks coding standards minimum line width of 80 chars.
+ reason: vertical line-up code clarity - all case statements fit into
+ 15 lines, which is more important.
+ **********************************************************/
+
+uint16 pdb_decode_acct_ctrl(const char *p)
+{
+       uint16 acct_ctrl = 0;
+       BOOL finished = False;
+
+       /*
+        * Check if the account type bits have been encoded after the
+        * NT password (in the form [NDHTUWSLXI]).
+        */
+
+       if (*p != '[') return 0;
+
+       for (p++; *p && !finished; p++)
        {
-               DEBUG(10,("pwdb_smb_map_names: NULL\n"));
-               return NULL;
+               switch (*p)
+               {
+                       case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
+                       case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
+                       case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
+                       case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ } 
+                       case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ } 
+                       case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ } 
+                       case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ } 
+                       case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ } 
+                       case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } 
+                       case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ } 
+                       case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
+            case ' ': { break; }
+                       case ':':
+                       case '\n':
+                       case '\0': 
+                       case ']':
+                       default:  { finished = True; }
+               }
        }
 
-       DEBUG(10,("pwdb_smb_map_names: unix %s nt %s unix %d nt%d\n",
-                  smb->unix_name != NULL ? smb->unix_name : "NULL",
-                  smb->nt_name   != NULL ? smb->nt_name   : "NULL",
-                  smb->unix_uid, smb->user_rid));
+       return acct_ctrl;
+}
+
+/*******************************************************************
+ gets password-database-format time from a string.
+ ********************************************************************/
 
-       if (smb->unix_name == NULL && smb->nt_name == NULL &&
-           smb->unix_uid == (uid_t)-1 && smb->user_rid == 0xffffffff)
+static time_t get_time_from_string(const char *p)
+{
+       int i;
+
+       for (i = 0; i < 8; i++)
        {
-               return NULL;
+               if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
+               break;
+       }
+       if (i == 8)
+       {
+               /*
+                * p points at 8 characters of hex digits - 
+                * read into a time_t as the seconds since
+                * 1970 that the password was last changed.
+                */
+               return (time_t)strtol(p, NULL, 16);
        }
-       if (smb->unix_name != NULL && smb->nt_name != NULL &&
-           smb->unix_uid != (uid_t)-1 && smb->user_rid != 0xffffffff)
+       return (time_t)-1;
+}
+
+/*******************************************************************
+ gets password last set time
+ ********************************************************************/
+
+time_t pdb_get_last_set_time(const char *p)
+{
+       if (*p && StrnCaseCmp(p, "LCT-", 4))
        {
-               return smb;
+               return get_time_from_string(p + 4);
        }
+       return (time_t)-1;
+}
 
-       if (!found && smb->unix_name != NULL)
+
+/*******************************************************************
+ sets password-database-format time in a string.
+ ********************************************************************/
+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);
+}
+
+/*******************************************************************
+ sets logon time
+ ********************************************************************/
+void pdb_set_logon_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "LNT", t);
+}
+
+/*******************************************************************
+ sets logoff time
+ ********************************************************************/
+void pdb_set_logoff_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "LOT", t);
+}
+
+/*******************************************************************
+ sets kickoff time
+ ********************************************************************/
+void pdb_set_kickoff_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "KOT", t);
+}
+
+/*******************************************************************
+ sets password can change time
+ ********************************************************************/
+void pdb_set_can_change_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "CCT", t);
+}
+
+/*******************************************************************
+ sets password last set time
+ ********************************************************************/
+void pdb_set_must_change_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "MCT", t);
+}
+
+/*******************************************************************
+ sets password last set time
+ ********************************************************************/
+void pdb_set_last_set_time(char *p, int max_len, time_t t)
+{
+       set_time_in_string(p, max_len, "LCT", t);
+}
+
+
+/*************************************************************
+ Routine to set 32 hex password characters from a 16 byte array.
+**************************************************************/
+void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
+{
+       if (pwd != NULL)
        {
-               found = lookupsmbpwnam(smb->unix_name, &gmep);
+               int i;
+               for (i = 0; i < 16; i++)
+               {
+                       slprintf(&p[i*2], 3, "%02X", pwd[i]);
+               }
        }
-       if (!found && smb->unix_uid  != (uid_t)-1)
+       else
        {
-               found = lookupsmbpwuid(smb->unix_uid , &gmep);
+               if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
+               {
+                       safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
+               }
+               else
+               {
+                       safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
+               }
        }
+}
+/*************************************************************
+ Routine to get the 32 hex characters and turn them
+ into a 16 byte array.
+**************************************************************/
+BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
+{
+       int i;
+       unsigned char   lonybble, hinybble;
+       char           *hexchars = "0123456789ABCDEF";
+       char           *p1, *p2;
 
-       if (!found)
+       for (i = 0; i < 32; i += 2)
        {
-               sid_copy(&sid, &global_sam_sid);
-               sid_append_rid(&sid, smb->user_rid);
+               hinybble = toupper(p[i]);
+               lonybble = toupper(p[i + 1]);
+
+               p1 = strchr(hexchars, hinybble);
+               p2 = strchr(hexchars, lonybble);
+
+               if (!p1 || !p2)
+               {
+                       return (False);
+               }
+
+               hinybble = PTR_DIFF(p1, hexchars);
+               lonybble = PTR_DIFF(p2, hexchars);
+
+               pwd[i / 2] = (hinybble << 4) | lonybble;
        }
+       return (True);
+}
+
+/*******************************************************************
+ Group and User RID username mapping function
+ ********************************************************************/
 
-       if (!found && smb->user_rid != 0xffffffff)
+BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
+{
+    struct passwd *pw = Get_Pwnam(user_name, False);
+
+       if (u_rid == NULL || g_rid == NULL || user_name == NULL)
        {
-               found = lookupsmbpwsid  (&sid        , &gmep);
+               return False;
        }
-       if (!found && smb->nt_name  != NULL)
+
+       if (!pw)
        {
-               found = lookupsmbpwntnam(smb->nt_name, &gmep);
+               DEBUG(1,("Username %s is invalid on this system\n", user_name));
+               return False;
        }
 
-       if (!found)
+       if (user_in_list(user_name, lp_domain_guest_users()))
        {
-               return NULL;
+               *u_rid = DOMAIN_USER_RID_GUEST;
        }
-
-       if (!sid_front_equal(&global_sam_sid, &gmep.sid))
+       else if (user_in_list(user_name, lp_domain_admin_users()))
        {
-               fstring sid_str;
-               sid_to_string(sid_str, &gmep.sid);
-               DEBUG(0,("UNIX User %s Primary Group is in the wrong domain! %s\n",
-                         smb->unix_name, sid_str));
-               return NULL;
+               *u_rid = DOMAIN_USER_RID_ADMIN;
+       }
+       else
+       {
+               /* turn the unix UID into a Domain RID.  this is what the posix
+                  sub-system does (adds 1000 to the uid) */
+               *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
+       }
+
+       /* absolutely no idea what to do about the unix GID to Domain RID mapping */
+       *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
+
+       return True;
+}
+
+/****************************************************************************
+ Read the machine SID from a file.
+****************************************************************************/
+
+static BOOL read_sid_from_file(int fd, char *sid_file)
+{   
+  fstring fline;
+    
+  memset(fline, '\0', sizeof(fline));
+
+  if(read(fd, fline, sizeof(fline) -1 ) < 0) {
+    DEBUG(0,("unable to read file %s. Error was %s\n",
+           sid_file, strerror(errno) ));
+    return False;
+  }
+
+  /*
+   * Convert to the machine SID.
+   */
+
+  fline[sizeof(fline)-1] = '\0';
+  if(!string_to_sid( &global_sam_sid, fline)) {
+    DEBUG(0,("unable to generate machine SID.\n"));
+    return False;
+  }
+
+  return True;
+}
+
+/****************************************************************************
+ Generate the global machine sid. Look for the MACHINE.SID file first, if
+ not found then look in smb.conf and use it to create the MACHINE.SID file.
+****************************************************************************/
+BOOL pdb_generate_sam_sid(void)
+{
+       int fd;
+       char *p;
+       pstring sid_file;
+       fstring sid_string;
+       SMB_STRUCT_STAT st;
+       BOOL overwrite_bad_sid = False;
+
+       generate_wellknown_sids();
+
+       pstrcpy(sid_file, lp_smb_passwd_file());
+       p = strrchr(sid_file, '/');
+       if(p != NULL) {
+               *++p = '\0';
+       }
+
+       if (!directory_exist(sid_file, NULL)) {
+               if (mkdir(sid_file, 0700) != 0) {
+                       DEBUG(0,("can't create private directory %s : %s\n",
+                                sid_file, strerror(errno)));
+                       return False;
+               }
+       }
+
+       pstrcat(sid_file, "MACHINE.SID");
+    
+       if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
+               DEBUG(0,("unable to open or create file %s. Error was %s\n",
+                        sid_file, strerror(errno) ));
+               return False;
+       } 
+  
+       /*
+        * Check if the file contains data.
+        */
+       
+       if(sys_fstat( fd, &st) < 0) {
+               DEBUG(0,("unable to stat file %s. Error was %s\n",
+                        sid_file, strerror(errno) ));
+               close(fd);
+               return False;
+       } 
+  
+       if(st.st_size > 0) {
+               /*
+                * We have a valid SID - read it.
+                */
+               if(!read_sid_from_file( fd, sid_file)) {
+                       DEBUG(0,("unable to read file %s. Error was %s\n",
+                                sid_file, strerror(errno) ));
+                       close(fd);
+                       return False;
+               }
+
+               /*
+                * JRA. Reversed the sense of this test now that I have
+                * actually done this test *personally*. One more reason
+                * to never trust third party information you have not
+                * independently verified.... sigh. JRA.
+                */
+
+               if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
+                       /*
+                        * Fix and re-write...
+                        */
+                       overwrite_bad_sid = True;
+                       global_sam_sid.sub_auths[0] = 21;
+                       DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
+detected - re-writing to be decimal 21 instead.\n" ));
+                       sid_to_string(sid_string, &global_sam_sid);
+                       if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
+                               DEBUG(0,("unable to seek file file %s. Error was %s\n",
+                                        sid_file, strerror(errno) ));
+                               close(fd);
+                               return False;
+                       }
+               } else {
+                       close(fd);
+                       return True;
+               }
+       } else {
+               /*
+                * The file contains no data - we need to generate our
+                * own sid.
+                * Generate the new sid data & turn it into a string.
+                */
+               int i;
+               uchar raw_sid_data[12];
+               DOM_SID mysid;
+
+               memset((char *)&mysid, '\0', sizeof(DOM_SID));
+               mysid.sid_rev_num = 1;
+               mysid.id_auth[5] = 5;
+               mysid.num_auths = 0;
+               mysid.sub_auths[mysid.num_auths++] = 21;
+
+               generate_random_buffer( raw_sid_data, 12, True);
+               for( i = 0; i < 3; i++)
+                       mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
+
+               sid_to_string(sid_string, &mysid);
+       } 
+       
+       fstrcat(sid_string, "\n");
+       
+       /*
+        * Ensure our new SID is valid.
+        */
+       
+       if(!string_to_sid( &global_sam_sid, sid_string)) {
+               DEBUG(0,("unable to generate machine SID.\n"));
+               return False;
+       } 
+  
+       /*
+        * Do an exclusive blocking lock on the file.
+        */
+       
+       if(!do_file_lock( fd, 60, F_WRLCK)) {
+               DEBUG(0,("unable to lock file %s. Error was %s\n",
+                        sid_file, strerror(errno) ));
+               close(fd);
+               return False;
+       } 
+       if(!overwrite_bad_sid) {
+               /*
+                * At this point we have a blocking lock on the SID
+                * file - check if in the meantime someone else wrote
+                * SID data into the file. If so - they were here first,
+                * use their data.
+                */
+       
+               if(sys_fstat( fd, &st) < 0) {
+                       DEBUG(0,("unable to stat file %s. Error was %s\n",
+                                sid_file, strerror(errno) ));
+                       close(fd);
+                       return False;
+               } 
+  
+               if(st.st_size > 0) {
+                       /*
+                        * Unlock as soon as possible to reduce
+                        * contention on the exclusive lock.
+                        */ 
+                       do_file_lock( fd, 60, F_UNLCK);
+               
+                       /*
+                        * We have a valid SID - read it.
+                        */
+               
+                       if(!read_sid_from_file( fd, sid_file)) {
+                               DEBUG(0,("unable to read file %s. Error was %s\n",
+                                        sid_file, strerror(errno) ));
+                               close(fd);
+                               return False;
+                       }
+                       close(fd);
+                       return True;
+               } 
+       }
+       
+       /*
+        * The file is still empty and we have an exlusive lock on it,
+        * or we're fixing an earlier mistake.
+        * Write out out SID data into the file.
+        */
+
+       /*
+        * Use chmod here as some (strange) UNIX's don't
+        * have fchmod. JRA.
+        */     
+
+       if(chmod(sid_file, 0644) < 0) {
+               DEBUG(0,("unable to set correct permissions on file %s. \
+Error was %s\n", sid_file, strerror(errno) ));
+               do_file_lock( fd, 60, F_UNLCK);
+               close(fd);
+               return False;
+       } 
+       
+       if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
+               DEBUG(0,("unable to write file %s. Error was %s\n",
+                        sid_file, strerror(errno) ));
+               do_file_lock( fd, 60, F_UNLCK);
+               close(fd);
+               return False;
+       } 
+       
+       /*
+        * Unlock & exit.
+        */
+       
+       do_file_lock( fd, 60, F_UNLCK);
+       close(fd);
+       return True;
+}   
+
+/*******************************************************************
+ Converts NT user RID to a UNIX uid.
+ ********************************************************************/
+
+uid_t pdb_user_rid_to_uid(uint32 user_rid)
+{
+       return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
+}
+
+/*******************************************************************
+ Converts NT user RID to a UNIX gid.
+ ********************************************************************/
+
+gid_t pdb_user_rid_to_gid(uint32 user_rid)
+{
+       return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
+}
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID.
+ ********************************************************************/
+
+uint32 pdb_uid_to_user_rid(uid_t uid)
+{
+       return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
+}
+
+/*******************************************************************
+ converts NT Group RID to a UNIX uid.
+ ********************************************************************/
+
+uint32 pdb_gid_to_group_rid(gid_t gid)
+{
+  return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
+}
+
+/*******************************************************************
+ Decides if a RID is a well known RID.
+ ********************************************************************/
+
+static BOOL pdb_rid_is_well_known(uint32 rid)
+{
+  return (rid < 1000);
+}
+
+/*******************************************************************
+ Decides if a RID is a user or group RID.
+ ********************************************************************/
+  
+BOOL pdb_rid_is_user(uint32 rid)
+{
+  /* lkcl i understand that NT attaches an enumeration to a RID
+   * such that it can be identified as either a user, group etc
+   * type.  there are 5 such categories, and they are documented.
+   */
+   if(pdb_rid_is_well_known(rid)) {
+      /*
+       * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
+       * and DOMAIN_USER_RID_GUEST.
+       */
+     if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
+       return True;
+   } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
+     return True;
+   }
+   return False;
+}
+
+/*******************************************************************
+ Convert a rid into a name. Used in the lookup SID rpc.
+ ********************************************************************/
+
+BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
+{
+
+       BOOL is_user = pdb_rid_is_user(rid);
+
+       DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" :
+                       "group", (unsigned int)rid));
+
+       if(is_user) {
+               if(rid == DOMAIN_USER_RID_ADMIN) {
+                       pstring admin_users;
+                       char *p = admin_users;
+                       pstrcpy( admin_users, lp_domain_admin_users());
+                       if(!next_token(&p, name, NULL, sizeof(fstring)))
+                               fstrcpy(name, "Administrator");
+               } else if (rid == DOMAIN_USER_RID_GUEST) {
+                       pstring guest_users;
+                       char *p = guest_users;
+                       pstrcpy( guest_users, lp_domain_guest_users());
+                       if(!next_token(&p, name, NULL, sizeof(fstring)))
+                               fstrcpy(name, "Guest");
+               } else {
+                       uid_t uid = pdb_user_rid_to_uid(rid);
+                       struct passwd *pass = sys_getpwuid(uid);
+
+                       *psid_name_use = SID_NAME_USER;
+
+                       DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid,
+                               pass ? "succeeded" : "failed" ));
+
+                       if(!pass) {
+                               slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
+                               return True;
+                       }
+
+                       fstrcpy(name, pass->pw_name);
+
+                       DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name,
+                               (unsigned int)rid ));
+               }
+
+       } else {
+               gid_t gid = pdb_user_rid_to_gid(rid);
+               struct group *gr = getgrgid(gid);
+
+               *psid_name_use = SID_NAME_ALIAS;
+
+               DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid,
+                       gr ? "succeeded" : "failed" ));
+
+               if(!gr) {
+                       slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
+                       return True;
+               }
+
+               fstrcpy( name, gr->gr_name);
+
+               DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name,
+                       (unsigned int)rid ));
+       }
+
+       return True;
+}
+
+/*******************************************************************
+ Convert a name into a SID. Used in the lookup name rpc.
+ ********************************************************************/
+
+BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
+{
+       extern DOM_SID global_sid_World_Domain;
+       struct passwd *pass = NULL;
+       DOM_SID local_sid;
+
+       sid_copy(&local_sid, &global_sam_sid);
+
+       if(!strequal(global_myname, domain) && !strequal(global_myworkgroup, domain))
+               return False;
+
+       /*
+        * Special case for MACHINE\Everyone. Map to the world_sid.
+        */
+
+       if(strequal(user, "Everyone")) {
+               sid_copy( psid, &global_sid_World_Domain);
+               sid_append_rid(psid, 0);
+               *psid_name_use = SID_NAME_ALIAS;
+               return True;
+       }
+
+       (void)map_username(user);
+
+       if(!(pass = Get_Pwnam(user, False))) {
+               /*
+                * Maybe it was a group ?
+                */
+               struct group *grp = getgrnam(user);
+
+               if(!grp)
+                       return False;
+
+               sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
+               *psid_name_use = SID_NAME_ALIAS;
+       } else {
+
+               sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
+               *psid_name_use = SID_NAME_USER;
        }
 
-       fstrcpy(unix_name, gmep.unix_name);
-       fstrcpy(nt_name  , gmep.nt_name  );
-       if (smb->unix_name == NULL      ) smb->unix_name = unix_name;
-       if (smb->nt_name   == NULL      ) smb->nt_name   = nt_name  ;
-       if (smb->unix_uid  == (uid_t)-1 ) smb->unix_uid  = (uid_t)gmep.unix_id;
-       if (smb->user_rid  == 0xffffffff) sid_split_rid(&gmep.sid, &smb->user_rid);
+       sid_copy( psid, &local_sid);
 
-       return smb;
+       return True;
 }
index 41b01a1a49927ee8f77b40f1c82448a5ddfef385..f578d9a20ea02ab271a57340cc620660dbb3cdd0 100644 (file)
@@ -34,7 +34,7 @@ extern int DEBUGLEVEL;
  *
  */
 
-static struct passgrp_ops *pwgrp_ops = NULL;
+static struct passgrp_ops *pwgrp_ops;
 
 /***************************************************************
  Initialise the passgrp operations.
@@ -50,10 +50,8 @@ BOOL initialise_passgrp_db(void)
 #ifdef WITH_NISPLUS
   pwgrp_ops =  nisplus_initialise_password_grp();
 #elif defined(WITH_LDAP)
-  pwgrp_ops = ldap_initialise_password_grp();
-#elif defined(USE_SMBUNIX_DB)
-  pwgrp_ops = unix_initialise_password_grp();
-#elif defined(USE_SMBPASS_DB)
+  pwgrp_ops = ldap_initialize_password_grp();
+#else 
   pwgrp_ops = file_initialise_password_grp();
 #endif 
 
@@ -72,30 +70,8 @@ struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
                uint32 **grps, int *num_grps,
                uint32 **alss, int *num_alss)
 {
-       struct smb_passwd *pwd = NULL;
-       void *fp = NULL;
-
-       DEBUG(10, ("search by user_rid: 0x%x\n", user_rid));
-
-       /* Open the smb password database - not for update. */
-       fp = startsmbgrpent(False);
-
-       if (fp == NULL)
-       {
-               DEBUG(0, ("unable to open smb passgrp database.\n"));
-               return NULL;
-       }
-
-       while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->user_rid != user_rid)
-      ;
-
-       if (pwd != NULL)
-       {
-               DEBUG(10, ("found by user_rid: 0x%x\n", user_rid));
-       }
-
-       endsmbgrpent(fp);
-       return pwd;
+       return iterate_getsmbgrpuid(pwdb_user_rid_to_uid(user_rid),
+                                   grps, num_grps, alss, num_alss);
 }
 
 /************************************************************************
@@ -103,14 +79,14 @@ struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
  does not have search facilities.
 *************************************************************************/
 
-struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
+struct smb_passwd *iterate_getsmbgrpuid(uid_t smb_userid,
                uint32 **grps, int *num_grps,
                uint32 **alss, int *num_alss)
 {
        struct smb_passwd *pwd = NULL;
        void *fp = NULL;
 
-       DEBUG(10, ("search by unix_uid: %x\n", (int)unix_uid));
+       DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
 
        /* Open the smb password database - not for update. */
        fp = startsmbgrpent(False);
@@ -121,12 +97,12 @@ struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
                return NULL;
        }
 
-       while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->unix_uid != unix_uid)
+       while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->smb_userid != smb_userid)
       ;
 
        if (pwd != NULL)
        {
-               DEBUG(10, ("found by unix_uid: %x\n", (int)unix_uid));
+               DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
        }
 
        endsmbgrpent(fp);
@@ -138,14 +114,12 @@ struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
  does not have search facilities.
 *************************************************************************/
 
-struct smb_passwd *iterate_getsmbgrpntnam(const char *nt_name,
+struct smb_passwd *iterate_getsmbgrpnam(char *name,
                uint32 **grps, int *num_grps,
                uint32 **alss, int *num_alss)
 {
        struct smb_passwd *pwd = NULL;
-       fstring name;
        void *fp = NULL;
-       fstrcpy(name, nt_name);
 
        DEBUG(10, ("search by name: %s\n", name));
 
@@ -158,7 +132,7 @@ struct smb_passwd *iterate_getsmbgrpntnam(const char *nt_name,
                return NULL;
        }
 
-       while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && !strequal(pwd->nt_name, name))
+       while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && !strequal(pwd->smb_name, name))
       ;
 
        if (pwd != NULL)
@@ -216,11 +190,11 @@ struct smb_passwd *getsmbgrpent(void *vp,
  Routine to search smb passwd by name.
 *************************************************************************/
 
-struct smb_passwd *getsmbgrpntnam(char *name,
+struct smb_passwd *getsmbgrpnam(char *name,
                uint32 **grps, int *num_grps,
                uint32 **alss, int *num_alss)
 {
-       return pwgrp_ops->getsmbgrpntnam(name, grps, num_grps, alss, num_alss);
+       return pwgrp_ops->getsmbgrpnam(name, grps, num_grps, alss, num_alss);
 }
 
 /************************************************************************
@@ -238,10 +212,10 @@ struct smb_passwd *getsmbgrprid(uint32 user_rid,
  Routine to search smb passwd by uid.
 *************************************************************************/
 
-struct smb_passwd *getsmbgrpuid(uid_t unix_uid,
+struct smb_passwd *getsmbgrpuid(uid_t smb_userid,
                uint32 **grps, int *num_grps,
                uint32 **alss, int *num_alss)
 {
-       return pwgrp_ops->getsmbgrpuid(unix_uid, grps, num_grps, alss, num_alss);
+       return pwgrp_ops->getsmbgrpuid(smb_userid, grps, num_grps, alss, num_alss);
 }
 
index e3c6a5da441dfa33b738db3b26f155967ac8fbdf..4cfac6d94845727e4002e88bcbd80e96469b70e2 100644 (file)
 
 #ifdef USE_SMBPASS_DB
 
-static int pw_file_lock_depth = 0;
 extern int DEBUGLEVEL;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
 
 static char s_readbuf[1024];
+static int pw_file_lock_depth;
 
 /***************************************************************
  Start to enumerate the smbpasswd list. Returns a void pointer
@@ -33,8 +35,37 @@ static char s_readbuf[1024];
 
 static void *startsmbfilepwent(BOOL update)
 {
-       return startfileent(lp_smb_passwd_file(), s_readbuf, sizeof(s_readbuf),
-                             &pw_file_lock_depth, update);
+  FILE *fp = NULL;
+  char *pfile = lp_smb_passwd_file();
+
+  if (!*pfile) {
+    DEBUG(0, ("startsmbfilepwent: No SMB password file set\n"));
+    return (NULL);
+  }
+  DEBUG(10, ("startsmbfilepwent: opening file %s\n", pfile));
+
+  fp = sys_fopen(pfile, update ? "r+b" : "rb");
+
+  if (fp == NULL) {
+    DEBUG(0, ("startsmbfilepwent: unable to open file %s\n", pfile));
+    return NULL;
+  }
+
+  /* Set a buffer to do more efficient reads */
+  setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
+
+  if (!pw_file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, &pw_file_lock_depth))
+  {
+    DEBUG(0, ("startsmbfilepwent: unable to lock file %s\n", pfile));
+    fclose(fp);
+    return NULL;
+  }
+
+  /* Make sure it is only rw by the owner */
+  chmod(pfile, 0600);
+
+  /* We have a lock on the file. */
+  return (void *)fp;
 }
 
 /***************************************************************
@@ -43,216 +74,361 @@ static void *startsmbfilepwent(BOOL update)
 
 static void endsmbfilepwent(void *vp)
 {
-       endfileent(vp, &pw_file_lock_depth);
+  FILE *fp = (FILE *)vp;
+
+  pw_file_unlock(fileno(fp), &pw_file_lock_depth);
+  fclose(fp);
+  DEBUG(7, ("endsmbfilepwent: closed password file.\n"));
 }
 
 /*************************************************************************
- Return the current position in the smbpasswd list as an SMB_BIG_UINT.
- This must be treated as an opaque token.
-*************************************************************************/
-
-static SMB_BIG_UINT getsmbfilepwpos(void *vp)
+ Routine to return the next entry in the smbpasswd list.
+ *************************************************************************/
+static struct smb_passwd *getsmbfilepwent(void *vp)
 {
-       return getfilepwpos(vp);
-}
+  /* Static buffers we will return. */
+  static struct smb_passwd pw_buf;
+  static pstring  user_name;
+  static unsigned char smbpwd[16];
+  static unsigned char smbntpwd[16];
+  FILE *fp = (FILE *)vp;
+  char            linebuf[256];
+  unsigned char   c;
+  unsigned char  *p;
+  long            uidval;
+  size_t            linebuf_len;
 
-/*************************************************************************
- Set the current position in the smbpasswd list from an SMB_BIG_UINT.
- This must be treated as an opaque token.
-*************************************************************************/
+  if(fp == NULL) {
+    DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
+    return NULL;
+  }
 
-static BOOL setsmbfilepwpos(void *vp, SMB_BIG_UINT tok)
-{
-       return setfilepwpos(vp, tok);
+  pdb_init_smb(&pw_buf);
+
+  pw_buf.acct_ctrl = ACB_NORMAL;  
+
+  /*
+   * Scan the file, a line at a time and check if the name matches.
+   */
+  while (!feof(fp)) {
+    linebuf[0] = '\0';
+
+    fgets(linebuf, 256, fp);
+    if (ferror(fp)) {
+      return NULL;
+    }
+
+    /*
+     * Check if the string is terminated with a newline - if not
+     * then we must keep reading and discard until we get one.
+     */
+    linebuf_len = strlen(linebuf);
+    if (linebuf[linebuf_len - 1] != '\n') {
+      c = '\0';
+      while (!ferror(fp) && !feof(fp)) {
+        c = fgetc(fp);
+        if (c == '\n')
+          break;
+      }
+    } else
+      linebuf[linebuf_len - 1] = '\0';
+
+#ifdef DEBUG_PASSWORD
+    DEBUG(100, ("getsmbfilepwent: got line |%s|\n", linebuf));
+#endif
+    if ((linebuf[0] == 0) && feof(fp)) {
+      DEBUG(4, ("getsmbfilepwent: end of file reached\n"));
+      break;
+    }
+    /*
+     * The line we have should be of the form :-
+     * 
+     * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
+     * ignored....
+     * 
+     * or,
+     *
+     * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
+     *
+     * if Windows NT compatible passwords are also present.
+     * [Account type] is an ascii encoding of the type of account.
+     * LCT-(8 hex digits) is the time_t value of the last change time.
+     */
+
+    if (linebuf[0] == '#' || linebuf[0] == '\0') {
+      DEBUG(6, ("getsmbfilepwent: skipping comment or blank line\n"));
+      continue;
+    }
+    p = (unsigned char *) strchr(linebuf, ':');
+    if (p == NULL) {
+      DEBUG(0, ("getsmbfilepwent: malformed password entry (no :)\n"));
+      continue;
+    }
+    /*
+     * As 256 is shorter than a pstring we don't need to check
+     * length here - if this ever changes....
+     */
+    strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
+    user_name[PTR_DIFF(p, linebuf)] = '\0';
+
+    /* Get smb uid. */
+
+    p++;               /* Go past ':' */
+
+    if(*p == '-') {
+      DEBUG(0, ("getsmbfilepwent: uids in the smbpasswd file must not be negative.\n"));
+      continue;
+    }
+
+    if (!isdigit(*p)) {
+      DEBUG(0, ("getsmbfilepwent: malformed password entry (uid not number)\n"));
+      continue;
+    }
+
+    uidval = atoi((char *) p);
+
+    while (*p && isdigit(*p))
+      p++;
+
+    if (*p != ':') {
+      DEBUG(0, ("getsmbfilepwent: malformed password entry (no : after uid)\n"));
+      continue;
+    }
+
+    pw_buf.smb_name = user_name;
+    pw_buf.smb_userid = uidval;
+
+    /*
+     * Now get the password value - this should be 32 hex digits
+     * which are the ascii representations of a 16 byte string.
+     * Get two at a time and put them into the password.
+     */
+
+    /* Skip the ':' */
+    p++;
+
+    if (*p == '*' || *p == 'X') {
+      /* Password deliberately invalid - end here. */
+      DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
+      pw_buf.smb_nt_passwd = NULL;
+      pw_buf.smb_passwd = NULL;
+      pw_buf.acct_ctrl |= ACB_DISABLED;
+      return &pw_buf;
+    }
+
+    if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
+      DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
+      continue;
+    }
+
+    if (p[32] != ':') {
+      DEBUG(0, ("getsmbfilepwent: malformed password entry (no terminating :)\n"));
+      continue;
+    }
+
+    if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+      pw_buf.smb_passwd = NULL;
+      pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+    } else {
+      if (!pdb_gethexpwd((char *)p, smbpwd)) {
+        DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
+        continue;
+      }
+      pw_buf.smb_passwd = smbpwd;
+    }
+
+    /* 
+     * Now check if the NT compatible password is
+     * available.
+     */
+    pw_buf.smb_nt_passwd = NULL;
+
+    p += 33; /* Move to the first character of the line after
+                the lanman password. */
+    if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
+      if (*p != '*' && *p != 'X') {
+        if(pdb_gethexpwd((char *)p,smbntpwd))
+          pw_buf.smb_nt_passwd = smbntpwd;
+      }
+      p += 33; /* Move to the first character of the line after
+                  the NT password. */
+    }
+
+    DEBUG(5,("getsmbfilepwent: returning passwd entry for user %s, uid %ld\n",
+            user_name, uidval));
+
+    if (*p == '[')
+       {
+      pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
+
+      /* Must have some account type set. */
+      if(pw_buf.acct_ctrl == 0)
+        pw_buf.acct_ctrl = ACB_NORMAL;
+
+      /* Now try and get the last change time. */
+      if(*p == ']')
+        p++;
+      if(*p == ':') {
+        p++;
+        if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
+          int i;
+          p += 4;
+          for(i = 0; i < 8; i++) {
+            if(p[i] == '\0' || !isxdigit(p[i]))
+              break;
+          }
+          if(i == 8) {
+            /*
+             * p points at 8 characters of hex digits - 
+             * read into a time_t as the seconds since
+             * 1970 that the password was last changed.
+             */
+            pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
+          }
+        }
+      }
+    } else {
+      /* 'Old' style file. Fake up based on user name. */
+      /*
+       * Currently trust accounts are kept in the same
+       * password file as 'normal accounts'. If this changes
+       * we will have to fix this code. JRA.
+       */
+      if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
+        pw_buf.acct_ctrl &= ~ACB_NORMAL;
+        pw_buf.acct_ctrl |= ACB_WSTRUST;
+      }
+    }
+
+    return &pw_buf;
+  }
+
+  DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
+  return NULL;
 }
 
 /*************************************************************************
  Routine to return the next entry in the smbpasswd list.
-
- this function is non-static as it is called (exclusively and only)
- from getsamfile21pwent().
+ this function is a nice, messy combination of reading:
+ - the smbpasswd file
+ - the unix password database
+ - smb.conf options (not done at present).
  *************************************************************************/
-struct smb_passwd *getsmbfilepwent(void *vp)
+
+static struct sam_passwd *getsmbfile21pwent(void *vp)
 {
-       /* Static buffers we will return. */
-       static struct smb_passwd pw_buf;
-       static pstring  unix_name;
-       static unsigned char smbpwd[16];
-       static unsigned char smbntpwd[16];
-       char            linebuf[256];
-       char  *p;
-       int            uidval;
-       size_t            linebuf_len;
-
-       if (vp == NULL)
+       struct smb_passwd *pw_buf = getsmbfilepwent(vp);
+       static struct sam_passwd user;
+       struct passwd *pwfile;
+
+       static pstring full_name;
+       static pstring home_dir;
+       static pstring home_drive;
+       static pstring logon_script;
+       static pstring profile_path;
+       static pstring acct_desc;
+       static pstring workstations;
+       
+       DEBUG(5,("getsmbfile21pwent\n"));
+
+       if (pw_buf == NULL) return NULL;
+
+       pwfile = sys_getpwnam(pw_buf->smb_name);
+       if (pwfile == NULL)
        {
-               DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
+               DEBUG(0,("getsmbfile21pwent: smbpasswd database is corrupt!\n"));
+               DEBUG(0,("getsmbfile21pwent: username %s not in unix passwd database!\n", pw_buf->smb_name));
                return NULL;
        }
 
-       pwdb_init_smb(&pw_buf);
+       pdb_init_sam(&user);
+
+       pstrcpy(samlogon_user, pw_buf->smb_name);
 
-       pw_buf.acct_ctrl = ACB_NORMAL;  
+       if (samlogon_user[strlen(samlogon_user)-1] != '$')
+       {
+               /* XXXX hack to get standard_sub_basic() to use sam logon username */
+               /* possibly a better way would be to do a become_user() call */
+               sam_logon_in_ssb = True;
+
+               user.smb_userid    = pw_buf->smb_userid;
+               user.smb_grpid     = pwfile->pw_gid;
+
+               user.user_rid  = pdb_uid_to_user_rid (user.smb_userid);
+               user.group_rid = pdb_gid_to_group_rid(user.smb_grpid );
 
-       /*
-        * Scan the file, a line at a time.
-        */
-       while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+               pstrcpy(full_name    , pwfile->pw_gecos        );
+               pstrcpy(logon_script , lp_logon_script       ());
+               pstrcpy(profile_path , lp_logon_path         ());
+               pstrcpy(home_drive   , lp_logon_drive        ());
+               pstrcpy(home_dir     , lp_logon_home         ());
+               pstrcpy(acct_desc    , "");
+               pstrcpy(workstations , "");
+
+               sam_logon_in_ssb = False;
+       }
+       else
        {
-               /*
-                * The line we have should be of the form :-
-                * 
-                * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
-                * ignored....
-                * 
-                * or,
-                *
-                * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
-                *
-                * if Windows NT compatible passwords are also present.
-                * [Account type] is an ascii encoding of the type of account.
-                * LCT-(8 hex digits) is the time_t value of the last change time.
-                */
-
-               /*
-                * As 256 is shorter than a pstring we don't need to check
-                * length here - if this ever changes....
-                */
-               p = strncpyn(unix_name, linebuf, sizeof(unix_name), ':');
-
-               if (p == NULL)
-               {
-                       DEBUG(0,("getsmbfilepwent: no ':' separator found\n"));
-                       continue;
-               }
-
-               /* Go past ':' */
-               p++;
-
-               /* Get smb uid. */
-
-               p = Atoic( p, &uidval, ":");
-
-               pw_buf.unix_name = unix_name;
-               pw_buf.unix_uid = uidval;
-
-               /*
-                * Now get the password value - this should be 32 hex digits
-                * which are the ascii representations of a 16 byte string.
-                * Get two at a time and put them into the password.
-                */
-
-               /* Skip the ':' */
-               p++;
-
-               if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
-               {
-                       DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
-                       continue;
-               }
-
-               if (p[32] != ':')
-               {
-                       DEBUG(0, ("getsmbfilepwent: malformed password entry (no terminating :)\n"));
-                       continue;
-               }
-
-               if (!strncasecmp( p, "NO PASSWORD", 11))
-               {
-                       pw_buf.smb_passwd = NULL;
-                       pw_buf.acct_ctrl |= ACB_PWNOTREQ;
-               }
-               else
-               {
-                       if (!pwdb_gethexpwd(p, (char *)smbpwd, NULL))
-                       {
-                               DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
-                               continue;
-                       }
-                       pw_buf.smb_passwd = smbpwd;
-               }
-
-               /* 
-                * Now check if the NT compatible password is
-                * available.
-                */
-               pw_buf.smb_nt_passwd = NULL;
-
-               /* Move to the first character of the line after the lanman password. */
-               p += 33;
-               if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':'))
-               {
-                       if (*p != '*' && *p != 'X')
-                       {
-                               if(pwdb_gethexpwd(p,(char *)smbntpwd, NULL))
-                               {
-                                       pw_buf.smb_nt_passwd = smbntpwd;
-                               }
-                       }
-                       /* Move to the first character of the line after the NT password. */
-                       p += 33;
-               }
-
-               DEBUG(5,("getsmbfilepwent: returning passwd entry for unix user %s, unix uid %d\n",
-                         unix_name, uidval));
-
-               if (*p == '[')
-               {
-                       pw_buf.acct_ctrl = pwdb_decode_acct_ctrl((char*)p);
-
-                       /* Must have some account type set. */
-                       if (pw_buf.acct_ctrl == 0)
-                       {
-                               pw_buf.acct_ctrl = ACB_NORMAL;
-                       }
-
-                       /* Now try and get the last change time. */
-                        while (*p != ']' && *p != ':') 
-                        {
-                                p++;
-                        }
-                       if (*p == ']')
-                       {
-                               p++;
-                       }
-                       if (*p == ':')
-                       {
-                               p++;
-                               pw_buf.pass_last_set_time = pwdb_get_last_set_time(p);
-                       }
-               }
-               else
-               {
-                       /* 'Old' style file. Fake up based on user name. */
-                       /*
-                        * Currently trust accounts are kept in the same
-                        * password file as 'normal accounts'. If this changes
-                        * we will have to fix this code. JRA.
-                        */
-                       if (pw_buf.unix_name[strlen(pw_buf.unix_name) - 1] == '$')      
-                       {
-                               pw_buf.acct_ctrl &= ~ACB_NORMAL;
-                               pw_buf.acct_ctrl |= ACB_WSTRUST;
-                       }
-               }
-
-               if (*p == '*' || *p == 'X')
-               {
-                       /* Password deliberately invalid - end here. */
-                       DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
-                       pw_buf.smb_nt_passwd = NULL;
-                       pw_buf.smb_passwd = NULL;
-                       pw_buf.acct_ctrl |= ACB_DISABLED;
-               }
-
-               DEBUG(6,("unixuser:%s uid:%d acb:%x\n",
-                         pw_buf.unix_name, pw_buf.unix_uid, pw_buf.acct_ctrl));
-
-               return &pw_buf;
+               user.smb_userid    = pw_buf->smb_userid;
+               user.smb_grpid     = pwfile->pw_gid;
+
+               user.user_rid  = pdb_uid_to_user_rid (user.smb_userid);
+               user.group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+
+               pstrcpy(full_name    , "");
+               pstrcpy(logon_script , "");
+               pstrcpy(profile_path , "");
+               pstrcpy(home_drive   , "");
+               pstrcpy(home_dir     , "");
+               pstrcpy(acct_desc    , "");
+               pstrcpy(workstations , "");
        }
 
-       DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
-       return NULL;
+       user.smb_name     = pw_buf->smb_name;
+       user.full_name    = full_name;
+       user.home_dir     = home_dir;
+       user.dir_drive    = home_drive;
+       user.logon_script = logon_script;
+       user.profile_path = profile_path;
+       user.acct_desc    = acct_desc;
+       user.workstations = workstations;
+
+       user.unknown_str = NULL; /* don't know, yet! */
+       user.munged_dial = NULL; /* "munged" dial-back telephone number */
+
+       user.smb_nt_passwd = pw_buf->smb_nt_passwd;
+       user.smb_passwd    = pw_buf->smb_passwd;
+                       
+       user.acct_ctrl = pw_buf->acct_ctrl;
+
+       user.unknown_3 = 0xffffff; /* don't know */
+       user.logon_divs = 168; /* hours per week */
+       user.hours_len = 21; /* 21 times 8 bits = 168 */
+       memset(user.hours, 0xff, user.hours_len); /* available at all hours */
+       user.unknown_5 = 0x00020000; /* don't know */
+       user.unknown_5 = 0x000004ec; /* don't know */
+
+       return &user;
+}
+
+/*************************************************************************
+ Return the current position in the smbpasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static SMB_BIG_UINT getsmbfilepwpos(void *vp)
+{
+  return (SMB_BIG_UINT)sys_ftell((FILE *)vp);
+}
+
+/*************************************************************************
+ Set the current position in the smbpasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static BOOL setsmbfilepwpos(void *vp, SMB_BIG_UINT tok)
+{
+  return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET);
 }
 
 /************************************************************************
@@ -287,8 +463,8 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
    */
 
   while ((pwd = getsmbfilepwent(fp)) != NULL) {
-    if (strequal(newpwd->unix_name, pwd->unix_name)) {
-      DEBUG(0, ("add_smbfilepwd_entry: entry with unix name %s already exists\n", pwd->unix_name));
+    if (strequal(newpwd->smb_name, pwd->smb_name)) {
+      DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
       endsmbfilepwent(fp);
       return False;
     }
@@ -305,21 +481,21 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
 
   if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) {
     DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
-Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
+Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
     endsmbfilepwent(fp);
     return False;
   }
 
-  new_entry_length = strlen(newpwd->unix_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
+  new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
 
   if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
     DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
-Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
+Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
     endsmbfilepwent(fp);
     return False;
   }
 
-  slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->unix_name, (unsigned)newpwd->unix_uid);
+  slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
   p = &new_entry[strlen(new_entry)];
 
   if(newpwd->smb_passwd != NULL) {
@@ -355,7 +531,7 @@ Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
 
   /* Add the account encoding and the last change time. */
   slprintf((char *)p, new_entry_length - 1 - (p - new_entry),  "%s:LCT-%08X:\n",
-           pwdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL));
+           pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL));
 
 #ifdef DEBUG_PASSWORD
   DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d entry_len %d made line |%s|", 
@@ -364,13 +540,13 @@ Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
 
   if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) {
     DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \
-Error was %s\n", wr_len, newpwd->unix_name, pfile, strerror(errno)));
+Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));
 
     /* Remove the entry we just wrote. */
     if(sys_ftruncate(fd, offpos) == -1) {
       DEBUG(0, ("add_smbfilepwd_entry: ERROR failed to ftruncate file %s. \
 Error was %s. Password file may be corrupt ! Please examine by hand !\n", 
-             newpwd->unix_name, strerror(errno)));
+             newpwd->smb_name, strerror(errno)));
     }
 
     endsmbfilepwent(fp);
@@ -395,7 +571,7 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
 static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 {
   /* Static buffers we will return. */
-  static pstring  unix_name;
+  static pstring  user_name;
 
   char            linebuf[256];
   char            readbuf[1024];
@@ -416,17 +592,6 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
   int wr_len;
   int fd;
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("mod_smbfilepwd_entry: password entries\n"));
-       if (pwd->smb_passwd != NULL)
-       {
-               dump_data(100, pwd->smb_passwd, 16);
-       }
-       if (pwd->smb_nt_passwd != NULL)
-       {
-               dump_data(100, pwd->smb_nt_passwd, 16);
-       }
-#endif
   if (!*pfile) {
     DEBUG(0, ("No SMB password file set\n"));
     return False;
@@ -444,7 +609,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
   lockfd = fileno(fp);
 
-  if (!file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
+  if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
     DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
     fclose(fp);
     return False;
@@ -464,7 +629,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
     fgets(linebuf, sizeof(linebuf), fp);
     if (ferror(fp)) {
-      file_unlock(lockfd, &pw_file_lock_depth);
+      pw_file_unlock(lockfd, &pw_file_lock_depth);
       fclose(fp);
       return False;
     }
@@ -524,16 +689,16 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
      * As 256 is shorter than a pstring we don't need to check
      * length here - if this ever changes....
      */
-    strncpy(unix_name, linebuf, PTR_DIFF(p, linebuf));
-    unix_name[PTR_DIFF(p, linebuf)] = '\0';
-    if (strequal(unix_name, pwd->unix_name)) {
+    strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
+    user_name[PTR_DIFF(p, linebuf)] = '\0';
+    if (strequal(user_name, pwd->smb_name)) {
       found_entry = True;
       break;
     }
   }
 
   if (!found_entry) {
-    file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -545,7 +710,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
   if (!isdigit(*p)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n"));
-    file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -554,7 +719,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
     p++;
   if (*p != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n"));
-    file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -571,28 +736,28 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
   if (!override && (*p == '*' || *p == 'X')) {
     /* Password deliberately invalid - end here. */
-    DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for unix user %s\n", unix_name));
-    file_unlock(lockfd, &pw_file_lock_depth);
+    DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for user %s\n", user_name));
+    pw_file_unlock(lockfd, &pw_file_lock_depth);
     fclose(fp);
     return False;
   }
 
   if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return (False);
   }
 
   if (p[32] != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
 
   if (!override && (*p == '*' || *p == 'X')) {
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -603,14 +768,14 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
               the lanman password. */
   if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return (False);
   }
 
   if (p[32] != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -648,7 +813,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
        * acct ctrl field. Encode the given acct ctrl
        * bits into it.
        */
-      fstrcpy(encode_bits, pwdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+      fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
     } else {
       /*
        * If using the old format and the ACB_DISABLED or
@@ -738,7 +903,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
   if(wr_len > sizeof(linebuf)) {
     DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return (False);
   }
@@ -756,7 +921,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
 
   if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
     DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
@@ -764,50 +929,89 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
   /* Sanity check - ensure the areas we are writing are framed by ':' */
   if (read(fd, linebuf, wr_len+1) != wr_len+1) {
     DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
 
   if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
     DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
  
   if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
     DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
 
   if (write(fd, ascii_p16, wr_len) != wr_len) {
     DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
-    file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&pw_file_lock_depth);
     fclose(fp);
     return False;
   }
 
-  file_unlock(lockfd,&pw_file_lock_depth);
+  pw_file_unlock(lockfd,&pw_file_lock_depth);
   fclose(fp);
   return True;
 }
 
-static struct smb_passdb_ops file_ops = {
+/*
+ * Stub functions - implemented in terms of others.
+ */
+
+static BOOL mod_smbfile21pwd_entry(struct sam_passwd* pwd, BOOL override)
+{
+       return mod_smbfilepwd_entry(pdb_sam_to_smb(pwd), override);
+}
+
+static BOOL add_smbfile21pwd_entry(struct sam_passwd *newpwd)
+{
+       return add_smbfilepwd_entry(pdb_sam_to_smb(newpwd));
+}
+
+static struct sam_disp_info *getsmbfiledispnam(char *name)
+{
+       return pdb_sam_to_dispinfo(getsam21pwnam(name));
+}
+
+static struct sam_disp_info *getsmbfiledisprid(uint32 rid)
+{
+       return pdb_sam_to_dispinfo(getsam21pwrid(rid));
+}
+
+static struct sam_disp_info *getsmbfiledispent(void *vp)
+{
+       return pdb_sam_to_dispinfo(getsam21pwent(vp));
+}
+
+static struct passdb_ops file_ops = {
   startsmbfilepwent,
   endsmbfilepwent,
   getsmbfilepwpos,
   setsmbfilepwpos,
   iterate_getsmbpwnam,          /* In passdb.c */
   iterate_getsmbpwuid,          /* In passdb.c */
+  iterate_getsmbpwrid,          /* In passdb.c */
   getsmbfilepwent,
   add_smbfilepwd_entry,
-  mod_smbfilepwd_entry
+  mod_smbfilepwd_entry,
+  getsmbfile21pwent,
+  iterate_getsam21pwnam,
+  iterate_getsam21pwuid,
+  iterate_getsam21pwrid, 
+  add_smbfile21pwd_entry,
+  mod_smbfile21pwd_entry,
+  getsmbfiledispnam,
+  getsmbfiledisprid,
+  getsmbfiledispent
 };
 
-struct smb_passdb_ops *file_initialise_password_db(void)
+struct passdb_ops *file_initialize_password_db(void)
 {    
   return &file_ops;
 }
index a0d9b1b143570f57418ebc3b402c0bae8e653323..9d0aecf8b8a296ad71e54f8482e70bfbb2c7ac38 100644 (file)
 /*************************************************************
 add a new user to the local smbpasswd file
 *************************************************************/
-static BOOL add_new_user(char *user_name, uid_t uid,
-                               uint16 acb_info,
-                               uchar *new_p16, uchar *new_nt_p16)
+static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, 
+                        BOOL disable_user, BOOL set_no_password,
+                        uchar *new_p16, uchar *new_nt_p16)
 {
        struct smb_passwd new_smb_pwent;
 
-       pwdb_init_smb(&new_smb_pwent);
-
        /* Create a new smb passwd entry and set it to the given password. */
-       new_smb_pwent.unix_uid = uid;
-       new_smb_pwent.nt_name = user_name; 
+       new_smb_pwent.smb_userid = uid;
+       new_smb_pwent.smb_name = user_name; 
        new_smb_pwent.smb_passwd = NULL;
        new_smb_pwent.smb_nt_passwd = NULL;
-       new_smb_pwent.acct_ctrl = acb_info;
+       new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
        
-       if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
-       {
+       if(disable_user) {
+               new_smb_pwent.acct_ctrl |= ACB_DISABLED;
+       } else if (set_no_password) {
+               new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
+       } else {
                new_smb_pwent.smb_passwd = new_p16;
                new_smb_pwent.smb_nt_passwd = new_nt_p16;
        }
@@ -51,93 +52,83 @@ static BOOL add_new_user(char *user_name, uid_t uid,
 
 
 /*************************************************************
-change a password entry in the local smbpasswd file.
-
-when modifying an account, set acb_mask to those bits that
-require changing (to zero or one) and set acb_info to the
-value required in those bits.  all bits NOT set in acb_mask
-will NOT be modified.
-
-when _adding_ an account, acb_mask must be set to 0xFFFF and
-it is ignored, btw :-)
-
+change a password entry in the local smbpasswd file
 *************************************************************/
-BOOL local_password_change(char *user_name,
-                               BOOL add_user,
-                               uint16 acb_info, uint16 acb_mask,
-                               char *new_passwd, 
-                               char *err_str, size_t err_str_len,
-                               char *msg_str, size_t msg_str_len)
+
+BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+                          char *new_passwd, 
+                          char *err_str, size_t err_str_len,
+                          char *msg_str, size_t msg_str_len)
 {
-       const struct passwd  *pwd;
+       struct passwd  *pwd;
+       void *vp;
        struct smb_passwd *smb_pwent;
-       static struct smb_passwd new_pwent;
-       static uchar           new_p16[16];
-       static uchar           new_nt_p16[16];
-       fstring unix_name;
-       uid_t unix_uid;
+       uchar           new_p16[16];
+       uchar           new_nt_p16[16];
 
        *err_str = '\0';
        *msg_str = '\0';
 
-       pwd = Get_Pwnam(user_name, False);
+       pwd = sys_getpwnam(user_name);
        
        /*
-        * Check for a trust account.
+        * Check for a local account.
         */
        
-       if ((acb_info & acb_mask) != acb_info)
-       {
-               slprintf(err_str, err_str_len - 1, "programmer error: acb_info (%x) requests bits to be set outside of acb_mask (%x) range\n", acb_info, acb_mask);
-       }
-
-       if (pwd == NULL)
-       {
-               if (!IS_BITS_SET_ALL(acb_info, ACB_NORMAL))
-               {
-                       slprintf(err_str, err_str_len - 1, "User %s does not \
-exist in system password file (usually /etc/passwd).  \
-Cannot add trust account without a valid system user.\n", user_name);
-               }
-               else
-               {
-                       slprintf(err_str, err_str_len - 1, "User %s does not \
-exist in system password file (usually /etc/passwd).\n", user_name);
-               }
+       if(!pwd) {
+               slprintf(err_str, err_str_len - 1, "User %s does not \
+exist in system password file (usually /etc/passwd). Cannot add \
+account without a valid local system user.\n", user_name);
                return False;
        }
 
-       unix_uid = pwd->pw_uid;
-       fstrcpy(unix_name, pwd->pw_name);
-
        /* Calculate the MD4 hash (NT compatible) of the new password. */
        nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
 
+       /*
+        * Open the smbpaswd file.
+        */
+       vp = startsmbpwent(True);
+       if (!vp && errno == ENOENT) {
+               FILE *fp;
+               slprintf(msg_str,msg_str_len-1,
+                       "smbpasswd file did not exist - attempting to create it.\n");
+               fp = sys_fopen(lp_smb_passwd_file(), "w");
+               if (fp) {
+                       fprintf(fp, "# Samba SMB password file\n");
+                       fclose(fp);
+                       vp = startsmbpwent(True);
+               }
+       }
+
+       if (!vp) {
+               slprintf(err_str, err_str_len-1, "Cannot open file %s. Error was %s\n",
+                       lp_smb_passwd_file(), strerror(errno) );
+               return False;
+       }
+  
        /* Get the smb passwd entry for this user */
        smb_pwent = getsmbpwnam(user_name);
-       if (smb_pwent == NULL)
-       {
-               if (!add_user)
-               {
+       if (smb_pwent == NULL) {
+               if(add_user == False) {
                        slprintf(err_str, err_str_len-1,
-                               "Failed to find entry for user %s.\n", unix_name);
+                               "Failed to find entry for user %s.\n", pwd->pw_name);
+                       endsmbpwent(vp);
                        return False;
                }
 
-               if (add_new_user(user_name, unix_uid, acb_info,
-                                new_p16, new_nt_p16))
-               {
+               if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user,
+                                set_no_password, new_p16, new_nt_p16)) {
                        slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
+                       endsmbpwent(vp);
                        return True;
-               }
-               else
-               {
+               } else {
                        slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
+                       endsmbpwent(vp);
                        return False;
                }
-       }
-       else
-       {
+       } else {
                /* the entry already existed */
                add_user = False;
        }
@@ -147,25 +138,44 @@ exist in system password file (usually /etc/passwd).\n", user_name);
         * and the valid last change time.
         */
 
-       memcpy(&new_pwent, smb_pwent, sizeof(new_pwent));
-       new_pwent.nt_name = user_name; 
-       new_pwent.acct_ctrl &= ~acb_mask;
-       new_pwent.acct_ctrl |= (acb_info & acb_mask);
-       new_pwent.smb_passwd = NULL;
-       new_pwent.smb_nt_passwd = NULL;
-
-       if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
-       {
-               new_pwent.smb_passwd = new_p16;
-               new_pwent.smb_nt_passwd = new_nt_p16;
+       if(disable_user) {
+               smb_pwent->acct_ctrl |= ACB_DISABLED;
+       } else if (enable_user) {
+               if(smb_pwent->smb_passwd == NULL) {
+                       smb_pwent->smb_passwd = new_p16;
+                       smb_pwent->smb_nt_passwd = new_nt_p16;
+               }
+               smb_pwent->acct_ctrl &= ~ACB_DISABLED;
+       } else if (set_no_password) {
+               smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
+               /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+               smb_pwent->smb_passwd = NULL;
+               smb_pwent->smb_nt_passwd = NULL;
+       } else {
+               /*
+                * If we're dealing with setting a completely empty user account
+                * ie. One with a password of 'XXXX', but not set disabled (like
+                * an account created from scratch) then if the old password was
+                * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
+                * We remove that as we're giving this user their first password
+                * and the decision hasn't really been made to disable them (ie.
+                * don't create them disabled). JRA.
+                */
+               if((smb_pwent->smb_passwd == NULL) && (smb_pwent->acct_ctrl & ACB_DISABLED))
+                       smb_pwent->acct_ctrl &= ~ACB_DISABLED;
+               smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
+               smb_pwent->smb_passwd = new_p16;
+               smb_pwent->smb_nt_passwd = new_nt_p16;
        }
        
-       if (!mod_smbpwd_entry(&new_pwent, True))
-       {
+       if(mod_smbpwd_entry(smb_pwent,True) == False) {
                slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n",
-                       unix_name);
+                       pwd->pw_name);
+               endsmbpwent(vp);
                return False;
        }
 
+       endsmbpwent(vp);
+
        return True;
 }
index 7a73bf59324e9c0244d4da8b221e0fd1d052bdd2..bbe24131b8e8ec98b9e5285cdf3aff8574ef1a8f 100644 (file)
 extern int DEBUGLEVEL;
 
 BOOL global_machine_password_needs_changing = False;
-static int mach_passwd_lock_depth = 0;
-static FILE *mach_passwd_fp = NULL;
+
+/***************************************************************
+ Lock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
+BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
+{
+  if (fd < 0)
+    return False;
+
+  if(*plock_depth == 0) {
+    if (!do_file_lock(fd, secs, type)) {
+      DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
+                 strerror(errno)));
+      return False;
+    }
+  }
+
+  (*plock_depth)++;
+
+  return True;
+}
+
+/***************************************************************
+ Unlock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
+BOOL pw_file_unlock(int fd, int *plock_depth)
+{
+  BOOL ret=True;
+
+  if(*plock_depth == 1)
+    ret = do_file_lock(fd, 5, F_UNLCK);
+
+  if (*plock_depth > 0)
+    (*plock_depth)--;
+
+  if(!ret)
+    DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
+                 strerror(errno)));
+  return ret;
+}
+
+static int mach_passwd_lock_depth;
+static FILE *mach_passwd_fp;
 
 /************************************************************************
  Routine to get the name for a trust account file.
@@ -43,7 +86,7 @@ static void get_trust_account_file_name( char *domain, char *name, char *mac_fil
 
   if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0)
   {
-    DEBUG(0,("get_trust_account_file_name: path %s too long to add trust details.\n",
+    DEBUG(0,("trust_password_lock: path %s too long to add trust details.\n",
               mac_file));
     return;
   }
@@ -52,8 +95,6 @@ static void get_trust_account_file_name( char *domain, char *name, char *mac_fil
   pstrcat(mac_file, ".");
   pstrcat(mac_file, name);
   pstrcat(mac_file, ".mac");
-
-  DEBUG(5,("trust_account_file_name: %s\n", mac_file));
 }
  
 /************************************************************************
@@ -82,7 +123,7 @@ BOOL trust_password_lock( char *domain, char *name, BOOL update)
 
     chmod(mac_file, 0600);
 
-    if(!file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK), 
+    if(!pw_file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK), 
                                       60, &mach_passwd_lock_depth))
     {
       DEBUG(0,("trust_password_lock: cannot lock file %s\n", mac_file));
@@ -101,7 +142,7 @@ BOOL trust_password_lock( char *domain, char *name, BOOL update)
 
 BOOL trust_password_unlock(void)
 {
-  BOOL ret = file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
+  BOOL ret = pw_file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
   if(mach_passwd_lock_depth == 0)
     fclose(mach_passwd_fp);
   return ret;
@@ -158,7 +199,7 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
 
   if(strlen(linebuf) != 45) {
     DEBUG(0,("get_trust_account_password: Malformed trust password file (wrong length \
-- was %d, should be 45).\n", strlen(linebuf)));
+- was %d, should be 45).\n", (int)strlen(linebuf)));
 #ifdef DEBUG_PASSWORD
     DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
 #endif
@@ -169,7 +210,7 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
    * Get the hex password.
    */
 
-  if (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd, NULL) || linebuf[32] != ':' || 
+  if (!pdb_gethexpwd((char *)linebuf, ret_pwd) || linebuf[32] != ':' || 
          strncmp(&linebuf[33], "TLC-", 4)) {
     DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
 #ifdef DEBUG_PASSWORD
@@ -240,17 +281,17 @@ BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *mynam
   time_t lct;
 
   /*
-   * Get the trust account password.
+   * Get the machine account password.
    */
   if(!trust_password_lock( domain, myname, False)) {
-    DEBUG(0,("trust_get_passwd: unable to open the trust account password file for \
-trust %s in domain %s.\n", myname, domain ));
+    DEBUG(0,("domain_client_validate: unable to open the machine account password file for \
+machine %s in domain %s.\n", myname, domain ));
     return False;
   }
 
   if(get_trust_account_password( trust_passwd, &lct) == False) {
-    DEBUG(0,("trust_get_passwd: unable to read the trust account password for \
-trust %s in domain %s.\n", myname, domain ));
+    DEBUG(0,("domain_client_validate: unable to read the machine account password for \
+machine %s in domain %s.\n", myname, domain ));
     trust_password_unlock();
     return False;
   }
@@ -258,7 +299,7 @@ trust %s in domain %s.\n", myname, domain ));
   trust_password_unlock();
 
   /* 
-   * Here we check the last change time to see if the trust
+   * Here we check the last change time to see if the machine
    * password needs changing. JRA. 
    */
 
@@ -268,36 +309,3 @@ trust %s in domain %s.\n", myname, domain ));
   }
   return True;
 }
-
-/*********************************************************
-record Trust Account password.
-**********************************************************/
-BOOL create_trust_account_file(char *domain, char *name, uchar pass[16])
-{
-       /*
-        * Create the machine account password file.
-        */
-
-       if (!trust_password_lock( domain, name, True))
-       {
-               DEBUG(0,("unable to open the trust account password file for \
-account %s in domain %s.\n", name, domain)); 
-               return False;
-       }
-
-       /*
-        * Write the old machine account password.
-        */
-       
-       if (!set_trust_account_password( pass))
-       {              
-               DEBUG(0,("unable to write the trust account password for \
-%s in domain %s.\n", name, domain));
-               trust_password_unlock();
-               return False;
-       }
-       
-       trust_password_unlock();
-       
-       return True;
-}
index 8991cad97836936b35c143f0ff4284e5f94cfecf..4636c08c9492c0a4282e2ebab287823c624da005 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "includes.h"
 
-#ifdef USE_SMBGROUP_DB
+#ifdef USE_SMBPASS_DB
 
 static int grp_file_lock_depth = 0;
 extern int DEBUGLEVEL;
@@ -32,7 +32,7 @@ extern int DEBUGLEVEL;
 static void *startsmbfilegrpent(BOOL update)
 {
        static char s_readbuf[1024];
-       return startfileent(lp_smb_passgrp_file(), s_readbuf, sizeof(s_readbuf),
+       return startfilepwent(lp_smb_passgrp_file(), s_readbuf, sizeof(s_readbuf),
                              &grp_file_lock_depth, update);
 }
 
@@ -42,7 +42,7 @@ static void *startsmbfilegrpent(BOOL update)
 
 static void endsmbfilegrpent(void *vp)
 {
-       endfileent(vp, &grp_file_lock_depth);
+       endfilepwent(vp, &grp_file_lock_depth);
 }
 
 /*************************************************************************
@@ -77,8 +77,9 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
        static pstring  user_name;
        struct passwd *pwfile;
        pstring         linebuf;
-       char  *p;
+       unsigned char  *p;
        int            uidval;
+       size_t            linebuf_len;
 
        if (vp == NULL)
        {
@@ -91,12 +92,12 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
        /*
         * Scan the file, a line at a time.
         */
-       while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
+       while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
        {
                /*
                 * The line we have should be of the form :-
                 * 
-                * username:uid:aliasrid1,aliasrid2..:domainrid1,domainrid2..:
+                * username:uid:domainrid1,domainrid2..:aliasrid1,aliasrid2..:
                 */
 
                /*
@@ -105,12 +106,6 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
                 */
                p = strncpyn(user_name, linebuf, sizeof(user_name), ':');
 
-               if (p == NULL)
-               {
-                       DEBUG(0,("getsmbfilegrpent: no ':' separator found\n"));
-                       continue;
-               }
-
                /* Go past ':' */
                p++;
 
@@ -119,42 +114,48 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
                p = Atoic((char *) p, &uidval, ":");
 
                pw_buf.smb_name = user_name;
-               pw_buf.unix_uid = uidval;
+               pw_buf.smb_userid = uidval;
 
                /*
-                * Now get a list of alias RIDs
+                * Now get the password value - this should be 32 hex digits
+                * which are the ascii representations of a 16 byte string.
+                * Get two at a time and put them into the password.
                 */
 
                /* Skip the ':' */
                p++;
 
-               if (als_rids != NULL && num_alss != NULL)
+               if (grp_rids != NULL && num_grps != NULL)
                {
                        int i;
-                       p = get_numlist(p, als_rids, num_alss);
+                       p = get_numlist(p, grp_rids, num_grps);
                        if (p == NULL)
                        {
                                DEBUG(0,("getsmbfilegrpent: invalid line\n"));
                                return NULL;
                        }
+                       for (i = 0; i < (*num_grps); i++)
+                       {
+                               (*grp_rids)[i] = pwdb_gid_to_group_rid((*grp_rids)[i]);
+                       }
                }
 
-               /*
-                * Now get a list of group RIDs
-                */
-
                /* Skip the ':' */
                p++;
 
-               if (grp_rids != NULL && num_grps != NULL)
+               if (als_rids != NULL && num_alss != NULL)
                {
                        int i;
-                       p = get_numlist(p, grp_rids, num_grps);
+                       p = get_numlist(p, als_rids, num_alss);
                        if (p == NULL)
                        {
                                DEBUG(0,("getsmbfilegrpent: invalid line\n"));
                                return NULL;
                        }
+                       for (i = 0; i < (*num_alss); i++)
+                       {
+                               (*als_rids)[i] = pwdb_gid_to_alias_rid((*als_rids)[i]);
+                       }
                }
 
                pwfile = Get_Pwnam(pw_buf.smb_name, False);
@@ -191,5 +192,5 @@ struct passgrp_ops *file_initialise_password_grp(void)
 
 #else
  /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
- void smbpassgroup_dummy_function(void) { } /* stop some compilers complaining */
+ void smbpass_dummy_function(void) { } /* stop some compilers complaining */
 #endif /* USE_SMBPASS_DB */
index 242406c9748ec863e5f34776a6ebfe6a4a527eca..62010706bb3abe30139050f00df44eb435bb6296 100644 (file)
@@ -9,6 +9,8 @@
    Re-written again by Andrew Tridgell
 
    Modified for SVID support by Norm Jacobs, 1997
+
+   Modified for CUPS support by Michael Sweet, 1999
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -54,6 +56,9 @@
  *
  *  Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
  *  in smb.conf under Solaris.
+ *
+ *  Modified to call CUPS support if printcap name is set to "cups"
+ *  in smb.conf.
  */
 
 #include "includes.h"
@@ -69,7 +74,7 @@ extern int DEBUGLEVEL;
     ****************************************** */
 static int strlocate(char *xpLine,char *xpS)
 {
-       int iS,iL,i,iRet;
+       int iS,iL,iRet;
        char *p;
        iS = strlen(xpS);
        iL = strlen(xpLine);
@@ -91,9 +96,9 @@ static int strlocate(char *xpLine,char *xpS)
 /* ******************************************************************* */
 /* *    Scan qconfig and search all virtual printer (device printer) * */
 /* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)())
+static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
 {
-       int iLg,iEtat;
+       int iEtat;
        FILE *pfile;
        char *line,*p;
        pstring name,comment;
@@ -262,6 +267,11 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
        return(False);
       }
 
+#ifdef HAVE_LIBCUPS
+    if (strequal(psz, "cups"))
+       return (cups_printername_ok(pszPrintername));
+#endif /* HAVE_LIBCUPS */
+
 #ifdef SYSV
     if (strequal(psz, "lpstat"))
        return (sysv_printername_ok(pszPrintername));
@@ -329,6 +339,13 @@ void pcap_printer_fn(void (*fn)(char *, char *))
       return;
     }
 
+#ifdef HAVE_LIBCUPS
+    if (strequal(psz, "cups")) {
+      cups_printer_fn(fn);
+      return;
+    }
+#endif /* HAVE_LIBCUPS */
+
 #ifdef SYSV
     if (strequal(psz, "lpstat")) {
       sysv_printer_fn(fn);
index 5c5eebeb5028c193c59661af4fe5cddb2a6aec15..85eaf8f95dd5a38fe5cd8d53e5c2c19e7e5ee02e 100644 (file)
@@ -60,7 +60,17 @@ static void populate_printers(void)
                        if (((tmp = strchr(buf, ' ')) == NULL) ||
                            ((tmp = strchr(++tmp, ' ')) == NULL))
                                continue;
-                       name = ++tmp;
+
+                       /*
+                        * In case we're only at the "for ".
+                        */
+
+            if(!strncmp("for ",++tmp,4))
+            {
+                               tmp=strchr(tmp, ' ');
+                               tmp++;
+                       }
+                       name = tmp;
 
                        /* truncate the ": ..." */
                        if ((tmp = strchr(name, ':')) != NULL)
@@ -69,9 +79,12 @@ static void populate_printers(void)
                        /* add it to the cache */
                        if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
                                ZERO_STRUCTP(ptmp);
-                               ptmp->name = strdup(name);
+                               if((ptmp->name = strdup(name)) == NULL)
+                                       DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
                                ptmp->next = printers;
                                printers = ptmp;
+                       } else {
+                               DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
                        }
                }
                pclose(fp);
index e1fb53f40dc13e3c50a85dc54691204add755d3b..134a5946300ac6a7cacc23e53850920eb69b6a4f 100644 (file)
@@ -49,12 +49,12 @@ Build the print command in the supplied buffer. This means getting the
 print command for the service and inserting the printer name and the
 print file name. Return NULL on error, else the passed buffer pointer.
 ****************************************************************************/
-static char *build_print_command(connection_struct *conn, int snum,
+static char *build_print_command(connection_struct *conn,
                                 char *command, 
-                                char *syscmd, char *filename1)
+                                char *syscmd, char *filename)
 {
+       int snum = SNUM(conn);
        char *tstr;
-       pstring filename;
   
        /* get the print command for the service. */
        tstr = command;
@@ -72,13 +72,8 @@ static char *build_print_command(connection_struct *conn, int snum,
                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 */
@@ -90,17 +85,10 @@ static char *build_print_command(connection_struct *conn, int snum,
                tstr = SERVICE(snum);
        }
   
-       string_sub(syscmd, "%p", tstr);
+       pstring_sub(syscmd, "%p", tstr);
+  
+       standard_sub(conn,syscmd);
   
-       if (conn != NULL)
-       {
-               standard_sub(conn, syscmd);
-       }
-       else
-       {
-               standard_sub_basic(syscmd);
-       }
-
        return (syscmd);
 }
 
@@ -108,9 +96,10 @@ static char *build_print_command(connection_struct *conn, int snum,
 /****************************************************************************
 print a file - called on closing the file
 ****************************************************************************/
-void print_file(connection_struct *conn, int snum, files_struct *file)
+void print_file(connection_struct *conn, files_struct *file)
 {
        pstring syscmd;
+       int snum = SNUM(conn);
        char *tempstr;
 
        *syscmd = 0;
@@ -121,7 +110,7 @@ void print_file(connection_struct *conn, int snum, files_struct *file)
                return;
        }
 
-       tempstr = build_print_command(conn, snum,
+       tempstr = build_print_command(conn, 
                                      PRINTCOMMAND(snum), 
                                      syscmd, file->fsp_name);
        if (tempstr != NULL) {
@@ -252,7 +241,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]);
@@ -275,6 +264,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
@@ -345,7 +336,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);
   }
 
@@ -354,7 +345,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;
@@ -390,6 +381,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);
@@ -415,9 +408,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,"(","\"");
-  all_string_sub(line,")","\"");
+  pstring_sub(line,"standard input","STDIN");
+  all_string_sub(line,"(","\"",0);
+  all_string_sub(line,")","\"",0);
 
   for (count=0; 
        count<10 && 
@@ -532,9 +525,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,"(","\"");
-    all_string_sub(line,")","\"");
+    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 */
@@ -570,7 +563,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++) ;
       
@@ -605,7 +598,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
 
@@ -619,27 +612,47 @@ 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,"-"," ");
-  
-  for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
+  /* 
+   * 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.
+   */
+
+  /*
+   * 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);
-    }
-    
+  }
 
   buf->job = atoi(tok[1]);
   buf->size = atoi(tok[3]);
@@ -674,14 +687,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,"-- ","\"");
-  all_string_sub(line," --","\"");
+  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));
 
   
@@ -737,9 +750,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,"(","\"");
-  all_string_sub(line,")","\"");
+  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++) ;
 
@@ -807,7 +820,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++) ;
 
@@ -851,8 +864,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]);
@@ -964,7 +977,8 @@ static BOOL parse_lpq_entry(int snum,char *line,
 /****************************************************************************
 get a printer queue
 ****************************************************************************/
-int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue,
+int get_printqueue(int snum, 
+                  connection_struct *conn,print_queue_struct **queue,
                   print_status_struct *status)
 {
        char *lpq_command = lp_lpqcommand(snum);
@@ -993,16 +1007,9 @@ int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue
        }
     
        pstrcpy(syscmd,lpq_command);
-       string_sub(syscmd,"%p",printername);
+       pstring_sub(syscmd,"%p",printername);
 
-       if (conn != NULL)
-       {
-               standard_sub(conn, syscmd);
-       }
-       else
-       {
-               standard_sub_basic(syscmd);
-       }
+       standard_sub(conn,syscmd);
 
        slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
   
@@ -1039,7 +1046,7 @@ int get_printqueue(int snum, connection_struct *conn, print_queue_struct **queue
                        break;
                }
 
-               bzero((char *)&(*queue)[count],sizeof(**queue));
+               memset((char *)&(*queue)[count],'\0',sizeof(**queue));
          
                /* parse it */
                if (!parse_lpq_entry(snum,line,
@@ -1089,16 +1096,9 @@ void del_printqueue(connection_struct *conn,int snum,int jobid)
   slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
 
   pstrcpy(syscmd,lprm_command);
-  string_sub(syscmd,"%p",printername);
-  string_sub(syscmd,"%j",jobstr);
-       if (conn != NULL)
-       {
-               standard_sub(conn, syscmd);
-       }
-       else
-       {
-               standard_sub_basic(syscmd);
-       }
+  pstring_sub(syscmd,"%p",printername);
+  pstring_sub(syscmd,"%j",jobstr);
+  standard_sub(conn,syscmd);
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
@@ -1134,16 +1134,9 @@ void status_printjob(connection_struct *conn,int snum,int jobid,int status)
   slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
 
   pstrcpy(syscmd,lpstatus_command);
-  string_sub(syscmd,"%p",printername);
-  string_sub(syscmd,"%j",jobstr);
-       if (conn != NULL)
-       {
-               standard_sub(conn, syscmd);
-       }
-       else
-       {
-               standard_sub_basic(syscmd);
-       }
+  pstring_sub(syscmd,"%p",printername);
+  pstring_sub(syscmd,"%j",jobstr);
+  standard_sub(conn,syscmd);
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));  
@@ -1197,15 +1190,8 @@ void status_printqueue(connection_struct *conn,int snum,int status)
   }
 
   pstrcpy(syscmd,queuestatus_command);
-  string_sub(syscmd,"%p",printername);
-       if (conn != NULL)
-       {
-               standard_sub(conn, syscmd);
-       }
-       else
-       {
-               standard_sub_basic(syscmd);
-       }
+  pstring_sub(syscmd,"%p",printername);
+  standard_sub(conn,syscmd);
 
   ret = smbrun(syscmd,NULL,False);
   DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
index b685b1191697d41c34766073eb7f880d9b57e2c6..72954f90c9f50b64462661d67e920d69e09b3ed7 100644 (file)
 
 extern int DEBUGLEVEL;
 
-#define SHMEM_KEY ((key_t)0x07021999)
-#define SHM_MAGIC 0x6349985
-#define SHM_VERSION 1
-
 #define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
 
 static int shm_id;
@@ -52,13 +48,13 @@ BOOL profile_setup(BOOL rdonly)
 
  again:
        /* try to use an existing key */
-       shm_id = shmget(SHMEM_KEY, 0, 0);
+       shm_id = shmget(PROF_SHMEM_KEY, 0, 0);
        
        /* if that failed then create one. There is a race condition here
           if we are running from inetd. Bad luck. */
        if (shm_id == -1) {
                if (read_only) return False;
-               shm_id = shmget(SHMEM_KEY, sizeof(*profile_p), 
+               shm_id = shmget(PROF_SHMEM_KEY, sizeof(*profile_p), 
                                IPC_CREAT | IPC_EXCL | IPC_PERMS);
        }
        
@@ -101,6 +97,8 @@ BOOL profile_setup(BOOL rdonly)
 
        if (!read_only && (shm_ds.shm_nattch == 1)) {
                memset((char *)profile_p, 0, sizeof(*profile_p));
+               profile_p->prof_shm_magic = PROF_SHM_MAGIC;
+               profile_p->prof_shm_version = PROF_SHM_VERSION;
                DEBUG(3,("Initialised profile area\n"));
        }
 
index 9b26ca60f4742d3f5b75010098761692fa7e7517..5fe392f2148415136ff6c6c1acc05bdf08e3d12b 100644 (file)
@@ -4,6 +4,7 @@
    NT Domain Authentication SMB / MSRPC client
    Copyright (C) Andrew Tridgell 1994-1997
    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+   Copyright (C) Jeremy Allison  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
 #include "nterr.h"
 
 extern int DEBUGLEVEL;
+extern fstring global_myworkgroup;
+extern pstring global_myname;
 
 /****************************************************************************
 Initialize domain session credentials.
 ****************************************************************************/
 
-uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               unsigned char trust_pwd[16],
-                               uint16 sec_chan)
+BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
 {
-       DOM_CHAL clnt_chal;
-       DOM_CHAL srv_chal;
-       uint32 ret;
-       UTIME zerotime;
-       uint8 sess_key[16];
-       DOM_CRED clnt_cred;
-
-       /******************* Request Challenge ********************/
-
-       generate_random_buffer( clnt_chal.data, 8, False);
-
-       /* send a client challenge; receive a server challenge */
-       ret = cli_net_req_chal(srv_name, myhostname, &clnt_chal, &srv_chal);
-       if (ret != 0)
-       {
-               DEBUG(1,("cli_nt_setup_creds: request challenge failed\n"));
-               return ret;
-       }
-
-       /**************** Long-term Session key **************/
-
-       /* calculate the session key */
-       cred_session_key(&clnt_chal, &srv_chal, (char *)trust_pwd, sess_key);
-       bzero(sess_key+8, 8);
-
-       /******************* Authenticate 2 ********************/
-
-       /* calculate auth-2 credentials */
-       zerotime.time = 0;
-       cred_create(sess_key, &clnt_chal, zerotime, &clnt_cred.challenge);
-
-       if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred))
-       {
-               return NT_STATUS_ACCESS_DENIED | 0xC0000000;
-       }
-
-       /*  
-        * Send client auth-2 challenge.
-        * Receive an auth-2 challenge response and check it.
-        */
-
-       ret = cli_net_auth2(srv_name, trust_acct, myhostname,
-                           sec_chan, 0x000001ff, &srv_chal);
-       if (ret != 0x0)
-       {
-               DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed.  status: %x\n", ret));
-       }
-
-       return ret;
+  DOM_CHAL clnt_chal;
+  DOM_CHAL srv_chal;
+
+  UTIME zerotime;
+
+  /******************* Request Challenge ********************/
+
+  generate_random_buffer( clnt_chal.data, 8, False);
+       
+  /* send a client challenge; receive a server challenge */
+  if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal))
+  {
+    DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
+    return False;
+  }
+
+  /**************** Long-term Session key **************/
+
+  /* calculate the session key */
+  cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, cli->sess_key);
+  memset((char *)cli->sess_key+8, '\0', 8);
+
+  /******************* Authenticate 2 ********************/
+
+  /* calculate auth-2 credentials */
+  zerotime.time = 0;
+  cred_create(cli->sess_key, &clnt_chal, zerotime, &(cli->clnt_cred.challenge));
+
+  /*  
+   * Send client auth-2 challenge.
+   * Receive an auth-2 challenge response and check it.
+   */
+
+  if (!cli_net_auth2(cli, SEC_CHAN_WKSTA, 0x000001ff, &srv_chal))
+  {
+    DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
+    return False;
+  }
+
+  return True;
 }
 
 /****************************************************************************
  Set machine password.
  ****************************************************************************/
 
-BOOL cli_nt_srv_pwset(const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               unsigned char *new_hashof_trust_pwd,
-                               uint16 sec_chan)
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
 {
+  unsigned char processed_new_pwd[16];
+
   DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__));
 
 #ifdef DEBUG_PASSWORD
-  dump_data(6, new_hashof_trust_pwd, 16);
+  dump_data(6, (char *)new_hashof_mach_pwd, 16);
 #endif
 
+  /* Process the new password. */
+  cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1);
+
   /* send client srv_pwset challenge */
-  return cli_net_srv_pwset(srv_name, myhostname, trust_acct,
-                          new_hashof_trust_pwd, sec_chan);
+  return cli_net_srv_pwset(cli, processed_new_pwd);
 }
 
 /****************************************************************************
@@ -111,59 +103,51 @@ NT login - interactive.
 password equivalents, protected by the session key) is inherently insecure
 given the current design of the NT Domain system. JRA.
  ****************************************************************************/
-BOOL cli_nt_login_interactive(const char* srv_name, const char* myhostname,
-                               const char *domain, const char *username, 
-                               uint32 luid_low, char *password,
-                               NET_ID_INFO_CTR *ctr,
-                               NET_USER_INFO_3 *user_info3)
+BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username, 
+                              uint32 smb_userid_low, char *password,
+                              NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
 {
-       uchar lm_owf_user_pwd[16];
-       uchar nt_owf_user_pwd[16];
-       BOOL ret;
-       uint8 sess_key[16];
+  uchar lm_owf_user_pwd[16];
+  uchar nt_owf_user_pwd[16];
+  BOOL ret;
 
-       DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+  DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
 
-       nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
+  nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
 
 #ifdef DEBUG_PASSWORD
 
-       DEBUG(100,("nt owf of user password: "));
-       dump_data(100, lm_owf_user_pwd, 16);
+  DEBUG(100,("nt owf of user password: "));
+  dump_data(100, (char *)lm_owf_user_pwd, 16);
 
-       DEBUG(100,("nt owf of user password: "));
-       dump_data(100, nt_owf_user_pwd, 16);
+  DEBUG(100,("nt owf of user password: "));
+  dump_data(100, (char *)nt_owf_user_pwd, 16);
 
 #endif
 
-       if (!cli_get_sesskey_srv(srv_name, sess_key))
-       {
-               DEBUG(1,("could not obtain session key for %s\n", srv_name));
-               return False;
-       }
+  DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
 
-       /* indicate an "interactive" login */
-       ctr->switch_value = INTERACTIVE_LOGON_TYPE;
+  /* indicate an "interactive" login */
+  ctr->switch_value = INTERACTIVE_LOGON_TYPE;
 
-       /* Create the structure needed for SAM logon. */
-       make_id_info1(&ctr->auth.id1, domain, 0, 
-                                   luid_low, 0,
-                                   username, myhostname,
-                                   (char *)sess_key,
-                                   lm_owf_user_pwd, nt_owf_user_pwd);
+  /* Create the structure needed for SAM logon. */
+  init_id_info1(&ctr->auth.id1, domain, 0, 
+                smb_userid_low, 0,
+                username, cli->clnt_name_slash,
+                (char *)cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
 
-       /* Ensure we overwrite all the plaintext password
-       equivalents. */
-       memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
-       memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
+  /* Ensure we overwrite all the plaintext password
+     equivalents. */
+  memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
+  memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
 
-       /* Send client sam-logon request - update credentials on success. */
-       ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
+  /* Send client sam-logon request - update credentials on success. */
+  ret = cli_net_sam_logon(cli, ctr, user_info3);
 
-       memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
-       memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
+  memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
+  memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
 
-       return ret;
+  return ret;
 }
 
 /****************************************************************************
@@ -172,98 +156,33 @@ NT login - network.
 password equivalents over the network. JRA.
 ****************************************************************************/
 
-BOOL cli_nt_login_network(const char* srv_name, const char* myhostname,
-                               const char *domain, const char *username, 
-                               uint32 luid_low, char lm_chal[8],
-                               char lm_chal_resp[24],
-                               char nt_chal_resp[24],
-                               NET_ID_INFO_CTR *ctr,
-                               NET_USER_INFO_3 *user_info3)
+BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, 
+                          uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
+                          char nt_chal_resp[24],
+                          NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
 {
-       uint8 sess_key[16];
-       BOOL ret;
-       DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
-
-       if (!cli_get_sesskey_srv(srv_name, sess_key))
-       {
-               DEBUG(1,("could not obtain session key for %s\n", srv_name));
-               return False;
-       }
+  DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
 
-       /* indicate a "network" login */
-       ctr->switch_value = NET_LOGON_TYPE;
-
-       /* Create the structure needed for SAM logon. */
-       make_id_info2(&ctr->auth.id2, domain, 0, 
-               luid_low, 0,
-               username, myhostname,
-               (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp);
-
-       /* Send client sam-logon request - update credentials on success. */
-       ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("cli sess key:"));
-       dump_data(100, sess_key, 8);
-       DEBUG(100,("enc user sess key:"));
-       dump_data(100, user_info3->user_sess_key, 16);
-#endif
+  /* indicate a "network" login */
+  ctr->switch_value = NET_LOGON_TYPE;
 
-       SamOEMhash(user_info3->user_sess_key, sess_key, False);
+  /* Create the structure needed for SAM logon. */
+  init_id_info2(&ctr->auth.id2, domain, 0, 
+                smb_userid_low, 0,
+                username, cli->clnt_name_slash,
+                (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp);
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("dec user sess key:"));
-       dump_data(100, user_info3->user_sess_key, 16);
-#endif
-       return ret;
+  /* Send client sam-logon request - update credentials on success. */
+  return cli_net_sam_logon(cli, ctr, user_info3);
 }
 
 /****************************************************************************
 NT Logoff.
 ****************************************************************************/
-BOOL cli_nt_logoff(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr)
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
 {
   DEBUG(5,("cli_nt_logoff: %d\n", __LINE__));
 
   /* Send client sam-logoff request - update credentials on success. */
-  return cli_net_sam_logoff(srv_name, myhostname, ctr);
+  return cli_net_sam_logoff(cli, ctr);
 }
-
-/****************************************************************************
-NT SAM database sync
-****************************************************************************/
-BOOL net_sam_sync(const char* srv_name, const char* myhostname,
-                               const char* trust_acct,
-                               uchar trust_passwd[16],
-                               SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
-                               SAM_DELTA_CTR deltas    [MAX_SAM_DELTAS],
-                               uint32 *num_deltas)
-{
-       BOOL res = True;
-
-       *num_deltas = 0;
-
-       DEBUG(5,("Attempting SAM sync with PDC: %s\n",
-               srv_name));
-
-       res = res ? cli_nt_setup_creds( srv_name, myhostname,
-                                      trust_acct, 
-                                      trust_passwd, SEC_CHAN_BDC) == 0x0 : False;
-
-       memset(trust_passwd, 0, 16);
-
-       res = res ? cli_net_sam_sync(srv_name, myhostname,
-                                    0, num_deltas, hdr_deltas, deltas) : False;
-
-       if (!res)
-       {
-               DEBUG(5, ("SAM synchronisation FAILED\n"));
-               return False;
-       }
-
-       DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas));
-
-       return True;
-}
-
index b039bde159bf4def6b697b9cd9c36740be2c53b0..cfd562785b34650a59c2753841827b10e1798bf1 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Jeremy Allison                    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
 
 extern int DEBUGLEVEL;
 
-/****************************************************************************
- obtain the sid from the PDC.  do some verification along the way...
-****************************************************************************/
-BOOL get_domain_sids(const char *domain, DOM_SID *sid3, DOM_SID *sid5)
-{
-       POLICY_HND pol;
-       fstring srv_name;
-       struct cli_connection *con = NULL;
-       BOOL res = True;
-       BOOL res1 = True;
-       fstring dom3;
-       fstring dom5;
-       extern struct ntuser_creds *usr_creds;
-       struct ntuser_creds usr;
-       
-       usr_creds = &usr;
-       ZERO_STRUCT(usr);
-       pwd_set_nullpwd(&usr.pwd);
-
-       if (sid3 == NULL && sid5 == NULL)
-       {
-               /* don't waste my time... */
-               return False;
-       }
-
-       if (!get_any_dc_name(domain, srv_name))
-       {
-               return False;
-       }
-
-       /*
-        * Ok - we have an anonymous connection to the IPC$ share.
-        * Now start the NT Domain stuff :-).
-        */
-
-       fstrcpy(dom3, "");
-       fstrcpy(dom5, "");
-       if (sid3 != NULL)
-       {
-               ZERO_STRUCTP(sid3);
-       }
-       if (sid5 != NULL)
-       {
-               ZERO_STRUCTP(sid5);
-       }
-
-       /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy(srv_name, &pol, False) : False;
-
-       if (sid3 != NULL)
-       {
-               /* send client info query, level 3.  receive domain name and sid */
-               res1 = res ? lsa_query_info_pol(&pol, 3, dom3, sid3) : False;
-       }
-
-       if (sid5 != NULL)
-       {
-               /* send client info query, level 5.  receive domain name and sid */
-               res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, sid5) : False;
-       }
-
-       /* close policy handle */
-       res = res ? lsa_close(&pol) : False;
-
-       /* close the session */
-       cli_connection_unlink(con);
-
-       if (res1)
-       {
-               pstring sid;
-               DEBUG(2,("LSA Query Info Policy\n"));
-               if (sid3 != NULL)
-               {
-                       sid_to_string(sid, sid3);
-                       DEBUG(2,("Domain Member     - Domain: %s SID: %s\n", dom3, sid));
-               }
-               if (sid5 != NULL)
-               {
-                       sid_to_string(sid, sid5);
-                       DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid));
-               }
-       }
-       else
-       {
-               DEBUG(1,("lsa query info failed\n"));
-       }
-
-       return res;
-}
-
-#if 0
-/****************************************************************************
- obtain a sid and domain name from a Domain Controller.  
-****************************************************************************/
-BOOL get_trust_sid_and_domain(const char* myname, char *server,
-                               DOM_SID *sid,
-                               char *domain, size_t len)
-{
-       POLICY_HND pol;
-       fstring srv_name;
-       struct cli_connection *con = NULL;
-       BOOL res = True;
-       BOOL res1 = True;
-       DOM_SID sid3;
-       DOM_SID sid5;
-       fstring dom3;
-       fstring dom5;
-
-       extern struct ntuser_creds *usr_creds;
-       struct ntuser_creds usr;
-       
-       usr_creds = &usr;
-       ZERO_STRUCT(usr);
-       pwd_set_nullpwd(&usr.pwd);
-
-       if (!cli_connection_init_list(server, PIPE_LSARPC, &con))
-       {
-               DEBUG(0,("get_trust_sid: unable to initialise client connection.\n"));
-               return False;
-       }
-
-       fstrcpy(dom3, "");
-       fstrcpy(dom5, "");
-       ZERO_STRUCT(sid3);
-       ZERO_STRUCT(sid5);
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, myname);
-       strupper(srv_name);
-
-       /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy(srv_name, &pol, False) : False;
-
-       /* send client info query, level 3.  receive domain name and sid */
-       res1 = res ? lsa_query_info_pol(&pol, 3, dom3, &sid3) : False;
-
-       /* send client info query, level 5.  receive domain name and sid */
-       res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, &sid5) : False;
-
-       /* close policy handle */
-       res = res ? lsa_close(&pol) : False;
-
-       /* close the session */
-       cli_connection_unlink(con);
-
-       if (res1)
-       {
-               pstring sid_str;
-               DEBUG(2,("LSA Query Info Policy\n"));
-               sid_to_string(sid_str, &sid3);
-               DEBUG(2,("Domain Member     - Domain: %s SID: %s\n",
-                         dom3, sid_str));
-               sid_to_string(sid_str, &sid5);
-               DEBUG(2,("Domain Controller - Domain: %s SID: %s\n",
-                         dom5, sid_str));
-
-               if (dom5[0] != 0 && sid_equal(&sid3, &sid5))
-               {
-                       safe_strcpy(domain, dom5, len);
-                       sid_copy(sid, &sid5);
-               }
-               else
-               {
-                       DEBUG(2,("Server %s is not a PDC\n", server));
-                       return False;
-               }
-
-       }
-       else
-       {
-               DEBUG(1,("lsa query info failed\n"));
-       }
-
-       return res1;
-}
-#endif
 
 /****************************************************************************
 do a LSA Open Policy
 ****************************************************************************/
-BOOL lsa_open_policy(const char *server_name, POLICY_HND *hnd,
+
+BOOL do_lsa_open_policy(struct cli_state *cli,
+                       char *server_name, POLICY_HND *hnd,
                        BOOL sec_qos)
 {
        prs_struct rbuf;
        prs_struct buf; 
        LSA_Q_OPEN_POL q_o;
        LSA_SEC_QOS qos;
-       BOOL valid_pol = False;
-       struct cli_connection *con = NULL;
+       LSA_R_OPEN_POL r_o;
 
-       if (!cli_connection_init(server_name, PIPE_LSARPC, &con))
-       {
+       if (hnd == NULL)
                return False;
-       }
 
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL );
 
        /* create and send a MSRPC command with api LSA_OPENPOLICY */
 
        DEBUG(4,("LSA Open Policy\n"));
 
        /* store the parameters */
-       if (sec_qos)
-       {
-               make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
-               make_q_open_pol(&q_o, 0x5c, 0, 0x02000000, &qos);
-       }
-       else
-       {
-               make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
+       if (sec_qos) {
+               init_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
+               init_q_open_pol(&q_o, 0x5c, 0, 0, &qos);
+       } else {
+               init_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
        }
 
        /* turn parameters into data stream */
-       lsa_io_q_open_pol("", &q_o, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, LSA_OPENPOLICY, &buf, &rbuf))
-       {
-               LSA_R_OPEN_POL r_o;
-               BOOL p;
-
-               lsa_io_r_open_pol("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-                       
-                       valid_pol = register_policy_hnd(hnd) &&
-                                   set_policy_con(hnd, con, 
-                                                        cli_connection_unlink);
-               }
-       }
-
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a LSA Open Policy2
-****************************************************************************/
-BOOL lsa_open_policy2( const char *server_name, POLICY_HND *hnd,
-                       BOOL sec_qos)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       LSA_Q_OPEN_POL2 q_o;
-       LSA_SEC_QOS qos;
-       BOOL valid_pol = False;
-
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_init(server_name, PIPE_LSARPC, &con))
-       {
+       if(!lsa_io_q_open_pol("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
                return False;
        }
 
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api LSA_OPENPOLICY2 */
-
-       DEBUG(4,("LSA Open Policy2\n"));
-
-       /* store the parameters */
-       if (sec_qos)
-       {
-               make_lsa_sec_qos(&qos, 2, 1, 0, 0x02000000);
-               make_q_open_pol2(&q_o, server_name, 0, 0x02000000, &qos);
-       }
-       else
-       {
-               make_q_open_pol2(&q_o, server_name, 0, 0x02000000, NULL);
-       }
-
-       /* turn parameters into data stream */
-       lsa_io_q_open_pol2("", &q_o, &buf, 0);
-
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_OPENPOLICY2, &buf, &rbuf))
-       {
-               LSA_R_OPEN_POL2 r_o;
-               BOOL p;
-
-               lsa_io_r_open_pol2("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_OPENPOLICY2: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-                       valid_pol = register_policy_hnd(hnd) &&
-                                   set_policy_con(hnd, con, 
-                                                        cli_connection_unlink);
-               }
-       }
-
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a LSA Open Secret
-****************************************************************************/
-BOOL lsa_open_secret( const POLICY_HND *hnd,
-                               const char *secret_name,
-                               uint32 des_access,
-                               POLICY_HND *hnd_secret)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       LSA_Q_OPEN_SECRET q_o;
-       BOOL valid_pol = False;
-
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api LSA_OPENSECRET */
-
-       DEBUG(4,("LSA Open Secret\n"));
-
-       make_q_open_secret(&q_o, hnd, secret_name, des_access);
-
-       /* turn parameters into data stream */
-       lsa_io_q_open_secret("", &q_o, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_OPENSECRET, &buf, &rbuf))
-       {
-               LSA_R_OPEN_SECRET r_o;
-               BOOL p;
-
-               lsa_io_r_open_secret("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data));
-                       valid_pol = True;
-               }
+       if (!rpc_api_pipe_req(cli, LSA_OPENPOLICY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a LSA Query Secret
-****************************************************************************/
-BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 *secret,
-                     NTTIME *last_update)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       LSA_Q_QUERY_SECRET q_q;
-       BOOL valid_info = False;
-
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_mem_free(&buf);
 
-       /* create and send a MSRPC command with api LSA_QUERYSECRET */
-
-       DEBUG(4,("LSA Query Secret\n"));
-
-       make_q_query_secret(&q_q, hnd);
-
-       /* turn parameters into data stream */
-       lsa_io_q_query_secret("", &q_q, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_QUERYSECRET, &buf, &rbuf))
-       {
-               LSA_R_QUERY_SECRET r_q;
-               BOOL p;
-
-               lsa_io_r_query_secret("", &r_q, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_q.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status)));
-                       p = False;
-               }
-
-               if (p && (r_q.info.ptr_value != 0) &&
-                   (r_q.info.value.ptr_secret != 0) &&
-                   (r_q.info.ptr_update != 0))
-               {
-                       uchar sess_key[16];
-                       STRING2 enc_secret;
-                       memcpy(&enc_secret,  &(r_q.info.value.enc_secret), sizeof(STRING2));
-                       memcpy(last_update, &(r_q.info.last_update),      sizeof(NTTIME));
-                       if (!cli_get_sesskey(hnd, sess_key))
-                       {
-                               return False;
-                       }
-#ifdef DEBUG_PASSWORD
-                       dump_data(100, sess_key, 16);
-#endif
-                       valid_info = nt_decrypt_string2(secret, &enc_secret,
-                                    sess_key);
-               }
+       if(!lsa_io_r_open_pol("", &r_o, &rbuf, 0)) {
+               DEBUG(0,("do_lsa_open_policy: Failed to unmarshall LSA_R_OPEN_POL\n"));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_info;
-}
-
-
-/****************************************************************************
-do a LSA Lookup Names
-****************************************************************************/
-BOOL lsa_lookup_names( POLICY_HND *hnd,
-                       int num_names,
-                       char **names,
-                       DOM_SID **sids,
-                       uint8 **types,
-                       int *num_sids)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       LSA_Q_LOOKUP_NAMES q_l;
-       BOOL valid_response = False;
-
-       if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
-
-       DEBUG(4,("LSA Lookup NAMEs\n"));
-
-       /* store the parameters */
-       make_q_lookup_names(&q_l, hnd, num_names, names);
-
-       /* turn parameters into data stream */
-       lsa_io_q_lookup_names("", &q_l, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPNAMES, &buf, &rbuf))
-       {
-               LSA_R_LOOKUP_NAMES r_l;
-               DOM_R_REF ref;
-               DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
-               BOOL p;
-
-               ZERO_STRUCT(ref);
-               ZERO_STRUCT(t_rids);
-
-               r_l.dom_ref = &ref;
-               r_l.dom_rid = t_rids;
-
-               lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
-               p = rbuf.offset != 0;
-               
-               if (p && r_l.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(1,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       if (r_l.ptr_dom_ref != 0 && r_l.ptr_entries != 0)
-                       {
-                               valid_response = True;
-                       }
-               }
-
-               if (num_sids != NULL && valid_response)
-               {
-                       (*num_sids) = r_l.num_entries;
-               }
-               if (valid_response)
-               {
-                       uint32 i;
-                       for (i = 0; i < r_l.num_entries; i++)
-                       {
-                               if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
-                                   t_rids[i].rid_idx != 0xffffffff)
-                               {
-                                       DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
-                                                 t_rids[i].rid_idx));
-                                       valid_response = False;
-                                       break;
-                               }
-                       }
-               }
-
-               if (types != NULL && valid_response && r_l.num_entries != 0)
-               {
-                       (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8));
-               }
-
-               if (sids != NULL && valid_response && r_l.num_entries != 0)
-               {
-                       (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID));
-               }
-
-               if (sids != NULL && (*sids) != NULL)
-               {
-                       int i;
-                       /* take each name, construct a SID */
-                       for (i = 0; i < (*num_sids); i++)
-                       {
-                               uint32 dom_idx = t_rids[i].rid_idx;
-                               uint32 dom_rid = t_rids[i].rid;
-                               DOM_SID *sid = &(*sids)[i];
-                               if (dom_idx != 0xffffffff)
-                               {
-                                       sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid);
-                                       if (dom_rid != 0xffffffff)
-                                       {
-                                               sid_append_rid(sid, dom_rid);
-                                       }
-                                       if (types != NULL && (*types) != NULL)
-                                       {
-                                               (*types)[i] = t_rids[i].type;
-                                       }
-                               }
-                               else
-                               {
-                                       ZERO_STRUCTP(sid);
-                                       if (types != NULL && (*types) != NULL)
-                                       {
-                                               (*types)[i] = SID_NAME_UNKNOWN;
-                                       }
-                               }
-                       }
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       } else {
+               /* ok, at last: we're happy. return the policy handle */
+               memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_response;
+       return True;
 }
 
 /****************************************************************************
 do a LSA Lookup SIDs
 ****************************************************************************/
-BOOL lsa_lookup_sids(POLICY_HND *hnd,
+
+BOOL do_lsa_lookup_sids(struct cli_state *cli,
+                       POLICY_HND *hnd,
                        int num_sids,
                        DOM_SID **sids,
                        char ***names,
-                       uint8 **types,
                        int *num_names)
 {
        prs_struct rbuf;
        prs_struct buf; 
        LSA_Q_LOOKUP_SIDS q_l;
+       LSA_R_LOOKUP_SIDS r_l;
+       DOM_R_REF ref;
+       LSA_TRANS_NAME_ENUM t_names;
+       int i;
        BOOL valid_response = False;
 
-       ZERO_STRUCT(q_l);
-
-       if (hnd == NULL || num_sids == 0 || sids == NULL) return False;
-
-       if (num_names != NULL)
-       {
-               *num_names = 0;
-       }
-       if (types != NULL)
-       {
-               *types = NULL;
-       }
-       if (names != NULL)
-       {
-               *names = NULL;
-       }
+       if (hnd == NULL || num_sids == 0 || sids == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL );
 
        /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
 
        DEBUG(4,("LSA Lookup SIDs\n"));
 
        /* store the parameters */
-       make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
+       init_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
 
        /* turn parameters into data stream */
-       lsa_io_q_lookup_sids("", &q_l, &buf, 0);
+       if(!lsa_io_q_lookup_sids("", &q_l, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPSIDS, &buf, &rbuf))
-       {
-               LSA_R_LOOKUP_SIDS r_l;
-               DOM_R_REF ref;
-               LSA_TRANS_NAME_ENUM t_names;
-               BOOL p;
-
-               r_l.dom_ref = &ref;
-               r_l.names   = &t_names;
-
-               lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
-               p = rbuf.offset != 0;
+       if (!rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       prs_mem_free(&buf);
+
+       r_l.dom_ref = &ref;
+       r_l.names   = &t_names;
+
+       if(!lsa_io_r_lookup_sids("", &r_l, &rbuf, 0)) {
+               DEBUG(0,("do_lsa_lookup_sids: Failed to unmarshall LSA_R_LOOKUP_SIDS\n"));
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
                
-               if (p && r_l.status != 0 &&
-                        r_l.status != 0x107 &&
-                        r_l.status != (0xC0000000 | NT_STATUS_NONE_MAPPED))
-               {
-                       /* report error code */
-                       DEBUG(1,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
-                       p = False;
-               }
+       if (r_l.status != 0) {
+               /* report error code */
+               DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
+       } else {
+               if (t_names.ptr_trans_names != 0)
+                       valid_response = True;
+       }
 
-               if (p)
-               {
-                       if (t_names.ptr_trans_names != 0 && r_l.ptr_dom_ref != 0)
-                       {
-                               valid_response = True;
-                       }
-               }
+       if(!valid_response) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (num_names != NULL && valid_response)
-               {
-                       (*num_names) = t_names.num_entries;
-               }
-               if (valid_response)
-               {
-                       uint32 i;
-                       for (i = 0; i < t_names.num_entries; i++)
-                       {
-                               if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
-                               {
-                                       DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
-                                       valid_response = False;
-                                       break;
-                               }
-                       }
-               }
+       if (num_names != NULL)
+               (*num_names) = t_names.num_entries;
 
-               if (types != NULL && valid_response && (*num_names) != 0)
-               {
-                       (*types) = (uint8*)malloc((*num_names) * sizeof(uint8));
+       for (i = 0; i < t_names.num_entries; i++) {
+               if (t_names.name[i].domain_idx >= ref.num_ref_doms_1) {
+                       DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
+                       prs_mem_free(&rbuf);
+                       return False;
                }
+       }
 
-               if (names != NULL && valid_response && (*num_names) != 0)
-               {
-                       (*names) = (char**)malloc((*num_names) * sizeof(char*));
-               }
+       if (names != NULL && t_names.num_entries != 0)
+               (*names) = (char**)malloc((*num_names) * sizeof(char*));
+
+       if (names != NULL && (*names) != NULL) {
+               /* take each name, construct a \DOMAIN\name string */
+               for (i = 0; i < (*num_names); i++) {
+                       fstring name;
+                       fstring dom_name;
+                       fstring full_name;
+                       uint32 dom_idx = t_names.name[i].domain_idx;
+                       fstrcpy(dom_name, dos_unistr2(ref.ref_dom[dom_idx].uni_dom_name.buffer));
+                       fstrcpy(name, dos_unistr2(t_names.uni_name[i].buffer));
+                       
+                       slprintf(full_name, sizeof(full_name)-1, "\\%s\\%s",
+                                dom_name, name);
 
-               if (names != NULL && (*names) != NULL)
-               {
-                       int i;
-                       /* take each name, construct a \DOMAIN\name string */
-                       for (i = 0; i < (*num_names); i++)
-                       {
-                               fstring name;
-                               fstring dom_name;
-                               fstring full_name;
-                               uint32 dom_idx = t_names.name[i].domain_idx;
-
-                               if (dom_idx != 0xffffffff)
-                               {
-                                       unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1);
-                                       unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1);
-                                       
-                                       memset(full_name, 0, sizeof(full_name));
-
-                                       slprintf(full_name, sizeof(full_name)-1, "%s\\%s",
-                                                dom_name, name);
-
-                                       (*names)[i] = strdup(full_name);
-                                       if (types != NULL && (*types) != NULL)
-                                       {
-                                               (*types)[i] = t_names.name[i].sid_name_use;
-                                       }
-                               }
-                               else
-                               {
-                                       (*names)[i] = NULL;
-                                       if (types != NULL && (*types) != NULL)
-                                       {
-                                               (*types)[i] = SID_NAME_UNKNOWN;
-                                       }
-                               }
-                       }
+                       (*names)[i] = strdup(full_name);
                }
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
        return valid_response;
 }
@@ -764,254 +213,169 @@ BOOL lsa_lookup_sids(POLICY_HND *hnd,
 /****************************************************************************
 do a LSA Query Info Policy
 ****************************************************************************/
-BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+BOOL do_lsa_query_info_pol(struct cli_state *cli,
+                       POLICY_HND *hnd, uint16 info_class,
                        fstring domain_name, DOM_SID *domain_sid)
 {
        prs_struct rbuf;
        prs_struct buf; 
        LSA_Q_QUERY_INFO q_q;
-       BOOL valid_response = False;
+       LSA_R_QUERY_INFO r_q;
+       fstring sid_str;
 
        ZERO_STRUCTP(domain_sid);
        domain_name[0] = 0;
 
-       if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
+       if (hnd == NULL || domain_name == NULL || domain_sid == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL );
 
        /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
 
        DEBUG(4,("LSA Query Info Policy\n"));
 
        /* store the parameters */
-       make_q_query(&q_q, hnd, info_class);
+       init_q_query(&q_q, hnd, info_class);
 
        /* turn parameters into data stream */
-       lsa_io_q_query("", &q_q, &buf, 0);
+       if(!lsa_io_q_query("", &q_q, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_QUERYINFOPOLICY, &buf, &rbuf))
-       {
-               LSA_R_QUERY_INFO r_q;
-               BOOL p;
-
-               lsa_io_r_query("", &r_q, &rbuf, 0);
-               p = rbuf.offset != 0;
-               
-               if (p && r_q.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
-                       p = False;
-               }
-
-               if (p && r_q.info_class != q_q.info_class)
-               {
-                       /* report different info classes */
-                       DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
-                                       q_q.info_class, r_q.info_class));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       fstring sid_str;
-                       /* ok, at last: we're happy. */
-                       switch (r_q.info_class)
-                       {
-                               case 3:
-                               {
-                                       if (r_q.dom.id3.buffer_dom_name != 0)
-                                       {
-                                               unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1);
-                                       }
-                                       if (r_q.dom.id3.buffer_dom_sid != 0)
-                                       {
-                                               *domain_sid = r_q.dom.id3.dom_sid.sid;
-                                       }
-
-                                       valid_response = True;
-                                       break;
-                               }
-                               case 5:
-                               {
-                                       if (r_q.dom.id5.buffer_dom_name != 0)
-                                       {
-                                               unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1);
-                                       }
-                                       if (r_q.dom.id5.buffer_dom_sid != 0)
-                                       {
-                                               *domain_sid = r_q.dom.id5.dom_sid.sid;
-                                       }
-
-                                       valid_response = True;
-                                       break;
-                               }
-                               default:
-                               {
-                                       DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
-                                       domain_name[0] = 0;
-
-                                       break;
-                               }
-                       }
-               
-                       sid_to_string(sid_str, domain_sid);
-                       DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s  domain sid:%s\n",
-                                 r_q.info_class, domain_name, sid_str));
-               }
+       if (!rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_response;
-}
-
-/****************************************************************************
-do a LSA Enumerate Trusted Domain 
-****************************************************************************/
-BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx,
-                       uint32 *num_doms, char ***names,
-                       DOM_SID ***sids)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       LSA_Q_ENUM_TRUST_DOM q_q;
-       BOOL valid_response = False;
-
-       if (hnd == NULL || num_doms == NULL || names == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api LSA_ENUMTRUSTDOM */
-
-       DEBUG(4,("LSA Enum Trusted Domains\n"));
-
-       /* store the parameters */
-       make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff);
-
-       /* turn parameters into data stream */
-       lsa_io_q_enum_trust_dom("", &q_q, &buf, 0);
+       prs_mem_free(&buf);
 
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_ENUMTRUSTDOM, &buf, &rbuf))
-       {
-               LSA_R_ENUM_TRUST_DOM r_q;
-               BOOL p;
+       if(!lsa_io_r_query("", &r_q, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0);
-               p = rbuf.offset != 0;
-               
-               if (p && r_q.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_ENUMTRUSTDOM: %s\n", get_nt_error_msg(r_q.status)));
-                       p = r_q.status == 0x8000001a;
-               }
+       if (r_q.status != 0) {
+               /* report error code */
+               DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       uint32 i;
-                       uint32 num_sids = 0;
-                       valid_response = True;
+       if (r_q.info_class != q_q.info_class) {
+               /* report different info classes */
+               DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
+                               q_q.info_class, r_q.info_class));
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-                       for (i = 0; i < r_q.num_domains; i++)
-                       {
-                               fstring tmp;
-                               unistr2_to_ascii(tmp, &r_q.uni_domain_name[i],
-                                                sizeof(tmp)-1);
-                               add_chars_to_array(num_doms, names, tmp);
-                               add_sid_to_array(&num_sids, sids,
-                                                &r_q.domain_sid[i].sid);
-                       }
-
-                       if (r_q.status == 0x0)
-                       {
-                               *enum_ctx = r_q.enum_context;
-                       }
-                       else
-                       {
-                               *enum_ctx = 0;
-                       }
-               }
+       /* ok, at last: we're happy. */
+       switch (r_q.info_class) {
+       case 3:
+               if (r_q.dom.id3.buffer_dom_name != 0) {
+                       char *dom_name = dos_unistrn2(r_q.dom.id3.uni_domain_name.buffer,
+                                                 r_q.dom.id3.uni_domain_name.uni_str_len);
+                       fstrcpy(domain_name, dom_name);
+               }
+               if (r_q.dom.id3.buffer_dom_sid != 0)
+                       *domain_sid = r_q.dom.id3.dom_sid.sid;
+               break;
+       case 5:
+               if (r_q.dom.id5.buffer_dom_name != 0) {
+                       char *dom_name = dos_unistrn2(r_q.dom.id5.uni_domain_name.buffer,
+                                                 r_q.dom.id5.uni_domain_name.uni_str_len);
+                       fstrcpy(domain_name, dom_name);
+               }
+               if (r_q.dom.id5.buffer_dom_sid != 0)
+                       *domain_sid = r_q.dom.id5.dom_sid.sid;
+               break;
+       default:
+               DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
+               domain_name[0] = 0;
+
+               prs_mem_free(&rbuf);
+               return False;
        }
+               
+       sid_to_string(sid_str, domain_sid);
+       DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s  domain sid:%s\n",
+                 r_q.info_class, domain_name, sid_str));
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_response;
+       return True;
 }
 
 /****************************************************************************
 do a LSA Close
 ****************************************************************************/
-BOOL lsa_close(POLICY_HND *hnd)
+
+BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        LSA_Q_CLOSE q_c;
-       BOOL valid_close = False;
+       LSA_R_CLOSE r_c;
+       int i;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
        /* create and send a MSRPC command with api LSA_OPENPOLICY */
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL );
 
        DEBUG(4,("LSA Close\n"));
 
        /* store the parameters */
-       make_lsa_q_close(&q_c, hnd);
+       init_lsa_q_close(&q_c, hnd);
 
        /* turn parameters into data stream */
-       lsa_io_q_close("", &q_c, &buf, 0);
+       if(!lsa_io_q_close("", &q_c, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, LSA_CLOSE, &buf, &rbuf))
-       {
-               LSA_R_CLOSE r_c;
-               BOOL p;
-
-               lsa_io_r_close("", &r_c, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_c.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
-                       p = False;
-               }
+       if (!rpc_api_pipe_req(cli, LSA_CLOSE, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       prs_mem_free(&buf);
+
+       if(!lsa_io_r_close("", &r_c, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       if (r_c.status != 0) {
+               /* report error code */
+               DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       /* check that the returned policy handle is all zeros */
-                       uint32 i;
-                       valid_close = True;
-
-                       for (i = 0; i < sizeof(r_c.pol.data); i++)
-                       {
-                               if (r_c.pol.data[i] != 0)
-                               {
-                                       valid_close = False;
-                                       break;
-                               }
-                       }       
-                       if (!valid_close)
-                       {
-                               DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
-                       }
+       /* check that the returned policy handle is all zeros */
+
+       for (i = 0; i < sizeof(r_c.pol.data); i++) {
+               if (r_c.pol.data[i] != 0) {
+                       DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
+                       prs_mem_free(&rbuf);
+                       return False;
                }
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       close_policy_hnd(hnd);
-
-       return valid_close;
+       return True;
 }
-
index 147578f4484302af3d63ca9b15af121f7bb491f4..8202960089354403df06142408017691d255b84a 100644 (file)
 #include "includes.h"
 
 extern int DEBUGLEVEL;
+extern pstring scope;
+extern pstring global_myname;
+extern fstring global_myworkgroup;
 
 /****************************************************************************
 Generate the next creds to use.
 ****************************************************************************/
 
-void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
+static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
 {
   /*
    * Create the new client credentials.
@@ -51,58 +54,61 @@ void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
 
 }
 
+#if UNUSED_CODE
 /****************************************************************************
 do a LSA Logon Control2
 ****************************************************************************/
-BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level)
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
 {
-       prs_struct rbuf;
-       prs_struct buf; 
-       NET_Q_LOGON_CTRL2 q_l;
-       BOOL ok = False;
-
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_struct rbuf;
+  prs_struct buf; 
+  NET_Q_LOGON_CTRL2 q_l;
+  BOOL ok = False;
 
-       /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
-       DEBUG(4,("net_logon_ctrl2 status level:%x\n", status_level));
+  /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
 
-       /* store the parameters */
-       make_q_logon_ctrl2(&q_l, srv_name, 0, 0, status_level);
+  DEBUG(4,("do_net_logon_ctrl2 from %s status level:%x\n",
+           global_myname, status_level));
 
-       /* turn parameters into data stream */
-       net_io_q_logon_ctrl2("", &q_l,  &buf, 0);
+  /* store the parameters */
+  init_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level);
 
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, NET_LOGON_CTRL2, &buf, &rbuf))
-       {
-               NET_R_LOGON_CTRL2 r_l;
+  /* turn parameters into data stream */
+  if(!net_io_q_logon_ctrl2("", &q_l,  &buf, 0)) {
+    DEBUG(0,("cli_net_logon_ctrl2: Error : failed to marshall NET_Q_LOGON_CTRL2 struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
-               net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
-               ok = (rbuf.offset != 0);
+  /* send the data on \PIPE\ */
+  if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf))
+  {
+    NET_R_LOGON_CTRL2 r_l;
 
-               if (ok && r_l.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(5,("net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status)));
-                       ok = False;
-               }
-       }
+    /*
+     * Unmarshall the return buffer.
+     */
+    ok = net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
+               
+    if (ok && r_l.status != 0)
+    {
+      /* report error code */
+      DEBUG(0,("do_net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status)));
+      cli->nt_error = r_l.status;
+      ok = False;
+    }
+  }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
+  prs_mem_free(&buf);
+  prs_mem_free(&rbuf);
 
-       cli_connection_unlink(con);
-       return ok;
+  return ok;
 }
+#endif
 
 /****************************************************************************
 LSA Authenticate 2
@@ -112,114 +118,90 @@ Ensure that the server credential returned matches the session key
 encrypt of the server challenge originally received. JRA.
 ****************************************************************************/
 
-uint32 cli_net_auth2(const char *srv_name,
-                               const char *trust_acct, 
-                               const char *acct_name, 
-                               uint16 sec_chan, 
-                               uint32 neg_flags, DOM_CHAL *srv_chal)
+BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, 
+                   uint32 neg_flags, DOM_CHAL *srv_chal)
 {
-       prs_struct rbuf;
-       prs_struct buf; 
-       NET_Q_AUTH_2 q_a;
-       uint32 status = 0x0;
-       uint8 sess_key[16];
-       DOM_CRED clnt_cred;
-
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
-
-       if (!cli_get_con_sesskey(con, sess_key))
-       {
-               return False;
-       }
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api NET_AUTH2 */
-
-       DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
-                 srv_name, trust_acct, sec_chan, acct_name,
-                 neg_flags));
-
-       cli_con_get_cli_cred(con, &clnt_cred);
-
-       /* store the parameters */
-       make_q_auth_2(&q_a, srv_name, trust_acct, sec_chan, acct_name,
-                     &clnt_cred.challenge, neg_flags);
-
-       /* turn parameters into data stream */
-       net_io_q_auth_2("", &q_a,  &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, NET_AUTH2, &buf, &rbuf))
-       {
-               NET_R_AUTH_2 r_a;
-
-               net_io_r_auth_2("", &r_a, &rbuf, 0);
-               status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0;
-
-               if (status == 0x0 && r_a.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(5,("cli_net_auth2: Error %s\n",
-                                 get_nt_error_msg(r_a.status)));
-                       status = r_a.status;
-               }
-
-               if (status == 0x0)
-               {
-                       /*
-                        * Check the returned value using the initial
-                        * server received challenge.
-                        */
-                       UTIME zerotime;
-
-                       zerotime.time = 0;
-                       if(cred_assert( &r_a.srv_chal, sess_key,
-                                       srv_chal, zerotime) == 0)
-                       {
-                               /*
-                                * Server replied with bad credential. Fail.
-                                */
-                               DEBUG(5,("cli_net_auth2: server %s replied \
-with bad credential (bad trust account password ?).\n", srv_name));
-                               status = NT_STATUS_NETWORK_CREDENTIAL_CONFLICT | 0xC0000000;
-                       }
-               }
+  prs_struct rbuf;
+  prs_struct buf; 
+  NET_Q_AUTH_2 q_a;
+  BOOL ok = False;
+
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
+
+  /* create and send a MSRPC command with api NET_AUTH2 */
+
+  DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
+         cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
+         credstr(cli->clnt_cred.challenge.data), neg_flags));
+
+  /* store the parameters */
+  init_q_auth_2(&q_a, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
+                &cli->clnt_cred.challenge, neg_flags);
+
+  /* turn parameters into data stream */
+  if(!net_io_q_auth_2("", &q_a,  &buf, 0)) {
+    DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
+
+  /* send the data on \PIPE\ */
+  if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf))
+  {
+    NET_R_AUTH_2 r_a;
+
+    ok = net_io_r_auth_2("", &r_a, &rbuf, 0);
+               
+    if (ok && r_a.status != 0)
+    {
+      /* report error code */
+      DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(r_a.status)));
+      cli->nt_error = r_a.status;
+      ok = False;
+    }
+
+    if (ok)
+    {
+      /* 
+       * Check the returned value using the initial
+       * server received challenge.
+       */
+      UTIME zerotime;
+
+      zerotime.time = 0;
+      if(cred_assert( &r_a.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
+        /*
+         * Server replied with bad credential. Fail.
+         */
+        DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+        ok = False;
+      }
+    }
 
 #if 0
-               /*
-                * Try commenting this out to see if this makes the connect
-                * work for a NT 3.51 PDC. JRA.
-                */
-
-               if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
-               {
-                       /* report different neg_flags */
-                       DEBUG(5,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n",
-                       q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
-                       ok = False;
-               }
-#endif
+    /*
+     * Try commenting this out to see if this makes the connect
+     * work for a NT 3.51 PDC. JRA.
+     */
 
-       }
-       else
-       {
-               DEBUG(5,("rpc_con_pipe_req FAILED\n"));
-               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-       }
+    if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
+    {
+      /* report different neg_flags */
+      DEBUG(0,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n",
+          q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
+      ok = False;
+    }
+#endif
 
-       DEBUG(5,("cli_net_auth2 status: %x\n", status));
+  }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
+  prs_mem_free(&buf);
+  prs_mem_free(&rbuf);
 
-       return status;
+  return ok;
 }
 
 /****************************************************************************
@@ -227,152 +209,127 @@ LSA Request Challenge. Sends our challenge to server, then gets
 server response. These are used to generate the credentials.
 ****************************************************************************/
 
-uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
-                               DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
 {
   prs_struct rbuf;
   prs_struct buf; 
   NET_Q_REQ_CHAL q_c;
-    uint32 status = 0x0;
-
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
-
-  if (srv_chal == NULL || clnt_chal == NULL)
-    return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+  BOOL valid_chal = False;
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_REQCHAL */
 
   DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
-         srv_name, myhostname, credstr(clnt_chal->data)));
+         cli->desthost, global_myname, credstr(clnt_chal->data)));
 
   /* store the parameters */
-  make_q_req_chal(&q_c, srv_name, myhostname, clnt_chal);
+  init_q_req_chal(&q_c, cli->srv_name_slash, global_myname, clnt_chal);
 
   /* turn parameters into data stream */
-  net_io_q_req_chal("", &q_c,  &buf, 0);
+  if(!net_io_q_req_chal("", &q_c,  &buf, 0)) {
+    DEBUG(0,("cli_net_req_chal: Error : failed to marshall NET_Q_REQ_CHAL struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
-  if (rpc_con_pipe_req(con, NET_REQCHAL, &buf, &rbuf))
+  if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf))
   {
     NET_R_REQ_CHAL r_c;
+    BOOL ok;
 
-    net_io_r_req_chal("", &r_c, &rbuf, 0);
-    status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0;
+    ok = net_io_r_req_chal("", &r_c, &rbuf, 0);
                
-    if (status == 0x0 && r_c.status != 0)
+    if (ok && r_c.status != 0)
     {
       /* report error code */
-      DEBUG(5,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
-       status = r_c.status;
+      DEBUG(0,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
+      cli->nt_error = r_c.status;
+      ok = False;
     }
 
-    if (status == 0x0)
+    if (ok)
     {
       /* ok, at last: we're happy. return the challenge */
       memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
+      valid_chal = True;
     }
   }
-  else
-  {
-    DEBUG(5,("rpc_con_pipe_req FAILED\n"));
-    status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-  }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
-  return status;
+  return valid_chal;
 }
 
 /***************************************************************************
 LSA Server Password Set.
 ****************************************************************************/
 
-BOOL cli_net_srv_pwset(const char* srv_name,
-                               const char* myhostname,
-                               const char* trust_acct,
-                               uint8 hashed_trust_pwd[16],
-                               uint16 sec_chan_type)
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
 {
   prs_struct rbuf;
   prs_struct buf; 
   DOM_CRED new_clnt_cred;
   NET_Q_SRV_PWSET q_s;
   BOOL ok = False;
-  unsigned char processed_new_pwd[16];
-  /* Process the new password. */
-
-       uint8 sess_key[16];
-       
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
-
-       if (!cli_get_con_sesskey(con, sess_key))
-       {
-               return False;
-       }
-
-       cred_hash3( processed_new_pwd, hashed_trust_pwd, sess_key, 1);
+  uint16 sec_chan_type = 2;
 
-  cli_con_gen_next_creds( con, &new_clnt_cred);
+  gen_next_creds( cli, &new_clnt_cred);
 
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SRV_PWSET */
 
   DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
-           srv_name, trust_acct, sec_chan_type, myhostname,
+           cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
            credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
 
   /* store the parameters */
-  make_q_srv_pwset(&q_s, srv_name, trust_acct, sec_chan_type,
-                   myhostname, &new_clnt_cred, (char *)processed_new_pwd);
+  init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
+                   global_myname, &new_clnt_cred, (char *)hashed_mach_pwd);
 
   /* turn parameters into data stream */
-  net_io_q_srv_pwset("", &q_s,  &buf, 0);
+  if(!net_io_q_srv_pwset("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
-  if (rpc_con_pipe_req(con, NET_SRVPWSET, &buf, &rbuf))
+  if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
   {
     NET_R_SRV_PWSET r_s;
 
-    net_io_r_srv_pwset("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
       /* report error code */
-      DEBUG(5,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
+      DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
+      cli->nt_error = r_s.status;
       ok = False;
     }
 
     /* Update the credentials. */
-    if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_cred)))
+    if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
     {
       /*
        * Server replied with bad credential. Fail.
        */
-      DEBUG(5,("cli_net_srv_pwset: server %s replied with bad credential \
-(bad trust account password ?).\n", srv_name));
+      DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
       ok = False;
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
@@ -381,9 +338,8 @@ BOOL cli_net_srv_pwset(const char* srv_name,
 LSA SAM Logon - interactive or network.
 ****************************************************************************/
 
-BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr, 
-                               NET_USER_INFO_3 *user_info3)
+BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, 
+                       NET_USER_INFO_3 *user_info3)
 {
   DOM_CRED new_clnt_cred;
   DOM_CRED dummy_rtn_creds;
@@ -393,75 +349,73 @@ BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname,
   NET_Q_SAM_LOGON q_s;
   BOOL ok = False;
 
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
+  gen_next_creds( cli, &new_clnt_cred);
 
-  cli_con_gen_next_creds( con, &new_clnt_cred);
-
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SAMLOGON */
 
-  DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s ll: %d\n",
-             srv_name, myhostname, 
+  DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s clnt %s %x ll: %d\n",
+             cli->srv_name_slash, global_myname, 
+             credstr(new_clnt_cred.challenge.data), cli->clnt_cred.timestamp.time,
              ctr->switch_value));
 
   memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
        dummy_rtn_creds.timestamp.time = time(NULL);
 
   /* store the parameters */
-  make_sam_info(&(q_s.sam_id), srv_name, myhostname,
+  q_s.validation_level = validation_level;
+  init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
          &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
 
-       q_s.validation_level = validation_level;
-
   /* turn parameters into data stream */
-  net_io_q_sam_logon("", &q_s,  &buf, 0);
+  if(!net_io_q_sam_logon("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_sam_logon: Error : failed to marshall NET_Q_SAM_LOGON struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
-  if (rpc_con_pipe_req(con, NET_SAMLOGON, &buf, &rbuf))
+  if (rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf))
   {
     NET_R_SAM_LOGON r_s;
 
     r_s.user = user_info3;
 
-    net_io_r_sam_logon("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_sam_logon("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
       /* report error code */
-      DEBUG(5,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status)));
+      DEBUG(0,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status)));
+      cli->nt_error = r_s.status;
       ok = False;
     }
 
     /* Update the credentials. */
-    if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
+    if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
     {
       /*
        * Server replied with bad credential. Fail.
        */
-      DEBUG(5,("cli_net_sam_logon: server %s replied with bad credential \
-(bad trust account password ?).\n", srv_name));
+      DEBUG(0,("cli_net_sam_logon: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
         ok = False;
     }
 
     if (ok && r_s.switch_value != 3)
     {
       /* report different switch_value */
-      DEBUG(5,("cli_net_sam_logon: switch_value of 3 expected %x\n",
+      DEBUG(0,("cli_net_sam_logon: switch_value of 3 expected %x\n",
                    r_s.switch_value));
       ok = False;
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
@@ -475,8 +429,7 @@ send a different info level. Right now though, I'm not sure
 what that needs to be (I need to see one on the wire before
 I can be sure). JRA.
 ****************************************************************************/
-BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
-                               NET_ID_INFO_CTR *ctr)
+BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
 {
   DOM_CRED new_clnt_cred;
   DOM_CRED dummy_rtn_creds;
@@ -485,147 +438,266 @@ BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
   NET_Q_SAM_LOGOFF q_s;
   BOOL ok = False;
 
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
+  gen_next_creds( cli, &new_clnt_cred);
 
-  cli_con_gen_next_creds( con, &new_clnt_cred);
-
-  prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-  prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
+  prs_init(&buf , 1024, 4, False);
+  prs_init(&rbuf, 0,    4, True );
 
   /* create and send a MSRPC command with api NET_SAMLOGOFF */
 
   DEBUG(4,("cli_net_sam_logoff: srv:%s mc:%s clnt %s %x ll: %d\n",
-            srv_name, myhostname,
+            cli->srv_name_slash, global_myname,
             credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time,
             ctr->switch_value));
 
   memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
 
-  /* store the parameters */
-  make_sam_info(&(q_s.sam_id), srv_name, myhostname,
+  init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
                 &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
 
   /* turn parameters into data stream */
-  net_io_q_sam_logoff("", &q_s,  &buf, 0);
+  if(!net_io_q_sam_logoff("", &q_s,  &buf, 0)) {
+    DEBUG(0,("cli_net_sam_logoff: Error : failed to marshall NET_Q_SAM_LOGOFF struct.\n"));
+    prs_mem_free(&buf);
+    prs_mem_free(&rbuf);
+    return False;
+  }
 
   /* send the data on \PIPE\ */
-  if (rpc_con_pipe_req(con, NET_SAMLOGOFF, &buf, &rbuf))
+  if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
   {
     NET_R_SAM_LOGOFF r_s;
 
-    net_io_r_sam_logoff("", &r_s, &rbuf, 0);
-    ok = (rbuf.offset != 0);
+    ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0);
                
     if (ok && r_s.status != 0)
     {
       /* report error code */
-      DEBUG(5,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
+      DEBUG(0,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
+      cli->nt_error = r_s.status;
       ok = False;
     }
 
     /* Update the credentials. */
-    if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
+    if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
     {
       /*
        * Server replied with bad credential. Fail.
        */
-      DEBUG(5,("cli_net_sam_logoff: server %s replied with bad credential \
-(bad trust account password ?).\n", srv_name ));
+      DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
       ok = False;
     }
   }
 
+  prs_mem_free(&buf);
   prs_mem_free(&rbuf);
-  prs_mem_free(&buf );
 
   return ok;
 }
 
-/***************************************************************************
-Synchronise SAM Database (requires SEC_CHAN_BDC).
-****************************************************************************/
-BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
-                               uint32 database_id,
-                               uint32 *num_deltas,
-                               SAM_DELTA_HDR *hdr_deltas,
-                               SAM_DELTA_CTR *deltas)
+/*********************************************************
+ Change the domain password on the PDC.
+**********************************************************/
+
+static BOOL modify_trust_password( char *domain, char *remote_machine, 
+                          unsigned char orig_trust_passwd_hash[16],
+                          unsigned char new_trust_passwd_hash[16])
 {
-       NET_Q_SAM_SYNC q_s;
-       prs_struct rbuf;
-       prs_struct buf; 
-       DOM_CRED new_clnt_cred;
-       BOOL ok = False;
-       uint8 sess_key[16];
-       
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
-       {
-               return False;
-       }
-
-       if (!cli_get_con_sesskey(con, sess_key))
-       {
-               return False;
-       }
-
-       cli_con_gen_next_creds(con, &new_clnt_cred);
-       
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
-       
-       /* create and send a MSRPC command with api NET_SAM_SYNC */
-       
-       make_q_sam_sync(&q_s, srv_name, myhostname,
-                       &new_clnt_cred, database_id);
-       
-       /* turn parameters into data stream */
-       net_io_q_sam_sync("", &q_s,  &buf, 0);
-       
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, NET_SAM_SYNC, &buf, &rbuf))
-       {
-               NET_R_SAM_SYNC r_s;
-
-               r_s.hdr_deltas = hdr_deltas;
-               r_s.deltas = deltas;
-
-               net_io_r_sam_sync("", sess_key, &r_s, &rbuf, 0);
-               ok = (rbuf.offset != 0);
-
-               if (ok && r_s.status != 0 && r_s.status != STATUS_MORE_ENTRIES)
-               {
-                       /* report error code */
-                       DEBUG(5,("cli_net_sam_sync: %s\n", get_nt_error_msg(r_s.status)));
-                       ok = False;
-               }
-               
-               /* Update the credentials. */
-               if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
-               {
-                       DEBUG(5,("cli_net_sam_sync: server %s replied with bad \
-credential (bad trust account password ?).\n", srv_name));
-                       ok = False;
-               }
-
-               if (ok)
-               {
-                       *num_deltas = r_s.num_deltas2;
-
-                       if (r_s.status == STATUS_MORE_ENTRIES)
-                       {
-                               DEBUG(5, ("(More entries)\n"));
-                       }
-               }
-       }
-       
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-       
-       return ok;
+  struct cli_state cli;
+
+  ZERO_STRUCT(cli);
+  if(cli_initialise(&cli) == False) {
+    DEBUG(0,("modify_trust_password: unable to initialize client connection.\n"));
+    return False;
+  }
+
+  if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
+    DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
+    return False;
+  }
+
+  if (ismyip(cli.dest_ip)) {
+    DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
+to ourselves.\n", remote_machine));
+    return False;
+  }
+
+  if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
+    DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+    return False;
+  }
+  
+  if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
+    DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \
+session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
+    return False;
+  }
+
+  cli.protocol = PROTOCOL_NT1;
+    
+  if (!cli_negprot(&cli)) {
+    DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  if (cli.protocol != PROTOCOL_NT1) {
+    DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n", 
+            remote_machine));
+    cli_shutdown(&cli);
+    return False;
+  }
+    
+  /*
+   * Do an anonymous session setup.
+   */
+    
+  if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+    DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+    cli_shutdown(&cli);
+    return False;
+  }
+    
+  if (!(cli.sec_mode & 1)) {
+    DEBUG(0,("modify_trust_password: machine %s isn't in user level security mode\n",
+          remote_machine));
+    cli_shutdown(&cli);
+    return False;
+  }
+    
+  if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+    DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  /*
+   * Ok - we have an anonymous connection to the IPC$ share.
+   * Now start the NT Domain stuff :-).
+   */
+    
+  if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
+    DEBUG(0,("modify_trust_password: unable to open the domain client session to \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+    cli_nt_session_close(&cli);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  } 
+  
+  if(cli_nt_setup_creds(&cli, orig_trust_passwd_hash) == False) {
+    DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
+%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+    cli_nt_session_close(&cli);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  } 
+
+  if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) {
+    DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
+%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine, 
+                            cli_errstr(&cli)));
+    cli_close(&cli, cli.nt_pipe_fnum);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  cli_nt_session_close(&cli);
+  cli_ulogoff(&cli);
+  cli_shutdown(&cli);
+
+  return True;
+}
+
+/************************************************************************
+ Change the trust account password for a domain.
+ The user of this function must have locked the trust password file for
+ update.
+************************************************************************/
+
+BOOL change_trust_account_password( char *domain, char *remote_machine_list)
+{
+  fstring remote_machine;
+  unsigned char old_trust_passwd_hash[16];
+  unsigned char new_trust_passwd_hash[16];
+  time_t lct;
+  BOOL res;
+
+  if(!get_trust_account_password( old_trust_passwd_hash, &lct)) {
+    DEBUG(0,("change_trust_account_password: unable to read the machine \
+account password for domain %s.\n", domain));
+    return False;
+  }
+
+  /*
+   * Create the new (random) password.
+   */
+  generate_random_buffer( new_trust_passwd_hash, 16, True);
+
+  while(remote_machine_list && 
+       next_token(&remote_machine_list, remote_machine, 
+                  LIST_SEP, sizeof(remote_machine))) {
+    strupper(remote_machine);
+    if(strequal(remote_machine, "*")) {
+
+      /*
+       * We have been asked to dynamcially determine the IP addresses of the PDC.
+       */
+
+      struct in_addr *ip_list = NULL;
+      int count = 0;
+      int i;
+
+      if(!get_dc_list(domain, &ip_list, &count))
+        continue;
+
+      /*
+       * Try and connect to the PDC/BDC list in turn as an IP
+       * address used as a string.
+       */
+
+      for(i = 0; i < count; i++) {
+        fstring dc_name;
+        if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name))
+          continue;
+        if((res = modify_trust_password( domain, dc_name,
+                                         old_trust_passwd_hash, new_trust_passwd_hash)))
+          break;
+      }
+
+      if(ip_list != NULL)
+        free((char *)ip_list);
+
+    } else {
+      res = modify_trust_password( domain, remote_machine,
+                                   old_trust_passwd_hash, new_trust_passwd_hash);
+    }
+
+    if(res) {
+      DEBUG(0,("%s : change_trust_account_password: Changed password for \
+domain %s.\n", timestring(False), domain));
+      /*
+       * Return the result of trying to write the new password
+       * back into the trust account file.
+       */
+      res = set_trust_account_password(new_trust_passwd_hash);
+      memset(new_trust_passwd_hash, 0, 16);
+      memset(old_trust_passwd_hash, 0, 16);
+      return res;
+    }
+  }
+
+  memset(new_trust_passwd_hash, 0, 16);
+  memset(old_trust_passwd_hash, 0, 16);
+
+  DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
+domain %s.\n", timestring(False), domain));
+  return False;
 }
index a8debd87fdb1166bdd65f98ef3c068826427ca70..8711ab116eef31f148d4c213e43f8320878a0007 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1998,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  Copyright (C) Paul Ashton                       1998.
+ *  Copyright (C) Jeremy Allison                    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
 
 extern int DEBUGLEVEL;
 extern struct pipe_id_info pipe_names[];
+extern fstring global_myworkgroup;
 extern pstring global_myname;
 
 /********************************************************************
- rpc pipe call id 
+ Rpc pipe call id.
  ********************************************************************/
+
 static uint32 get_rpc_call_id(void)
 {
-  static uint32 call_id = 0;
-  return ++call_id;
+       static uint32 call_id = 0;
+       return ++call_id;
 }
 
 /*******************************************************************
- uses SMBreadX to get rest of rpc data
+ Use SMBreadX to get rest of one fragment's worth of rpc data.
  ********************************************************************/
 
-static BOOL rpc_read(struct cli_state *cli, uint16 fnum,
-                     prs_struct *rdata, uint32 data_to_read,
-                     uint32 rdata_offset, BOOL one_only)
+static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset)
 {
-       size_t size = cli->max_recv_frag;
-       int file_offset = 0;
+       size_t size = (size_t)cli->max_recv_frag;
+       int stream_offset = 0;
        int num_read;
-       char *data;
-       uint32 new_data_size = rdata_offset + data_to_read;
-       uint8 cls;
-       uint32 type;
+       char *pdata;
+       uint32 err;
+       int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata);
 
-       DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
-       data_to_read, rdata_offset, file_offset));
+       DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n",
+               (int)data_to_read, (unsigned int)*rdata_offset, extra_data_size));
 
-       if (new_data_size > rdata->data->data_size)
-       {
-               mem_grow_data(&rdata->data, True, new_data_size, True);
-               DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
+       /*
+        * Grow the buffer if needed to accommodate the data to be read.
+        */
+
+       if (extra_data_size > 0) {
+               if(!prs_force_grow(rdata, (uint32)extra_data_size)) {
+                       DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", extra_data_size ));
+                       return False;
+               }
+               DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) ));
        }
 
-       data = rdata->data->data + rdata_offset;
+       pdata = prs_data_p(rdata) + *rdata_offset;
 
        do /* read data using SMBreadX */
        {
-               if (size > data_to_read)
-               {
-                       size = data_to_read;
-               }
+               if (size > (size_t)data_to_read)
+                       size = (size_t)data_to_read;
 
-               num_read = cli_read(cli, fnum, data, file_offset, size);
+               num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size);
 
-               DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
-                         file_offset, num_read, data_to_read));
+               DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
+                         num_read, stream_offset, data_to_read));
 
-               data_to_read -= num_read;
-               file_offset  += num_read;
-               data         += num_read;
-
-               if (cli_error(cli, &cls, &type))
-               {
-                       if (cls != ERRDOS || type != ERRmoredata)
-                       {
-                               return False;
-                       }
+               if (cli_error(cli, NULL, &err, NULL)) {
+                       DEBUG(0,("rpc_read: Error %u in cli_read\n", (unsigned int)err ));
+                       return False;
                }
 
-       } while (!one_only && num_read > 0 && data_to_read > 0);
+               data_to_read -= num_read;
+               stream_offset += num_read;
+               pdata += num_read;
 
-       rdata->data->offset.end = new_data_size;
+       } while (num_read > 0 && data_to_read > 0);
+       /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
 
-       DEBUG(5,("rpc_read: offset end: 0x%x.  data left to read:0x%x\n",
-                 rdata->data->offset.end, data_to_read));
+       /*
+        * Update the current offset into rdata by the amount read.
+        */
+       *rdata_offset += stream_offset;
 
        return True;
 }
 
 /****************************************************************************
- checks the header
+ Checks the header.
  ****************************************************************************/
+
 static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, 
-                          BOOL *first, BOOL *last, int *len)
+                          BOOL *first, BOOL *last, uint32 *len)
 {
-       DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
+       DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) ));
 
-       smb_io_rpc_hdr   ("rpc_hdr   ", rhdr   , rdata, 0);
-
-       if (!rdata->offset || rdata->offset != 0x10)
-       {
-               DEBUG(0,("cli_pipe: error in rpc header\n"));
+       if(!smb_io_rpc_hdr("rpc_hdr   ", rhdr, rdata, 0)) {
+               DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n"));
                return False;
        }
 
-       DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
-                 rdata->data->data_used));
+       if (prs_offset(rdata) != RPC_HEADER_LEN) {
+               DEBUG(0,("rpc_check_hdr: offset was %x, should be %x.\n", prs_offset(rdata), RPC_HEADER_LEN));
+               return False;
+       }
 
-       (*first   ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
-       (*last    ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
-       (*len     ) = rhdr->frag_len - rdata->data->data_used;
+       (*first) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
+       (*last) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
+       (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata);
 
-       return rhdr->pkt_type != RPC_FAULT;
+       return (rhdr->pkt_type != RPC_FAULT);
 }
 
-static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len)
+static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 len)
 {
        unsigned char *hash = cli->ntlmssp_hash;
-    unsigned char index_i = hash[256];
-    unsigned char index_j = hash[257];
-    int ind;
+       unsigned char index_i = hash[256];
+       unsigned char index_j = hash[257];
+       int ind;
 
-    for( ind = 0; ind < len; ind++)
-    {
-        unsigned char tc;
-        unsigned char t;
+       for( ind = 0; ind < len; ind++) {
+               unsigned char tc;
+               unsigned char t;
 
-        index_i++;
-        index_j += hash[index_i];
+               index_i++;
+               index_j += hash[index_i];
 
-        tc = hash[index_i];
-        hash[index_i] = hash[index_j];
-        hash[index_j] = tc;
+               tc = hash[index_i];
+               hash[index_i] = hash[index_j];
+               hash[index_j] = tc;
 
-        t = hash[index_i] + hash[index_j];
-        data[ind] = data[ind] ^ hash[t];
-    }
+               t = hash[index_i] + hash[index_j];
+               data[ind] = data[ind] ^ hash[t];
+       }
 
-    hash[256] = index_i;
-    hash[257] = index_j;
+       hash[256] = index_i;
+       hash[257] = index_j;
 }
 
 /****************************************************************************
- decrypt data on an rpc pipe
+ Verify data on an rpc pipe.
+ The VERIFY & SEAL code is only executed on packets that look like this :
+
+ Request/Response PDU's look like the following...
+
+ |<------------------PDU len----------------------------------------------->|
+ |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
+
+ +------------+-----------------+-------------+---------------+-------------+
+ | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
+ +------------+-----------------+-------------+---------------+-------------+
+
+ Never on bind requests/responses.
  ****************************************************************************/
 
-static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
-                               int len, int auth_len)
+static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len)
 {
-       RPC_AUTH_NTLMSSP_CHK chk;
-       uint32 crc32;
-       int data_len = len - 0x18 - auth_len - 8;
-       char *reply_data = mem_data(&rdata->data, 0x18);
+       /*
+        * The following is that length of the data we must sign or seal.
+        * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
+        * preceeding the auth_data.
+        */
+
+       int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
+
+       /*
+        * The start of the data to sign/seal is just after the RPC headers.
+        */
+       char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
 
        BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
-       BOOL auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
+       BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
 
        DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
                  len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
 
-       if (reply_data == NULL) return False;
+       /*
+        * Unseal any sealed data in the PDU, not including the
+        * 8 byte auth_header or the auth_data.
+        */
 
-       if (auth_seal)
-       {
-               DEBUG(10,("rpc_auth_pipe: seal\n"));
+       if (auth_seal) {
+               DEBUG(10,("rpc_auth_pipe: unseal\n"));
                dump_data(100, reply_data, data_len);
                NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
                dump_data(100, reply_data, data_len);
        }
 
-       if (auth_verify || auth_seal)
-       {
-               RPC_HDR_AUTH         rhdr_auth; 
+       if (auth_verify || auth_seal) {
+               RPC_HDR_AUTH rhdr_auth; 
                prs_struct auth_req;
-               char *data = mem_data(&rdata->data, len - auth_len - 8);
-               prs_init(&auth_req , 0x08, 4, 0, True);
-               memcpy(auth_req.data->data, data, 8);
-               smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
-               prs_mem_free(&auth_req);
-
-               if (!rpc_hdr_auth_chk(&rhdr_auth))
-               {
+               char data[RPC_HDR_AUTH_LEN];
+               /*
+                * We set dp to be the end of the packet, minus the auth_len
+                * and the length of the header that preceeds the auth_data.
+                */
+               char *dp = prs_data_p(rdata) + len - auth_len - RPC_HDR_AUTH_LEN;
+
+               if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+                       DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
+                       return False;
+               }
+
+               memcpy(data, dp, sizeof(data));
+               
+               prs_init(&auth_req , 0, 4, UNMARSHALL);
+               prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False);
+
+               /*
+                * Unmarshall the 8 byte auth_header that comes before the
+                * auth data.
+                */
+
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0)) {
+                       DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_HDR_AUTH failed.\n"));
+                       return False;
+               }
+
+               if (!rpc_hdr_auth_chk(&rhdr_auth)) {
+                       DEBUG(0,("rpc_auth_pipe: rpc_hdr_auth_chk failed.\n"));
                        return False;
                }
        }
 
-       if (auth_verify)
-       {
+       /*
+        * Now unseal and check the auth verifier in the auth_data at
+        * then end of the packet. The 4 bytes skipped in the unseal
+        * seem to be a buffer pointer preceeding the sealed data.
+        */
+
+       if (auth_verify) {
+               RPC_AUTH_NTLMSSP_CHK chk;
+               uint32 crc32;
                prs_struct auth_verf;
-               char *data = mem_data(&rdata->data, len - auth_len);
-               if (data == NULL) return False;
+               char data[RPC_AUTH_NTLMSSP_CHK_LEN];
+               char *dp = prs_data_p(rdata) + len - auth_len;
+
+               if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+                       DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
+                       return False;
+               }
 
                DEBUG(10,("rpc_auth_pipe: verify\n"));
+               dump_data(100, dp, auth_len);
+               NTLMSSPcalc_ap(cli, (uchar*)(dp+4), auth_len - 4);
+
+               memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN);
                dump_data(100, data, auth_len);
-               NTLMSSPcalc_ap(cli, (uchar*)(data+4), auth_len - 4);
-               prs_init(&auth_verf, 0x08, 4, 0, True);
-               memcpy(auth_verf.data->data, data, 16);
-               smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
-               dump_data(100, data, auth_len);
-               prs_mem_free(&auth_verf);
-       }
 
-       if (auth_verify)
-       {
-               crc32 = crc32_calc_buffer(data_len, reply_data);
-               if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num))
-               {
+               prs_init(&auth_verf, 0, 4, UNMARSHALL);
+               prs_give_memory(&auth_verf, data, RPC_AUTH_NTLMSSP_CHK_LEN, False);
+
+               if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0)) {
+                       DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_AUTH_NTLMSSP_CHK failed.\n"));
+                       return False;
+               }
+
+               crc32 = crc32_calc_buffer(reply_data, data_len);
+
+               if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) {
+                       DEBUG(0,("rpc_auth_pipe: rpc_auth_ntlmssp_chk failed.\n"));
                        return False;
                }
                cli->ntlmssp_seq_num++;
@@ -230,204 +288,215 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
 
 
 /****************************************************************************
send data on an rpc pipe, which *must* be in one fragment.
Send data on an rpc pipe, which *must* be in one fragment.
  receive response data from an rpc pipe, which may be large...
 
read the first fragment: unfortunately have to use SMBtrans for the first
Read the first fragment: unfortunately have to use SMBtrans for the first
  bit, then SMBreadX for subsequent bits.
 
if first fragment received also wasn't the last fragment, continue
If first fragment received also wasn't the last fragment, continue
  getting fragments until we _do_ receive the last fragment.
 
- [note: from a data abstraction viewpoint, this function is marginally
-        complicated by the return side of cli_api_pipe getting in the way
-        (i.e, the SMB header stuff).  the proper way to do this is to split
-        cli_api_pipe down into receive / transmit.  oh, and split cli_readx
-        down.  in other words, state-based (kernel) techniques...]
+ Request/Response PDU's look like the following...
+
+ |<------------------PDU len----------------------------------------------->|
+ |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
+
+ +------------+-----------------+-------------+---------------+-------------+
+ | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
+ +------------+-----------------+-------------+---------------+-------------+
+
+ Where the presence of the AUTH_HDR and AUTH are dependent on the
+ signing & sealing being neogitated.
 
  ****************************************************************************/
 
-static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum,
-                       BOOL bind_rq, uint16 cmd, 
-                       prs_struct *param , prs_struct *data,
-                       prs_struct *rparam, prs_struct *rdata)
+static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, prs_struct *rdata)
 {
-       int len;
-
-       uint16 setup[2]; /* only need 2 uint16 setup parameters */
-       uint8 cls;
-       uint32 type;
+       uint32 len;
+       char *rparam = NULL;
+       uint32 rparam_len = 0;
+       uint16 setup[2];
+       uint32 err;
        BOOL first = True;
        BOOL last  = True;
-       BOOL used_smb_trans = False;
-       RPC_HDR    rhdr;
+       RPC_HDR rhdr;
+       char *pdata = data ? prs_data_p(data) : NULL;
+       uint32 data_len = data ? prs_offset(data) : 0;
+       char *prdata = NULL;
+       uint32 rdata_len = 0;
+       uint32 current_offset = 0;
 
-       /*
-       * Setup the pointers from the incoming.
-       */
-       char *pparams = param ? param->data->data : NULL;
-       int params_len = param ? param->data->data_used : 0;
-       char *pdata = data ? data->data->data : NULL;
-       int data_len = data ? data->data->data_used : 0;
-
-       /*
-       * Setup the pointers to the outgoing.
-       */
-       char **pp_ret_params = rparam ? &rparam->data->data : NULL;
-       uint32 *p_ret_params_len = rparam ? &rparam->data->data_used : NULL;
-
-       char **pp_ret_data = rdata ? &rdata->data->data : NULL;
-       uint32 *p_ret_data_len = rdata ? &rdata->data->data_used : NULL;
-
-       /* create setup parameters. */
+       /* 
+        * Create setup parameters - must be in native byte order.
+        */
        setup[0] = cmd; 
-       setup[1] = fnum; /* pipe file handle.  got this from an SMBOpenX. */
+       setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */
 
-       if (data_len > 2048 && !bind_rq)
-       {
-               ssize_t written;
-
-               DEBUG(5,("rpc_api_pipe: cli_write %d\n", data_len));
+       DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum));
 
-               written = cli_write(cli, fnum, 0x0008, pdata, 0, data_len);
+       /* send the data: receive a response. */
+       if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
+                 setup, 2, 0,                     /* Setup, length, max */
+                 NULL, 0, 0,                      /* Params, length, max */
+                 pdata, data_len, data_len,       /* data, length, max */                  
+                 &rparam, &rparam_len,            /* return params, len */
+                 &prdata, &rdata_len))            /* return data, len */
+       {
+               DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
+               return False;
+       }
 
-               if (written != data_len)
-                            
-               {
-                       fstring errstr;
-                       cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
-                       DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr));
-                       return False;
-               }
+       /*
+        * Throw away returned params - we know we won't use them.
+        */
 
-               DEBUG(5,("rpc_api_pipe: rpc_read after write\n"));
-       
-               first = False;
-               last = False;
+       if(rparam) {
+               free(rparam);
+               rparam = NULL;
        }
-       else
-       {
-               DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, fnum));
-               used_smb_trans = True;
-
-               /* send the data: receive a response. */
-               if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
-                         setup, 2, 0,                     /* Setup, length, max */
-                         pparams, params_len, 0,          /* Params, length, max */
-                         pdata, data_len, 2048,           /* data, length, max */                  
-                         pp_ret_params, p_ret_params_len, /* return params, len */
-                         pp_ret_data, p_ret_data_len))    /* return data, len */
-               {
-                       fstring errstr;
-                       cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
-                       DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr));
-                       return False;
-               }
 
-               if (rdata->data->data == NULL) return False;
+       if (prdata == NULL) {
+               DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n",
+                       (int)cmd, (int)cli->nt_pipe_fnum));
+               return False;
+       }
 
-               /**** parse the header: check it's a response record */
+       /*
+        * Give this memory as dynamically allocated to the return parse struct.
+        */
 
-               rdata->data->offset.start = 0;
-               rdata->data->offset.end   = rdata->data->data_used;
-               rdata->offset = 0;
+       prs_give_memory(rdata, prdata, rdata_len, True);
+       current_offset = rdata_len;
 
-               /* cli_api_pipe does an ordinary Realloc - we have no margins now. */
-               rdata->data->margin = 0;
-               if (rparam) rparam->data->margin = 0;
+       if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
+               prs_mem_free(rdata);
+               return False;
+       }
 
-               if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
-               {
-                       return False;
+       if (rhdr.pkt_type == RPC_BINDACK) {
+               if (!last && !first) {
+                       DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n"));
+                       first = True;
+                       last = True;
                }
+       }
 
-               if (rhdr.pkt_type == RPC_BINDACK)
-               {
-                       if (!last && !first)
-                       {
-                               DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n"));
-                               first = True;
-                               last = True;
-                       }
+       if (rhdr.pkt_type == RPC_RESPONSE) {
+               RPC_HDR_RESP rhdr_resp;
+               if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
+                       DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n"));
+                       prs_mem_free(rdata);
+                       return False;
                }
+       }
 
-               if (rhdr.pkt_type == RPC_RESPONSE)
-               {
-                       RPC_HDR_RESP rhdr_resp;
-                       smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
+       DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
+                 (unsigned int)len, (unsigned int)rdata_len ));
+
+       /* check if data to be sent back was too large for one SMB. */
+       /* err status is only informational: the _real_ check is on the length */
+       if (len > 0) { 
+               /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+               /*
+                * Read the rest of the first response PDU.
+                */
+               if (!rpc_read(cli, rdata, len, &current_offset)) {
+                       prs_mem_free(rdata);
+                       return False;
                }
+       }
 
-               DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
-                         len, rdata->data->data_used));
-
-               /* check if data to be sent back was too large for one SMB. */
-               /* err status is only informational: the _real_ check is on the length */
-               if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
-               {
-                       if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used, False))
-                       {
-                               return False;
-                       }
-               }
+       /*
+        * Now we have a complete PDU, check the auth struct if any was sent.
+        */
 
-               if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
-               {
+       if (rhdr.auth_len != 0) {
+               if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
                        return False;
-               }
-
-               /* only one rpc fragment, and it has been read */
-               if (first && last)
-               {
-                       DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
-                       return True;
-               }
+               /*
+                * Drop the auth footers from the current offset.
+                * We need this if there are more fragments.
+                * The auth footers consist of the auth_data and the
+                * preceeding 8 byte auth_header.
+                */
+               current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
+       }
+       
+       /* 
+        * Only one rpc fragment, and it has been read.
+        */
 
+       if (first && last) {
+               DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
+               return True;
        }
 
-       while (!last) /* read more fragments until we get the last one */
-       {
+       /*
+        * Read more fragments until we get the last one.
+        */
+
+       while (!last) {
                RPC_HDR_RESP rhdr_resp;
                int num_read;
+               char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN];
                prs_struct hps;
 
-               prs_init(&hps, 0x18, 4, 0, True);
-
-               num_read = cli_read(cli, fnum, hps.data->data, 0, 0x18);
-               DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
+               /*
+                * First read the header of the next PDU.
+                */
 
-               if (num_read != 0x18) return False;
+               prs_init(&hps, 0, 4, UNMARSHALL);
+               prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
 
-               if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
-               {
+               num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
+               if (cli_error(cli, NULL, &err, NULL)) {
+                       DEBUG(0,("rpc_api_pipe: cli_read error : %d\n", err ));
                        return False;
                }
 
-               smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
-
-               prs_mem_free(&hps);
+               DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
 
-               if (cli_error(cli, &cls, &type))
-               {
-                       if (cls != ERRDOS || type != ERRmoredata)
-                       {
-                               return False;
-                       }
+               if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) {
+                       DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n",
+                               RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read ));
+                       return False;
                }
 
-               if (first && used_smb_trans)
-               {
-                       DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
+               if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
+                       return False;
+
+               if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) {
+                       DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n"));
                        return False;
                }
 
-               if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used, False))
-               {
+               if (first) {
+                       DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n"));
                        return False;
                }
 
-               if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
-               {
+               /*
+                * Now read the rest of the PDU.
+                */
+
+               if (!rpc_read(cli, rdata, len, &current_offset))
                        return False;
+
+               /*
+                * Verify any authentication footer.
+                */
+
+               if (rhdr.auth_len != 0 ) {
+                       if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+                               return False;
+                       /*
+                        * Drop the auth footers from the current offset.
+                        * The auth footers consist of the auth_data and the
+                        * preceeding 8 byte auth_header.
+                        * We need this if there are more fragments.
+                        */
+                       current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
                }
        }
 
@@ -442,283 +511,362 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum,
  - caller is expected to free the header data structure once used.
 
  ********************************************************************/
-static BOOL create_rpc_bind_req(prs_struct *rhdr,
-                                prs_struct *rhdr_rb,
-                                prs_struct *rhdr_auth,
-                                prs_struct *auth_req,
-                                prs_struct *auth_ntlm,
-                               uint32 rpc_call_id,
+
+static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id,
                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
                                 char *my_name, char *domain, uint32 neg_flags)
 {
-       RPC_HDR_RB           hdr_rb;
-       RPC_HDR              hdr;
-       RPC_HDR_AUTH         hdr_auth;
-       RPC_AUTH_NTLMSSP_VERIFIER auth_verifier;
-       RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
+       RPC_HDR hdr;
+       RPC_HDR_RB hdr_rb;
+       char buffer[4096];
+       prs_struct auth_info;
+       int auth_len = 0;
 
-       /* create the bind request RPC_HDR_RB */
-       make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
-                       0x1, 0x0, 0x1, abstract, transfer);
+       prs_init(&auth_info, 0, 4, MARSHALL);
 
-       /* stream the bind request data */
-       smb_io_rpc_hdr_rb("", &hdr_rb,  rhdr_rb, 0);
-       mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
+       if (do_auth) {
+               RPC_HDR_AUTH hdr_auth;
+               RPC_AUTH_VERIFIER auth_verifier;
+               RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
 
-       if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
-       {
-               make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
-               smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
-               mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
+               /*
+                * Create the auth structs we will marshall.
+                */
+
+               init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00, 1);
+               init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_NEGOTIATE);
+               init_rpc_auth_ntlmssp_neg(&ntlmssp_neg, neg_flags, my_name, domain);
+
+               /*
+                * Use the 4k buffer to store the auth info.
+                */
+
+               prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
 
-               make_rpc_auth_ntlmssp_verifier(&auth_verifier,
-                                      "NTLMSSP", NTLMSSP_NEGOTIATE);
+               /*
+                * Now marshall the data into the temporary parse_struct.
+                */
 
-               smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_req, 0);
-               mem_realloc_data(auth_req->data, auth_req->offset);
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
+                       DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
+                       return False;
+               }
+
+               if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
+                       DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_VERIFIER.\n"));
+                       return False;
+               }
 
-               make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
-                                      neg_flags, my_name, domain);
+               if(!smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_info, 0)) {
+                       DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_NTLMSSP_NEG.\n"));
+                       return False;
+               }
 
-               smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0);
-               mem_realloc_data(auth_req->data, auth_req->offset);
+               /* Auth len in the rpc header doesn't include auth_header. */
+               auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN;
        }
 
        /* create the request RPC_HDR */
-       make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
-                    (auth_req  != NULL ? auth_req ->offset : 0) +
-                    (auth_ntlm != NULL ? auth_ntlm->offset : 0) +
-                    (rhdr_auth != NULL ? rhdr_auth->offset : 0) +
-                    rhdr_rb->offset + 0x10,
-                    (auth_req  != NULL ? auth_req ->offset : 0) +
-                    (auth_ntlm != NULL ? auth_ntlm->offset : 0));
-
-       smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
-       mem_realloc_data(rhdr->data, rhdr->offset);
+       init_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id, 
+               RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
+               auth_len);
 
-       if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
+       if(!smb_io_rpc_hdr("hdr"   , &hdr, rpc_out, 0)) {
+               DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n"));
+               return False;
+       }
 
-       /***/
-       /*** link rpc header, bind acknowledgment and authentication responses ***/
-       /***/
+       /* create the bind request RPC_HDR_RB */
+       init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0,
+                       0x1, 0x0, 0x1, abstract, transfer);
 
-       if (auth_req != NULL)
-       {
-               prs_link(NULL     , rhdr      , rhdr_rb  );
-               prs_link(rhdr     , rhdr_rb   , rhdr_auth);
-               prs_link(rhdr_rb  , rhdr_auth , auth_req );
-               prs_link(rhdr_auth, auth_req  , auth_ntlm);
-               prs_link(auth_req , auth_ntlm , NULL     );
+       /* Marshall the bind request data */
+       if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
+               DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n"));
+               return False;
        }
-       else
-       {
-               prs_link(NULL, rhdr   , rhdr_rb);
-               prs_link(rhdr, rhdr_rb, NULL   );
+
+       /*
+        * Grow the outgoing buffer to store any auth info.
+        */
+
+       if(hdr.auth_len != 0) {
+               if(!prs_append_prs_data( rpc_out, &auth_info)) {
+                       DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
+                       return False;
+               }
        }
 
        return True;
 }
 
 /*******************************************************************
- creates a DCE/RPC bind authentication response
-
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
-
+ Creates a DCE/RPC bind authentication response.
+ This is the packet that is sent back to the server once we
+ have received a BIND-ACK, to finish the third leg of
+ the authentication handshake.
  ********************************************************************/
-BOOL create_rpc_bind_resp(struct pwd_info *pwd,
+
+static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
                                char *domain, char *user_name, char *my_name,
                                uint32 ntlmssp_cli_flgs,
                                uint32 rpc_call_id,
-                               prs_struct *rhdr,
-                                prs_struct *rhdr_autha,
-                                prs_struct *auth_resp)
+                               prs_struct *rpc_out)
 {
-       RPC_HDR                   hdr;
-       RPC_HDR_AUTHA             hdr_autha;
-       RPC_AUTH_NTLMSSP_VERIFIER auth_verifier;
+       unsigned char lm_owf[24];
+       unsigned char nt_owf[24];
+       RPC_HDR hdr;
+       RPC_HDR_AUTHA hdr_autha;
+       RPC_AUTH_VERIFIER auth_verifier;
+       RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+       char buffer[4096];
+       prs_struct auth_info;
 
-       make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
-       smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
-       mem_realloc_data(rhdr_autha->data, rhdr_autha->offset);
+       /*
+        * Marshall the variable length data into a temporary parse
+        * struct, pointing into a 4k local buffer.
+        */
+        prs_init(&auth_info, 0, 4, MARSHALL);
 
-       make_rpc_auth_ntlmssp_verifier(&auth_verifier,
-                              "NTLMSSP", NTLMSSP_AUTH);
+       /*
+        * Use the 4k buffer to store the auth info.
+        */
 
-       smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
-       mem_realloc_data(auth_resp->data, auth_resp->offset);
+       prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
 
-       create_ntlmssp_resp(pwd, domain, user_name, my_name, ntlmssp_cli_flgs,
-                                auth_resp);
+       /*
+        * Create the variable length auth_data.
+        */
 
-       /* create the request RPC_HDR */
-       make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
-                    auth_resp->offset + rhdr_autha->offset + 0x10,
-                    auth_resp->offset);
+       init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH);
+
+       pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
+                       
+       init_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
+                                lm_owf, nt_owf,
+                                domain, user_name, my_name,
+                                ntlmssp_cli_flgs);
+
+       /*
+        * Marshall the variable length auth_data into a temp parse_struct.
+        */
+
+       if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
+               DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_VERIFIER.\n"));
+               return False;
+       }
+
+       if(!smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, &auth_info, 0)) {
+               DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_NTLMSSP_RESP.\n"));
+               return False;
+       }
+
+       /* Create the request RPC_HDR */
+       init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
+                       RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + prs_offset(&auth_info),
+                       prs_offset(&auth_info) );
+
+       /* Marshall it. */
+       if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
+               DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n"));
+               return False;
+       }
 
-       smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
-       mem_realloc_data(rhdr->data, rhdr->offset);
+       /* Create the request RPC_HDR_AUTHA */
+       init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN,
+                       NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00);
 
-       if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
+       if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
+               DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
+               return False;
+       }
 
-       /***/
-       /*** link rpc header and authentication responses ***/
-       /***/
+       /*
+        * Append the auth data to the outgoing buffer.
+        */
 
-       prs_link(NULL      , rhdr       , rhdr_autha);
-       prs_link(rhdr      , rhdr_autha , auth_resp );
-       prs_link(rhdr_autha, auth_resp  , NULL );
+       if(!prs_append_prs_data(rpc_out, &auth_info)) {
+               DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
+               return False;
+       }
 
        return True;
 }
 
 
 /*******************************************************************
- creates a DCE/RPC bind request
-
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
-
+ Creates a DCE/RPC request.
  ********************************************************************/
 
-static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len,
-                               int auth_len)
+static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len)
 {
        uint32 alloc_hint;
-       RPC_HDR_REQ hdr_req;
        RPC_HDR     hdr;
+       RPC_HDR_REQ hdr_req;
 
-       DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
-       op_num, data_len));
+       DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len));
 
        /* create the rpc header RPC_HDR */
-       make_rpc_hdr(&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
+       init_rpc_hdr(&hdr, RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
                     get_rpc_call_id(), data_len, auth_len);
 
+       /*
+        * The alloc hint should be the amount of data, not including 
+        * RPC headers & footers.
+        */
+
        if (auth_len != 0)
-       {
-               alloc_hint = data_len - 0x18 - auth_len - 16;
-       }
+               alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len;
        else
-       {
-               alloc_hint = data_len - 0x18;
-       }
+               alloc_hint = data_len - RPC_HEADER_LEN;
 
        DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
                   data_len, auth_len, alloc_hint));
 
-       /* create the rpc request RPC_HDR_REQ */
-       make_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
+       /* Create the rpc request RPC_HDR_REQ */
+       init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
 
        /* stream-time... */
-       smb_io_rpc_hdr    ("hdr    ", &hdr    , rhdr, 0);
-       smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
+       if(!smb_io_rpc_hdr("hdr    ", &hdr, rpc_out, 0))
+               return False;
 
-       if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
+       if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0))
+               return False;
 
-       rhdr->data->offset.start = 0;
-       rhdr->data->offset.end   = rhdr->offset;
+       if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN)
+               return False;
 
        return True;
 }
 
 
 /****************************************************************************
send a request on an rpc pipe.
Send a request on an rpc pipe.
  ****************************************************************************/
-BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num,
+
+BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                       prs_struct *data, prs_struct *rdata)
 {
-       /* fudge this, at the moment: create the header; memcpy the data.  oops. */
-       prs_struct dataa;
-       prs_struct rparam;
-       prs_struct hdr;
-       prs_struct hdr_auth;
-       prs_struct auth_verf;
-       int data_len;
-       int auth_len;
+       prs_struct outgoing_packet;
+       uint32 data_len;
+       uint32 auth_len;
        BOOL ret;
        BOOL auth_verify;
        BOOL auth_seal;
        uint32 crc32 = 0;
+       char *pdata_out = NULL;
 
        auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
        auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
 
-       /* happen to know that NTLMSSP authentication verifier is 16 bytes */
-       auth_len               = (auth_verify ? 16 : 0);
-       data_len               = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18;
-       data->data->offset.end = data->offset;
+       /*
+        * The auth_len doesn't include the RPC_HDR_AUTH_LEN.
+        */
 
-       prs_init(&hdr      , data_len, 4, SAFETY_MARGIN, False);
-       prs_init(&hdr_auth , 8       , 4, SAFETY_MARGIN, False);
-       prs_init(&auth_verf, auth_len, 4, SAFETY_MARGIN, False);
-       prs_init(&rparam   , 0       , 4, 0            , True );
+       auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0);
 
-       create_rpc_request(&hdr, op_num, data_len, auth_len);
+       /*
+        * PDU len is header, plus request header, plus data, plus
+        * auth_header_len (if present), plus auth_len (if present).
+        * NB. The auth stuff should be aligned on an 8 byte boundary
+        * to be totally DCE/RPC spec complient. For now we cheat and
+        * hope that the data structs defined are a multiple of 8 bytes.
+        */
 
-       if (auth_seal)
-       {
-               crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0));
-               NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset);
+       if((prs_offset(data) % 8) != 0) {
+               DEBUG(5,("rpc_api_pipe_req: Outgoing data not a multiple of 8 bytes....\n"));
        }
 
-       if (auth_seal || auth_verify)
-       {
-               RPC_HDR_AUTH         rhdr_auth;
+       data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(data) +
+                       (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len;
 
-               make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
-               smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
+       /*
+        * Malloc a parse struct to hold it (and enough for alignments).
+        */
+
+       if(!prs_init(&outgoing_packet, data_len + 8, 4, MARSHALL)) {
+               DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
+               return False;
        }
 
-       if (auth_verify)
-       {
-               RPC_AUTH_NTLMSSP_CHK chk;
+       pdata_out = prs_data_p(&outgoing_packet);
+       
+       /*
+        * Write out the RPC header and the request header.
+        */
+
+       if(!create_rpc_request(&outgoing_packet, op_num, data_len, auth_len)) {
+               DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
+               prs_mem_free(&outgoing_packet);
+               return False;
+       }
+
+       /*
+        * Seal the outgoing data if requested.
+        */
 
-               make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
-               smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
-               NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12);
+       if (auth_seal) {
+               crc32 = crc32_calc_buffer(prs_data_p(data), prs_offset(data));
+               NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data), prs_offset(data));
        }
 
-       if (auth_seal || auth_verify)
-       {
-               prs_link(NULL     , &hdr      , data      );
-               prs_link(&hdr     , data      , &hdr_auth );
-               prs_link(data     , &hdr_auth , &auth_verf);
-               prs_link(&hdr_auth, &auth_verf, NULL      );
+       /*
+        * Now copy the data into the outgoing packet.
+        */
+
+       if(!prs_append_prs_data( &outgoing_packet, data)) {
+               DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n"));
+               prs_mem_free(&outgoing_packet);
+               return False;
        }
-       else
-       {
-               prs_link(NULL, &hdr, data);
-               prs_link(&hdr, data, NULL);
+
+       /*
+        * Add a trailing auth_verifier if needed.
+        */
+
+       if (auth_seal || auth_verify) {
+               RPC_HDR_AUTH hdr_auth;
+
+               init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE,
+                       NTLMSSP_AUTH_LEVEL, 0x08, (auth_verify ? 1 : 0));
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &outgoing_packet, 0)) {
+                       DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_HDR_AUTH.\n"));
+                       prs_mem_free(&outgoing_packet);
+                       return False;
+               }
        }
 
-       DEBUG(100,("data_len: %x data_calc_len: %x\n",
-               data_len, mem_buf_len(data->data)));
+       /*
+        * Finally the auth data itself.
+        */
+
+       if (auth_verify) {
+               RPC_AUTH_NTLMSSP_CHK chk;
+               uint32 current_offset = prs_offset(&outgoing_packet);
+
+               init_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
+               if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &outgoing_packet, 0)) {
+                       DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n"));
+                       prs_mem_free(&outgoing_packet);
+                       return False;
+               }
+               NTLMSSPcalc_ap(cli, (unsigned char*)&pdata_out[current_offset+4], RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+       }
 
-       /* this is a hack due to limitations in rpc_api_pipe */
-       prs_init(&dataa, data_len, 4, 0x0, False);
-       mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data));
+       DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet)));
 
-       ret = rpc_api_pipe(cli, fnum, False, 0x0026, NULL, &dataa, &rparam, rdata);
+       ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata);
 
-       prs_mem_free(&hdr_auth );
-       prs_mem_free(&auth_verf);
-       prs_mem_free(&rparam   );
-       prs_mem_free(&hdr      );
-       prs_mem_free(&dataa    );
+       prs_mem_free(&outgoing_packet);
 
        return ret;
 }
 
 /****************************************************************************
-do an rpc bind
+ Set the handle state.
 ****************************************************************************/
 
-static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
-                               const char *pipe_name, uint16 device_state)
+static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
 {
        BOOL state_set = False;
        char param[2];
@@ -727,17 +875,18 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
        char *rdata = NULL;
        uint32 rparam_len, rdata_len;
 
-       if (pipe_name == NULL) return False;
+       if (pipe_name == NULL)
+               return False;
 
        DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
-                 fnum, pipe_name, device_state));
+       cli->nt_pipe_fnum, pipe_name, device_state));
 
        /* create parameters: device state */
        SSVAL(param, 0, device_state);
 
        /* create setup parameters. */
        setup[0] = 0x0001; 
-       setup[1] = fnum; /* pipe file handle.  got this from an SMBOpenX. */
+       setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
 
        /* send the data on \PIPE\ */
        if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
@@ -751,8 +900,10 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
                state_set = True;
        }
 
-       if (rparam) free(rparam);
-       if (rdata ) free(rdata );
+       if (rparam)
+               free(rparam);
+       if (rdata)
+               free(rdata );
 
        return state_set;
 }
@@ -761,27 +912,22 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
  check the rpc bind acknowledge response
 ****************************************************************************/
 
-static BOOL valid_pipe_name(const char *pipe_name,
-                               RPC_IFACE *abstract, RPC_IFACE *transfer)
+static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
 {
        int pipe_idx = 0;
 
-       while (pipe_names[pipe_idx].client_pipe != NULL)
-       {
-               if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
-               {
-                       DEBUG(5,("Bind Abstract Syntax:\n"));   
+       while (pipe_names[pipe_idx].client_pipe != NULL) {
+               if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) {
+                       DEBUG(5,("Bind Abstract Syntax: "));    
                        dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), 
                                  sizeof(pipe_names[pipe_idx].abstr_syntax));
-                       DEBUG(5,("Bind Transfer Syntax:\n"));
+                       DEBUG(5,("Bind Transfer Syntax: "));
                        dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
                                  sizeof(pipe_names[pipe_idx].trans_syntax));
 
                        /* copy the required syntaxes out so we can do the right bind */
-                       memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
-                              sizeof(pipe_names[pipe_idx].trans_syntax));
-                       memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
-                              sizeof(pipe_names[pipe_idx].abstr_syntax));
+                       *transfer = pipe_names[pipe_idx].trans_syntax;
+                       *abstract = pipe_names[pipe_idx].abstr_syntax;
 
                        return True;
                }
@@ -796,56 +942,44 @@ static BOOL valid_pipe_name(const char *pipe_name,
  check the rpc bind acknowledge response
 ****************************************************************************/
 
-static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name,
-                               RPC_IFACE *transfer)
+static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
 {
        int i = 0;
 
-       while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
-       {
+       while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) {
                DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
                pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
 
-               if ((strequal(pipe_name, pipe_names[i].client_pipe )))
-               {
-                       if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
-                       {
+               if ((strequal(pipe_name, pipe_names[i].client_pipe ))) {
+                       if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) {
                                DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
                                         pipe_names[i].server_pipe ));
                                break;
-                       }
-                       else
-                       {
+                       } else {
                                DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
                                         pipe_names[i].server_pipe ,
                                         hdr_ba->addr.str));
                                break;
                        }
-               }
-               else
-               {
+               } else {
                        i++;
                }
        }
 
-       if (pipe_names[i].server_pipe == NULL)
-       {
+       if (pipe_names[i].server_pipe == NULL) {
                DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
                return False;
        }
 
        /* check the transfer syntax */
-       if (!((hdr_ba->transfer.version == transfer->version) &&
-            (memcmp(hdr_ba->transfer.data, transfer->data,
-                    sizeof(transfer->version)) ==0)))
-       {
+       if ((hdr_ba->transfer.version != transfer->version) ||
+            (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
                DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
                return False;
        }
 
        /* lkclXXXX only accept one result: check the result(s) */
-       if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
-       {
+       if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
                DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
                          hdr_ba->res.num_results, hdr_ba->res.reason));
        }
@@ -855,196 +989,169 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name,
 }
 
 /****************************************************************************
-do an rpc bind
+ Create and send the third packet in an RPC auth.
 ****************************************************************************/
 
-static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum,
-                               const char *pipe_name,
-                               RPC_IFACE *abstract, RPC_IFACE *transfer, 
-                               char *my_name)
+static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id)
 {
-       prs_struct hdr;
-       prs_struct hdr_rb;
-       prs_struct hdr_auth;
-       prs_struct auth_req;
-       prs_struct auth_ntlm;
-       prs_struct data;
-       prs_struct rdata;
-       prs_struct rparam;
+       RPC_HDR_AUTH rhdr_auth;
+       RPC_AUTH_VERIFIER rhdr_verf;
+       RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
+       char buffer[MAX_PDU_FRAG_LEN];
+       prs_struct rpc_out;
+       ssize_t ret;
+
+       unsigned char p24[24];
+       unsigned char lm_owf[24];
+       unsigned char lm_hash[16];
+
+       if(!smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0)) {
+               DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_HDR_AUTH.\n"));
+               return False;
+       }
+       if(!smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0)) {
+               DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_VERIFIER.\n"));
+               return False;
+       }
+       if(!smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, rdata, 0)) {
+               DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_NTLMSSP_CHAL.\n"));
+               return False;
+       }
 
-       BOOL valid_ack = False;
-       BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
-       uint32 rpc_call_id;
+       cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
+
+       pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
+
+       prs_init(&rpc_out, 0, 4, MARSHALL);
+
+       prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
+
+       create_rpc_bind_resp(&cli->pwd, cli->domain,
+                            cli->user_name, global_myname, 
+                            cli->ntlmssp_cli_flgs, rpc_call_id,
+                            &rpc_out);
+                                           
+       pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
+       pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
+
+       NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
 
-       if (pipe_name == NULL || abstract == NULL || transfer == NULL)
        {
+               unsigned char j = 0;
+               int ind;
+               unsigned char k2[8];
+
+               memcpy(k2, p24, 5);
+               k2[5] = 0xe5;
+               k2[6] = 0x38;
+               k2[7] = 0xb0;
+
+               for (ind = 0; ind < 256; ind++)
+                       cli->ntlmssp_hash[ind] = (unsigned char)ind;
+
+               for( ind = 0; ind < 256; ind++) {
+                       unsigned char tc;
+
+                       j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
+
+                       tc = cli->ntlmssp_hash[ind];
+                       cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
+                       cli->ntlmssp_hash[j] = tc;
+               }
+
+               cli->ntlmssp_hash[256] = 0;
+               cli->ntlmssp_hash[257] = 0;
+       }
+
+       memset((char *)lm_hash, '\0', sizeof(lm_hash));
+
+       if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out), 
+                       0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
+               DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
                return False;
        }
 
-       DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name));
+       cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
+       return True;
+}
+
+/****************************************************************************
+ Do an rpc bind.
+****************************************************************************/
+
+static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
+{
+       RPC_IFACE abstract;
+       RPC_IFACE transfer;
+       prs_struct rpc_out;
+       prs_struct rdata;
+       BOOL do_auth = (cli->ntlmssp_cli_flgs != 0);
+       uint32 rpc_call_id;
+       char buffer[MAX_PDU_FRAG_LEN];
 
-       if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
+       DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
 
-       prs_init(&hdr      , 0x10                     , 4, 0x0          , False);
-       prs_init(&hdr_rb   , 1024                     , 4, SAFETY_MARGIN, False);
-       prs_init(&hdr_auth , (ntlmssp_auth ?    8 : 0), 4, SAFETY_MARGIN, False);
-       prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
-       prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
+       if (!valid_pipe_name(pipe_name, &abstract, &transfer))
+               return False;
 
-       prs_init(&rdata    , 0   , 4, SAFETY_MARGIN, True);
-       prs_init(&rparam   , 0   , 4, SAFETY_MARGIN, True);
+       prs_init(&rpc_out, 0, 4, MARSHALL);
 
-       rpc_call_id = get_rpc_call_id();
-       create_rpc_bind_req(&hdr, &hdr_rb,
-                           ntlmssp_auth ? &hdr_auth : NULL,
-                           ntlmssp_auth ? &auth_req : NULL,
-                           ntlmssp_auth ? &auth_ntlm : NULL,
-                           rpc_call_id,
-                           abstract, transfer,
-                           global_myname, cli->usr.domain, cli->usr.ntlmssp_flags);
+       /*
+        * Use the MAX_PDU_FRAG_LEN buffer to store the bind request.
+        */
 
-       /* this is a hack due to limitations in rpc_api_pipe */
-       prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
-       mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
+       prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
 
-       cli->max_recv_frag = 0x1000;
+       rpc_call_id = get_rpc_call_id();
 
-       /* send data on \PIPE\.  receive a response */
-       if (rpc_api_pipe(cli, fnum, True, 0x0026, NULL, &data, &rparam, &rdata))
-       {
-               RPC_HDR_BA                hdr_ba;
-               RPC_HDR_AUTH              rhdr_auth;
-               RPC_AUTH_NTLMSSP_VERIFIER rhdr_verf;
-               RPC_AUTH_NTLMSSP_CHAL     rhdr_chal;
+       /* Marshall the outgoing data. */
+       create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id,
+                           &abstract, &transfer,
+                           global_myname, cli->domain, cli->ntlmssp_cli_flgs);
 
-               DEBUG(5, ("rpc_api_pipe: return OK\n"));
+       /* Initialize the incoming data struct. */
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-               smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
+       /* send data on \PIPE\.  receive a response */
+       if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) {
+               RPC_HDR_BA   hdr_ba;
 
-               if (rdata.offset != 0)
-               {
-                       valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
-               }
+               DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));
 
-               if (valid_ack)
-               {
-                       cli->max_xmit_frag = hdr_ba.bba.max_tsize;
-                       cli->max_recv_frag = hdr_ba.bba.max_rsize;
+               if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0)) {
+                       DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
+                       prs_mem_free(&rdata);
+                       return False;
                }
 
-               if (valid_ack && ntlmssp_auth)
-               {
-                       smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
-                       if (rdata.offset == 0) valid_ack = False;
+               if(!check_bind_response(&hdr_ba, pipe_name, &transfer)) {
+                       DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n"));
+                       prs_mem_free(&rdata);
+                       return False;
                }
 
-               if (valid_ack && ntlmssp_auth)
-               {
-                       smb_io_rpc_auth_ntlmssp_verifier("", &rhdr_verf, &rdata, 0);
-                       if (rdata.offset == 0) valid_ack = False;
-               }
-               if (valid_ack && ntlmssp_auth)
-               {
-                       smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
-                       if (rdata.offset == 0) valid_ack = False;
-               }
-               if (valid_ack && ntlmssp_auth)
-               {
-                       unsigned char p24[24];
-                       unsigned char lm_owf[24];
-                       unsigned char lm_hash[16];
-
-                       prs_struct hdra;
-                       prs_struct hdr_autha;
-                       prs_struct auth_resp;
-                       prs_struct dataa;
-
-                       cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
-
-                       prs_init(&hdra     , 0x10, 4, 0x0          , False);
-                       prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False);
-                       prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
-
-                       pwd_make_lm_nt_owf(&cli->usr.pwd, rhdr_chal.challenge);
-
-                       create_rpc_bind_resp(&cli->usr.pwd, cli->usr.domain,
-                                            cli->usr.user_name, global_myname, 
-                                            cli->ntlmssp_cli_flgs,
-                                            rpc_call_id,
-                                            &hdra, &hdr_autha, &auth_resp);
-                                           
-                       pwd_get_lm_nt_owf(&cli->usr.pwd, lm_owf, NULL, NULL, NULL);
-                       pwd_get_lm_nt_16(&cli->usr.pwd, lm_hash, NULL);
-                       NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
-                       {
-                               unsigned char j = 0;
-                               int ind;
-                               unsigned char k2[8];
-
-                               memcpy(k2, p24, 5);
-                               k2[5] = 0xe5;
-                               k2[6] = 0x38;
-                               k2[7] = 0xb0;
-
-                               for (ind = 0; ind < 256; ind++)
-                               {
-                                       cli->ntlmssp_hash[ind] = (unsigned char)ind;
-                               }
-
-                               for( ind = 0; ind < 256; ind++)
-                               {
-                                       unsigned char tc;
-
-                                       j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
-
-                                       tc = cli->ntlmssp_hash[ind];
-                                       cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
-                                       cli->ntlmssp_hash[j] = tc;
-                               }
-
-                               cli->ntlmssp_hash[256] = 0;
-                               cli->ntlmssp_hash[257] = 0;
-                       }
-/*                     NTLMSSPhash(cli->ntlmssp_hash, p24); */
-                       bzero(lm_hash, sizeof(lm_hash));
-
-                       /* this is a hack due to limitations in rpc_api_pipe */
-                       prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
-                       mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
-
-                       if (cli_write(cli, fnum, 0x0008,
-                                 dataa.data->data, 0,
-                                 dataa.data->data_used) < 0)
-                       {
-                               valid_ack = False;
-                       }
+               cli->max_xmit_frag = hdr_ba.bba.max_tsize;
+               cli->max_recv_frag = hdr_ba.bba.max_rsize;
 
-                       if (valid_ack)
-                       {
-                               cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
-                       }
+               /*
+                * If we're doing NTLMSSP auth we need to send a reply to
+                * the bind-ack to complete the 3-way challenge response
+                * handshake.
+                */
 
-                       prs_mem_free(&hdra);
-                       prs_mem_free(&dataa);
-                       prs_mem_free(&hdr_autha);
-                       prs_mem_free(&auth_resp);
+               if (do_auth && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
+                       DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
+                       prs_mem_free(&rdata);
+                       return False;
                }
        }
 
-       prs_mem_free(&data     );
-       prs_mem_free(&hdr      );
-       prs_mem_free(&hdr_rb   );
-       prs_mem_free(&hdr_auth );
-       prs_mem_free(&auth_req );
-       prs_mem_free(&auth_ntlm);
-       prs_mem_free(&rdata    );
-       prs_mem_free(&rparam   );
-
-       return valid_ack;
+       prs_mem_free(&rdata);
+       return True;
 }
 
 /****************************************************************************
- set ntlmssp negotiation flags
+ Set ntlmssp negotiation flags.
  ****************************************************************************/
 
 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
@@ -1054,68 +1161,45 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
 
 
 /****************************************************************************
- open a session
+ Open a session.
  ****************************************************************************/
 
-BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
-               uint16* fnum)
+BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
 {
-       RPC_IFACE abstract;
-       RPC_IFACE transfer;
+       int fnum;
 
-       /******************* open the pipe *****************/
-       if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
-       {
-               int f;
-               f = cli_nt_create(cli, &(pipe_name[5]));
-               if (f == -1)
-               {
-                       fstring errstr;
-                       cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
+       if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) {
+               if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) {
                        DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s.  Error was %s\n",
-                                &(pipe_name[5]), cli->desthost, errstr));
+                                &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
                        return False;
                }
-               *fnum = (uint16)f;
-       }
-       else
-       {
-               int f;
-               f = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE);
-               if (f == -1)
-               {
-                       fstring errstr;
-                       cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
+
+               cli->nt_pipe_fnum = (uint16)fnum;
+       } else {
+               if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
                        DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
-                                pipe_name, cli->desthost, errstr));
+                                pipe_name, cli->desthost, cli_errstr(cli)));
                        return False;
                }
-               *fnum = (uint16)f;
+
+               cli->nt_pipe_fnum = (uint16)fnum;
 
                /**************** Set Named Pipe State ***************/
-               if (!rpc_pipe_set_hnd_state(cli, *fnum, pipe_name, 0x4300))
-               {
-                       fstring errstr;
-                       cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
+               if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) {
                        DEBUG(0,("cli_nt_session_open: pipe hnd state failed.  Error was %s\n",
-                                 errstr));
-                       cli_close(cli, *fnum);
+                                 cli_errstr(cli)));
+                       cli_close(cli, cli->nt_pipe_fnum);
                        return False;
                }
-
        }
 
        /******************* bind request on pipe *****************/
 
-       if (!rpc_pipe_bind(cli, *fnum, pipe_name,
-                          &abstract, &transfer,
-                          global_myname))
-       {
-               fstring errstr;
-               cli_safe_errstr(cli, errstr, sizeof(errstr)-1);
+       if (!rpc_pipe_bind(cli, pipe_name, global_myname)) {
                DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
-                         errstr));
-               cli_close(cli, *fnum);
+                         cli_errstr(cli)));
+               cli_close(cli, cli->nt_pipe_fnum);
                return False;
        }
 
@@ -1123,6 +1207,18 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
         * Setup the remote server name prefixed by \ and the machine account name.
         */
 
+       fstrcpy(cli->srv_name_slash, "\\\\");
+       fstrcat(cli->srv_name_slash, cli->desthost);
+       strupper(cli->srv_name_slash);
+
+       fstrcpy(cli->clnt_name_slash, "\\\\");
+       fstrcat(cli->clnt_name_slash, global_myname);
+       strupper(cli->clnt_name_slash);
+
+       fstrcpy(cli->mach_acct, global_myname);
+       fstrcat(cli->mach_acct, "$");
+       strupper(cli->mach_acct);
+
        return True;
 }
 
@@ -1130,10 +1226,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
 close the session
 ****************************************************************************/
 
-void cli_nt_session_close(struct cli_state *cli, uint16 fnum)
+void cli_nt_session_close(struct cli_state *cli)
 {
-       if (fnum != 0xffff)
-       {
-               cli_close(cli, fnum);
-       }
+       cli_close(cli, cli->nt_pipe_fnum);
 }
index 4f1c28a70155f75829905241b6b83d237993a019..b5e9cbb2ac2e7627844a40c2a6c1b36af7285dd3 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1998,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  Copyright (C) Paul Ashton                  1997-1998.
+ *  Copyright (C) Jeremy Allison                    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
@@ -34,80 +35,38 @@ extern int DEBUGLEVEL;
 /****************************************************************************
 do a REG Open Policy
 ****************************************************************************/
-BOOL reg_connect( const char* srv_name,
-                               const char *full_keyname,
-                               char *key_name,
+BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
                                POLICY_HND *reg_hnd)
 {
        BOOL res = True;
        uint32 reg_type = 0;
 
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_init(srv_name, PIPE_WINREG, &con))
-       {
+       if (full_keyname == NULL)
                return False;
-       }
 
        ZERO_STRUCTP(reg_hnd);
 
-       if (full_keyname == NULL)
-       {
-               return False;
-       }
-
        /*
         * open registry receive a policy handle
         */
 
-       if (!reg_split_key(full_keyname, &reg_type, key_name))
-       {
-               DEBUG(0,("reg_connect: unrecognised key name %s\n",
-                         full_keyname));       
+       if (!reg_split_key(full_keyname, &reg_type, key_name)) {
+               DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname));  
                return False;
        }
 
-       switch (reg_type)
-       {
-               case HKEY_CLASSES_ROOT:
-               {
-                       res = res ? reg_open_hkcr(con, 
-                                       0x5428, 0x02000000,
-                                       reg_hnd) : False;
-                       break;
-               }
+       switch (reg_type) {
+       case HKEY_LOCAL_MACHINE:
+               res = res ? do_reg_open_hklm(cli, 0x84E0, 0x02000000, reg_hnd) : False;
+               break;
        
-               case HKEY_LOCAL_MACHINE:
-               {
-                       res = res ? reg_open_hklm(con, 
-                                       0x84E0, 0x02000000,
-                                       reg_hnd) : False;
-                       break;
-               }
-       
-               case HKEY_USERS:
-               {
-                       res = res ? reg_open_hku(con, 
-                                       0x84E0, 0x02000000,
-                                       reg_hnd) : False;
-                       break;
-               }
-               default:
-               {
-                       DEBUG(0,("reg_connect: unrecognised hive key\n"));      
-                       return False;
-               }
-       }
+       case HKEY_USERS:
+               res = res ? do_reg_open_hku(cli, 0x84E0, 0x02000000, reg_hnd) : False;
+               break;
 
-       if (res)
-       {
-               if (!register_policy_hnd(reg_hnd) ||
-                   !set_policy_con(reg_hnd, con, 
-                                                cli_connection_unlink))
-               {
-                       cli_connection_unlink(con);
-                       return False;
-               }
+       default:
+               DEBUG(0,("do_reg_connect: unrecognised hive key\n"));   
+               return False;
        }
 
        return res;
@@ -116,175 +75,123 @@ BOOL reg_connect( const char* srv_name,
 /****************************************************************************
 do a REG Open Policy
 ****************************************************************************/
-BOOL reg_open_hkcr( struct cli_connection *con,
-                               uint16 unknown_0, uint32 level,
-                               POLICY_HND *hnd)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       REG_Q_OPEN_HKCR q_o;
-       BOOL valid_pol = False;
-
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api REG_OPEN_HKCR */
-
-       DEBUG(4,("REG Open HKCR\n"));
-
-       make_reg_q_open_hkcr(&q_o, unknown_0, level);
-
-       /* turn parameters into data stream */
-       reg_io_q_open_hkcr("", &q_o, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, REG_OPEN_HKCR, &buf, &rbuf))
-       {
-               REG_R_OPEN_HKCR r_o;
-               BOOL p;
-
-               ZERO_STRUCT(r_o);
-
-               reg_io_r_open_hkcr("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_OPEN_HKCR: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a REG Open Policy
-****************************************************************************/
-BOOL reg_open_hklm( struct cli_connection *con,
-                               uint16 unknown_0, uint32 level,
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
                                POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_OPEN_HKLM q_o;
-       BOOL valid_pol = False;
+       REG_R_OPEN_HKLM r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_OPEN_HKLM */
 
        DEBUG(4,("REG Open HKLM\n"));
 
-       make_reg_q_open_hklm(&q_o, unknown_0, level);
+       init_reg_q_open_hklm(&q_o, unknown_0, level);
 
        /* turn parameters into data stream */
-       reg_io_q_open_hklm("", &q_o, &buf, 0);
+       if(!reg_io_q_open_hklm("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, REG_OPEN_HKLM, &buf, &rbuf))
-       {
-               REG_R_OPEN_HKLM r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_open_hklm("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_open_hklm("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-                       valid_pol = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       /* ok, at last: we're happy. return the policy handle */
+       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_pol;
+       return True;
 }
 
 /****************************************************************************
 do a REG Open HKU
 ****************************************************************************/
-BOOL reg_open_hku( struct cli_connection *con, 
-                               uint16 unknown_0, uint32 level,
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
                                POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_OPEN_HKU q_o;
-       BOOL valid_pol = False;
+       REG_R_OPEN_HKU r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_OPEN_HKU */
 
        DEBUG(4,("REG Open HKU\n"));
 
-       make_reg_q_open_hku(&q_o, unknown_0, level);
+       init_reg_q_open_hku(&q_o, unknown_0, level);
 
        /* turn parameters into data stream */
-       reg_io_q_open_hku("", &q_o, &buf, 0);
+       if(!reg_io_q_open_hku("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, REG_OPEN_HKU, &buf, &rbuf))
-       {
-               REG_R_OPEN_HKU r_o;
-               BOOL p;
+       if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_open_hku("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_open_hku("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-                       valid_pol = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       /* ok, at last: we're happy. return the policy handle */
+       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_pol;
+       return True;
 }
 
 /****************************************************************************
@@ -292,62 +199,65 @@ do a REG Unknown 0xB command.  sent after a create key or create value.
 this might be some sort of "sync" or "refresh" command, sent after
 modification of the registry...
 ****************************************************************************/
-BOOL reg_flush_key( POLICY_HND *hnd)
+BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_FLUSH_KEY q_o;
-       BOOL valid_query = False;
+       REG_R_FLUSH_KEY r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_FLUSH_KEY */
 
        DEBUG(4,("REG Unknown 0xB\n"));
 
-       make_reg_q_flush_key(&q_o, hnd);
+       init_reg_q_flush_key(&q_o, hnd);
 
        /* turn parameters into data stream */
-       reg_io_q_flush_key("", &q_o, &buf, 0);
+       if(!reg_io_q_flush_key("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_FLUSH_KEY, &buf, &rbuf))
-       {
-               REG_R_FLUSH_KEY r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_flush_key("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_flush_key("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Query Key
 ****************************************************************************/
-BOOL reg_query_key( POLICY_HND *hnd,
-                               char *key_class, uint32 *class_len,
+BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
+                               char *class, uint32 *class_len,
                                uint32 *num_subkeys, uint32 *max_subkeylen,
                                uint32 *max_subkeysize, uint32 *num_values,
                                uint32 *max_valnamelen, uint32 *max_valbufsize,
@@ -356,409 +266,427 @@ BOOL reg_query_key( POLICY_HND *hnd,
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_QUERY_KEY q_o;
-       BOOL valid_query = False;
+       REG_R_QUERY_KEY r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_QUERY_KEY */
 
        DEBUG(4,("REG Query Key\n"));
 
-       make_reg_q_query_key(&q_o, hnd, *class_len);
+       init_reg_q_query_key(&q_o, hnd, *class_len);
 
        /* turn parameters into data stream */
-       reg_io_q_query_key("", &q_o, &buf, 0);
+       if(!reg_io_q_query_key("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_QUERY_KEY, &buf, &rbuf))
-       {
-               REG_R_QUERY_KEY r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_query_key("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_query_key("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-                       
-                       *class_len      = r_o.hdr_class.uni_max_len;
-                       unistr2_to_ascii(key_class, &r_o.uni_class, sizeof(fstring)-1);
-                       *num_subkeys    = r_o.num_subkeys   ;
-                       *max_subkeylen  = r_o.max_subkeylen ;
-                       *max_subkeysize = r_o.max_subkeysize;
-                       *num_values     = r_o.num_values    ;
-                       *max_valnamelen = r_o.max_valnamelen;
-                       *max_valbufsize = r_o.max_valbufsize;
-                       *sec_desc       = r_o.sec_desc      ;
-                       *mod_time       = r_o.mod_time      ;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       *class_len      = r_o.hdr_class.uni_max_len;
+       fstrcpy(class, dos_unistr2_to_str(&r_o.uni_class));
+       *num_subkeys    = r_o.num_subkeys   ;
+       *max_subkeylen  = r_o.max_subkeylen ;
+       *max_subkeysize = r_o.max_subkeysize;
+       *num_values     = r_o.num_values    ;
+       *max_valnamelen = r_o.max_valnamelen;
+       *max_valbufsize = r_o.max_valbufsize;
+       *sec_desc       = r_o.sec_desc      ;
+       *mod_time       = r_o.mod_time      ;
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Unknown 1A
 ****************************************************************************/
-BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk)
+BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_UNK_1A q_o;
-       BOOL valid_query = False;
+       REG_R_UNK_1A r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_UNKNOWN_1A */
 
        DEBUG(4,("REG Unknown 1a\n"));
 
-       make_reg_q_unk_1a(&q_o, hnd);
+       init_reg_q_unk_1a(&q_o, hnd);
 
        /* turn parameters into data stream */
-       reg_io_q_unk_1a("", &q_o, &buf, 0);
+       if(!reg_io_q_unk_1a("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_UNK_1A, &buf, &rbuf))
-       {
-               REG_R_UNK_1A r_o;
-               BOOL p;
+       if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_unk_1a("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_unk_1a("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-                       (*unk) = r_o.unknown;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       (*unk) = r_o.unknown;
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Query Info
 ****************************************************************************/
-BOOL reg_query_info( POLICY_HND *hnd,
-                               const char* val_name,
-                               uint32 *type, BUFFER2 *buffer)
+BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
+                               char *type, uint32 *unk_0, uint32 *unk_1)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_INFO q_o;
-       BOOL valid_query = False;
+       REG_R_INFO r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_INFO */
 
        DEBUG(4,("REG Query Info\n"));
 
-       make_reg_q_info(&q_o, hnd, val_name, 4, 0);
+       init_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
 
        /* turn parameters into data stream */
-       reg_io_q_info("", &q_o, &buf, 0);
+       if(!reg_io_q_info("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_INFO, &buf, &rbuf))
-       {
-               REG_R_INFO r_o;
-               BOOL p;
-
-               ZERO_STRUCT(r_o);
+       if (!rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               r_o.type = type;
-               r_o.uni_type = buffer;
+       prs_mem_free(&buf);
 
-               reg_io_r_info("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_info("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-               }
+       if ( r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       fstrcpy(type, dos_buffer2_to_str(&r_o.uni_type));
+       (*unk_0) = r_o.unknown_0;
+       (*unk_1) = r_o.unknown_1;
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Set Key Security 
 ****************************************************************************/
-BOOL reg_set_key_sec( POLICY_HND *hnd,
-                               uint32 sec_info,
-                               uint32 sec_buf_size, SEC_DESC *sec_buf)
+BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_SET_KEY_SEC q_o;
-       BOOL valid_query = False;
+       REG_R_SET_KEY_SEC r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_SET_KEY_SEC */
 
        DEBUG(4,("REG Set Key security.\n"));
 
-       make_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_buf_size, sec_buf);
+       init_reg_q_set_key_sec(&q_o, hnd, sec_desc_buf);
 
        /* turn parameters into data stream */
-       reg_io_q_set_key_sec("", &q_o, &buf, 0);
+       if(!reg_io_q_set_key_sec("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_SET_KEY_SEC, &buf, &rbuf))
-       {
-               REG_R_SET_KEY_SEC r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_SET_KEY_SEC, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_set_key_sec("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       valid_query = True;
-               }
+       if(!reg_io_r_set_key_sec("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       if (r_o.status != 0) {
+               prs_mem_free(&rbuf);
+               return False;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
-
 /****************************************************************************
 do a REG Query Key Security 
 ****************************************************************************/
-BOOL reg_get_key_sec( POLICY_HND *hnd,
-                               uint32 sec_info,
-                               uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
+
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_GET_KEY_SEC q_o;
-       BOOL valid_query = False;
+       REG_R_GET_KEY_SEC r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_GET_KEY_SEC */
 
        DEBUG(4,("REG query key security.  buf_size: %d\n", *sec_buf_size));
 
-       make_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf);
+       init_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, NULL);
 
        /* turn parameters into data stream */
-       reg_io_q_get_key_sec("", &q_o, &buf, 0);
+       if(!reg_io_q_get_key_sec("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_GET_KEY_SEC, &buf, &rbuf))
-       {
-               REG_R_GET_KEY_SEC r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               r_o.data = sec_buf;
-               if (*sec_buf_size != 0)
-               {
-                       sec_buf->sec = (SEC_DESC*)malloc(*sec_buf_size);
-               }
-               reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status == 0x0000007a)
-               {
-                       /*
-                        * get the maximum buffer size: it was too small
-                        */
-                       (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
-                       DEBUG(5,("sec_buf_size too small.  use %d\n", *sec_buf_size));
-                       valid_query = True;
-               }
-               else if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-               else
-               {
-                       valid_query = True;
-                       (*sec_buf_size) = r_o.data->len;
-               }
+       ZERO_STRUCT(r_o);
+
+       if(!reg_io_r_get_key_sec("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       if (r_o.status == 0x0000007a) {
+               /*
+                * get the maximum buffer size: it was too small
+                */
+               (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+               DEBUG(5,("sec_buf_size too small.  use %d\n", *sec_buf_size));
+       } else if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       } else {
+               (*sec_buf_size) = r_o.data->len;
+               *ppsec_desc_buf = r_o.data;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Delete Value
 ****************************************************************************/
-BOOL reg_delete_val( POLICY_HND *hnd, char *val_name)
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_DELETE_VALUE q_o;
-       BOOL valid_delete = False;
+       REG_R_DELETE_VALUE r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_DELETE_VALUE */
 
        DEBUG(4,("REG Delete Value: %s\n", val_name));
 
-       make_reg_q_delete_val(&q_o, hnd, val_name);
+       init_reg_q_delete_val(&q_o, hnd, val_name);
 
        /* turn parameters into data stream */
-       reg_io_q_delete_val("", &q_o, &buf, 0);
+       if(!reg_io_q_delete_val("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_DELETE_VALUE, &buf, &rbuf))
-       {
-               REG_R_DELETE_VALUE r_o;
-               BOOL p;
+       if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_delete_val("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_delete_val("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_delete = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_delete;
+       return True;
 }
 
 /****************************************************************************
 do a REG Delete Key
 ****************************************************************************/
-BOOL reg_delete_key( POLICY_HND *hnd, char *key_name)
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_DELETE_KEY q_o;
-       BOOL valid_delete = False;
+       REG_R_DELETE_KEY r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_DELETE_KEY */
 
        DEBUG(4,("REG Delete Key: %s\n", key_name));
 
-       make_reg_q_delete_key(&q_o, hnd, key_name);
+       init_reg_q_delete_key(&q_o, hnd, key_name);
 
        /* turn parameters into data stream */
-       reg_io_q_delete_key("", &q_o, &buf, 0);
+       if(!reg_io_q_delete_key("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_DELETE_KEY, &buf, &rbuf))
-       {
-               REG_R_DELETE_KEY r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_delete_key("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_delete_key("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_delete = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_delete;
+       return True;
 }
 
 /****************************************************************************
 do a REG Create Key
 ****************************************************************************/
-BOOL reg_create_key( POLICY_HND *hnd,
+BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
                                char *key_name, char *key_class,
                                SEC_ACCESS *sam_access,
                                POLICY_HND *key)
@@ -766,73 +694,84 @@ BOOL reg_create_key( POLICY_HND *hnd,
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_CREATE_KEY q_o;
-       BOOL valid_create = False;
-       SEC_DESC sec;
-       SEC_DESC_BUF sec_buf;
-       int sec_len;
+       REG_R_CREATE_KEY r_o;
+       SEC_DESC *sec = NULL;
+       SEC_DESC_BUF *sec_buf = NULL;
+       size_t sec_len;
 
-       ZERO_STRUCT(sec);
-       ZERO_STRUCT(sec_buf);
        ZERO_STRUCT(q_o);
 
-       if (hnd == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       if (hnd == NULL)
+               return False;
 
        /* create and send a MSRPC command with api REG_CREATE_KEY */
 
        DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
                sam_access != NULL ? sam_access->mask : 0));
 
-       sec_len = make_sec_desc(&sec, 1, SEC_DESC_SELF_RELATIVE,
-                               NULL, NULL, NULL, NULL);
+       if((sec = make_sec_desc( 1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, NULL, &sec_len)) == NULL) {
+               DEBUG(0,("make_sec_desc : malloc fail.\n"));
+               return False;
+       }
+
+       DEBUG(10,("make_sec_desc: len = %d\n", (int)sec_len));
+
+       if((sec_buf = make_sec_desc_buf( (int)sec_len, sec)) == NULL) {
+               DEBUG(0,("make_sec_desc : malloc fail (1)\n"));
+               free_sec_desc(&sec);
+               return False;
+       }
+       free_sec_desc(&sec);
 
-       DEBUG(10,("make_sec_desc: len = %d\n", sec_len));
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
-       make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access,
-                             &sec_buf, sec_len, &sec);
+       init_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, sec_buf);
 
        /* turn parameters into data stream */
-       reg_io_q_create_key("", &q_o, &buf, 0);
+       if(!reg_io_q_create_key("", &q_o, &buf, 0)) {
+               free_sec_desc_buf(&sec_buf);
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_CREATE_KEY, &buf, &rbuf))
-       {
-               REG_R_CREATE_KEY r_o;
-               BOOL p;
+       if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf)) {
+               free_sec_desc_buf(&sec_buf);
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       free_sec_desc_buf(&sec_buf);
+       prs_mem_free(&buf);
 
-               reg_io_r_create_key("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_create_key("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_create = True;
-                       memcpy(key, r_o.key_pol.data, sizeof(key->data));
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       free_sec_desc(&sec);
+       memcpy(key, r_o.key_pol.data, sizeof(key->data));
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_create;
+       return True;
 }
 
 /****************************************************************************
 do a REG Enum Key
 ****************************************************************************/
-BOOL reg_enum_key( POLICY_HND *hnd,
+BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
                                int key_index, char *key_name,
                                uint32 *unk_1, uint32 *unk_2,
                                time_t *mod_time)
@@ -840,116 +779,122 @@ BOOL reg_enum_key( POLICY_HND *hnd,
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_ENUM_KEY q_o;
-       BOOL valid_query = False;
+       REG_R_ENUM_KEY r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_ENUM_KEY */
 
        DEBUG(4,("REG Enum Key\n"));
 
-       make_reg_q_enum_key(&q_o, hnd, key_index);
+       init_reg_q_enum_key(&q_o, hnd, key_index);
 
        /* turn parameters into data stream */
-       reg_io_q_enum_key("", &q_o, &buf, 0);
+       if(!reg_io_q_enum_key("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_ENUM_KEY, &buf, &rbuf))
-       {
-               REG_R_ENUM_KEY r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_enum_key("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_enum_key("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-                       (*unk_1) = r_o.unknown_1;
-                       (*unk_2) = r_o.unknown_2;
-                       unistr_to_ascii(key_name, r_o.key_name.str.buffer,
-                                       sizeof(fstring)-1);
-                       (*mod_time) = nt_time_to_unix(&r_o.time);
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       (*unk_1) = r_o.unknown_1;
+       (*unk_2) = r_o.unknown_2;
+       fstrcpy(key_name, dos_unistr2(r_o.key_name.str.buffer));
+       (*mod_time) = nt_time_to_unix(&r_o.time);
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Create Value
 ****************************************************************************/
-BOOL reg_create_val( POLICY_HND *hnd,
+BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
                                char *val_name, uint32 type, BUFFER3 *data)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_CREATE_VALUE q_o;
-       BOOL valid_create = False;
+       REG_R_CREATE_VALUE r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_CREATE_VALUE */
 
        DEBUG(4,("REG Create Value: %s\n", val_name));
 
-       make_reg_q_create_val(&q_o, hnd, val_name, type, data);
+       init_reg_q_create_val(&q_o, hnd, val_name, type, data);
 
        /* turn parameters into data stream */
-       reg_io_q_create_val("", &q_o, &buf, 0);
+       if(!reg_io_q_create_val("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_CREATE_VALUE, &buf, &rbuf))
-       {
-               REG_R_CREATE_VALUE r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               ZERO_STRUCT(r_o);
+       prs_mem_free(&buf);
 
-               reg_io_r_create_val("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       ZERO_STRUCT(r_o);
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!reg_io_r_create_val("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_create = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_create;
+       return True;
 }
 
 /****************************************************************************
 do a REG Enum Value
 ****************************************************************************/
-BOOL reg_enum_val( POLICY_HND *hnd,
+BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
                                int val_index, int max_valnamelen, int max_valbufsize,
                                fstring val_name,
                                uint32 *val_type, BUFFER2 *value)
@@ -957,253 +902,185 @@ BOOL reg_enum_val( POLICY_HND *hnd,
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_ENUM_VALUE q_o;
-       BOOL valid_query = False;
+       REG_R_ENUM_VALUE r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_ENUM_VALUE */
 
        DEBUG(4,("REG Enum Value\n"));
 
-       make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
+       init_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
 
        /* turn parameters into data stream */
-       reg_io_q_enum_val("", &q_o, &buf, 0);
+       if(!reg_io_q_enum_val("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_ENUM_VALUE, &buf, &rbuf))
-       {
-               REG_R_ENUM_VALUE r_o;
-               BOOL p;
-
-               ZERO_STRUCT(r_o);
-               r_o.buf_value = value;
-
-               reg_io_r_enum_val("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if (!rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p)
-               {
-                       valid_query = True;
-                       (*val_type) = r_o.type;
-                       unistr2_to_ascii(val_name, &r_o.uni_name, sizeof(fstring)-1);
-               }
+       prs_mem_free(&buf);
+
+       ZERO_STRUCT(r_o);
+       r_o.buf_value = value;
+
+       if(!reg_io_r_enum_val("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       (*val_type) = r_o.type;
+       fstrcpy(val_name, dos_unistr2_to_str(&r_o.uni_name));
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
 do a REG Open Key
 ****************************************************************************/
-BOOL reg_open_entry( POLICY_HND *hnd,
+BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
                                char *key_name, uint32 unk_0,
                                POLICY_HND *key_hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_OPEN_ENTRY q_o;
-       BOOL valid_pol = False;
+       REG_R_OPEN_ENTRY r_o;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api REG_OPEN_ENTRY */
 
        DEBUG(4,("REG Open Entry\n"));
 
-       make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
+       init_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
 
        /* turn parameters into data stream */
-       reg_io_q_open_entry("", &q_o, &buf, 0);
+       if(!reg_io_q_open_entry("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_OPEN_ENTRY, &buf, &rbuf))
-       {
-               REG_R_OPEN_ENTRY r_o;
-               BOOL p;
-
-               ZERO_STRUCT(r_o);
-
-               reg_io_r_open_entry("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       if (!rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&buf);
 
-               if (p)
-               {
-                       struct cli_connection *con = NULL;
+       ZERO_STRUCT(r_o);
 
-                       if (!cli_connection_get(hnd, &con))
-                       {
-                               return False;
-                       }
+       if(!reg_io_r_open_entry("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-                       memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
-                       valid_pol = cli_pol_link(key_hnd, hnd);
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
        }
 
+       memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
+
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
 
-       return valid_pol;
+       return True;
 }
 
 /****************************************************************************
 do a REG Close
 ****************************************************************************/
-BOOL reg_close( POLICY_HND *hnd)
+BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
        REG_Q_CLOSE q_c;
-       BOOL valid_close = False;
+       REG_R_CLOSE r_c;
+       int i;
 
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
        /* create and send a MSRPC command with api REG_CLOSE */
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL);
 
        DEBUG(4,("REG Close\n"));
 
        /* store the parameters */
-       make_reg_q_close(&q_c, hnd);
+       init_reg_q_close(&q_c, hnd);
 
        /* turn parameters into data stream */
-       reg_io_q_close("", &q_c, &buf, 0);
+       if(!reg_io_q_close("", &q_c, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, REG_CLOSE, &buf, &rbuf))
-       {
-               REG_R_CLOSE r_c;
-               BOOL p;
-
-               ZERO_STRUCT(r_c);
-
-               reg_io_r_close("", &r_c, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_c.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       /* check that the returned policy handle is all zeros */
-                       uint32 i;
-                       valid_close = True;
-
-                       for (i = 0; i < sizeof(r_c.pol.data); i++)
-                       {
-                               if (r_c.pol.data[i] != 0)
-                               {
-                                       valid_close = False;
-                                       break;
-                               }
-                       }       
-                       if (!valid_close)
-                       {
-                               DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
-                       }
-               }
+       if (!rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       close_policy_hnd(hnd);
-
-       return valid_close;
-}
-
-/****************************************************************************
-do a REG Shutdown Server
-****************************************************************************/
-BOOL reg_shutdown(const char *srv_name,
-                       const char *msg, uint32 timeout, uint16 flags)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       REG_Q_SHUTDOWN q_o;
-       BOOL valid_shutdown = False;
+       prs_mem_free(&buf);
 
-       struct cli_connection *con = NULL;
+       ZERO_STRUCT(r_c);
 
-       if (!cli_connection_init(srv_name, PIPE_LSARPC, &con))
-       {
+       if(!reg_io_r_close("", &r_c, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
                return False;
        }
 
-       if (msg == NULL) return False;
-
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api REG_SHUTDOWN */
-
-       DEBUG(4,("REG Shutdown: (timeout: %d secs) %s\n", timeout, msg));
-
-       make_reg_q_shutdown(&q_o, msg, timeout, flags);
-
-       /* turn parameters into data stream */
-       reg_io_q_shutdown("", &q_o, &buf, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, REG_SHUTDOWN, &buf, &rbuf))
-       {
-               REG_R_SHUTDOWN r_o;
-               BOOL p;
-
-               ZERO_STRUCT(r_o);
-
-               reg_io_r_shutdown("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
+       if (r_c.status != 0) {
+               /* report error code */
+               DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("REG_SHUTDOWN: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       /* check that the returned policy handle is all zeros */
 
-               if (p)
-               {
-                       valid_shutdown = True;
+       for (i = 0; i < sizeof(r_c.pol.data); i++) {
+               if (r_c.pol.data[i] != 0) {
+                       prs_mem_free(&rbuf);
+                       DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
+                       return False;
                }
-       }
+       }       
 
        prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       cli_connection_unlink(con);
 
-       return valid_shutdown;
+       return True;
 }
-
-
index 9a68016c666902875453a48b949319db356de0f9..8fccf6c7962299f11151bcb48f044316ba2efdb7 100644 (file)
@@ -4,6 +4,7 @@
    NT Domain Authentication SMB / MSRPC client
    Copyright (C) Andrew Tridgell 1994-1997
    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+   Copyright (C) Jeremy Allison 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
 extern int DEBUGLEVEL;
 
 /****************************************************************************
-do a SAMR change user password command
-****************************************************************************/
-BOOL samr_chgpasswd_user( struct cli_connection *con, 
-               char *srv_name, char *user_name,
-               char nt_newpass[516], uchar nt_oldhash[16],
-               char lm_newpass[516], uchar lm_oldhash[16])
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_CHGPASSWD_USER q_e;
-       BOOL valid_pwc = False;
-
-       /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
-               srv_name, user_name));
-
-       make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
-                                  nt_newpass, nt_oldhash,
-                                  lm_newpass, lm_oldhash);
-
-       /* turn parameters into data stream */
-       samr_io_q_chgpasswd_user("", &q_e, &data, 0);
-
-       dbgflush();
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SAMR_CHGPASSWD_USER, &data, &rdata))
-       {
-               SAMR_R_CHGPASSWD_USER r_e;
-               BOOL p;
-
-               samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
-
-               p = rdata.offset != 0;
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pwc = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pwc;
-}
-
-
-/****************************************************************************
-do a SAMR unknown 0x38 command
-****************************************************************************/
-BOOL samr_unknown_38(struct cli_connection *con, char *srv_name)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_UNKNOWN_38 q_e;
-       BOOL valid_un8 = False;
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
-
-       make_samr_q_unknown_38(&q_e, srv_name);
-
-       /* turn parameters into data stream */
-       samr_io_q_unknown_38("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SAMR_GET_DOM_PWINFO, &data, &rdata))
-       {
-               SAMR_R_UNKNOWN_38 r_e;
-               BOOL p;
-
-               samr_io_r_unknown_38("", &r_e, &rdata, 0);
-
-               p = rdata.offset != 0;
-#if 0
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
-                       p = False;
-               }
-#endif
-               if (p)
-               {
-                       valid_un8 = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_un8;
-}
-
-/****************************************************************************
-do a SAMR unknown 0x8 command
-****************************************************************************/
-BOOL samr_query_dom_info(  POLICY_HND *domain_pol, uint16 switch_value,
-                               SAM_UNK_CTR *ctr)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_QUERY_DOMAIN_INFO q_e;
-       BOOL valid_un8 = False;
-
-       DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
-
-       if (domain_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
-
-       /* turn parameters into data stream */
-       samr_io_q_query_dom_info("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
-       {
-               SAMR_R_QUERY_DOMAIN_INFO r_e;
-               BOOL p;
-
-               r_e.ctr = ctr;
-               samr_io_r_query_dom_info("", &r_e, &rdata, 0);
-
-               p = rdata.offset != 0;
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_un8 = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_un8;
-}
-
-/****************************************************************************
-do a SAMR enumerate Domains
-****************************************************************************/
-uint32 samr_enum_domains(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_domains)
-{
-       uint32 status = 0x0;
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ENUM_DOMAINS q_e;
-
-       DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
-
-       if (pol == NULL || num_sam_domains == NULL || sam == NULL)
-       {
-               return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-       }
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOMAINS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_enum_domains(&q_e, pol, *start_idx, size);
-
-       /* turn parameters into data stream */
-       samr_io_q_enum_domains("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOMAINS, &data, &rdata))
-       {
-               SAMR_R_ENUM_DOMAINS r_e;
-               BOOL p;
-
-               samr_io_r_enum_domains("", &r_e, &rdata, 0);
-
-               status = r_e.status;
-               p = rdata.offset != 0;
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ENUM_DOMAINS: %s\n", get_nt_error_msg(r_e.status)));
-                       p = (r_e.status == STATUS_MORE_ENTRIES);
-               }
-
-               if (p)
-               {
-                       uint32 i = (*num_sam_domains);
-                       uint32 j = 0;
-                       uint32 name_idx = 0;
-
-                       (*num_sam_domains) += r_e.num_entries2;
-                       (*sam) = (struct acct_info*) Realloc((*sam),
-                              sizeof(struct acct_info) * (*num_sam_domains));
-                                   
-                       if ((*sam) == NULL)
-                       {
-                               (*num_sam_domains) = 0;
-                               i = 0;
-                       }
-
-                       for (j = 0; i < (*num_sam_domains) && j < r_e.num_entries2; j++, i++)
-                       {
-                               (*sam)[i].rid = r_e.sam[j].rid;
-                               (*sam)[i].acct_name[0] = 0;
-                               (*sam)[i].acct_desc[0] = 0;
-                               if (r_e.sam[j].hdr_name.buffer)
-                               {
-                                       unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_dom_name[name_idx], sizeof((*sam)[i].acct_name)-1);
-                                       name_idx++;
-                               }
-                               DEBUG(5,("samr_enum_domains: idx: %4d rid: %8x acct: %s\n",
-                                         i, (*sam)[i].rid, (*sam)[i].acct_name));
-                       }
-                       (*start_idx) = r_e.next_idx;
-               }
-               else if (status == 0x0)
-               {
-                       status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-               }
-
-               if (r_e.sam != NULL)
-               {
-                       free(r_e.sam);
-               }
-               if (r_e.uni_dom_name != NULL)
-               {
-                       free(r_e.uni_dom_name);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return status;
-}
-
-/****************************************************************************
-do a SAMR enumerate groups
-****************************************************************************/
-uint32 samr_enum_dom_groups(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_groups)
-{
-       uint32 status = 0x0;
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ENUM_DOM_GROUPS q_e;
-
-       DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
-
-       if (pol == NULL || num_sam_groups == NULL)
-       {
-               return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-       }
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOM_GROUPS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_enum_dom_groups(&q_e, pol, *start_idx, size);
-
-       /* turn parameters into data stream */
-       samr_io_q_enum_dom_groups("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_GROUPS, &data, &rdata))
-       {
-               SAMR_R_ENUM_DOM_GROUPS r_e;
-               BOOL p;
-
-               samr_io_r_enum_dom_groups("", &r_e, &rdata, 0);
-
-               status = r_e.status;
-               p = rdata.offset != 0;
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ENUM_DOM_GROUPS: %s\n", get_nt_error_msg(r_e.status)));
-                       p = (r_e.status == STATUS_MORE_ENTRIES);
-               }
-
-               if (p)
-               {
-                       uint32 i = (*num_sam_groups);
-                       uint32 j = 0;
-                       uint32 name_idx = 0;
-
-                       (*num_sam_groups) += r_e.num_entries2;
-                       (*sam) = (struct acct_info*) Realloc((*sam),
-                              sizeof(struct acct_info) * (*num_sam_groups));
-                                   
-                       if ((*sam) == NULL)
-                       {
-                               (*num_sam_groups) = 0;
-                               i = 0;
-                       }
-
-                       for (j = 0; i < (*num_sam_groups) && j < r_e.num_entries2; j++, i++)
-                       {
-                               (*sam)[i].rid = r_e.sam[j].rid;
-                               (*sam)[i].acct_name[0] = 0;
-                               (*sam)[i].acct_desc[0] = 0;
-                               if (r_e.sam[j].hdr_name.buffer)
-                               {
-                                       unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
-                                       name_idx++;
-                               }
-                               DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s\n",
-                                         i, (*sam)[i].rid, (*sam)[i].acct_name));
-                       }
-                       (*start_idx) = r_e.next_idx;
-               }
-               else if (status == 0x0)
-               {
-                       status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-               }
-
-               if (r_e.sam != NULL)
-               {
-                       free(r_e.sam);
-               }
-               if (r_e.uni_grp_name != NULL)
-               {
-                       free(r_e.uni_grp_name);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return status;
-}
-
-/****************************************************************************
-do a SAMR enumerate aliases
-****************************************************************************/
-uint32 samr_enum_dom_aliases(  POLICY_HND *pol,
-                               uint32 *start_idx, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_aliases)
-{
-       uint32 status = 0x0;
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ENUM_DOM_ALIASES q_e;
-
-       DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
-
-       if (pol == NULL || num_sam_aliases == NULL)
-       {
-               return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-       }
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOM_ALIASES */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_enum_dom_aliases(&q_e, pol, *start_idx, size);
-
-       /* turn parameters into data stream */
-       samr_io_q_enum_dom_aliases("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_ALIASES, &data, &rdata))
-       {
-               SAMR_R_ENUM_DOM_ALIASES r_e;
-               BOOL p;
-
-               samr_io_r_enum_dom_aliases("", &r_e, &rdata, 0);
-
-               p = rdata.offset != 0;
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ENUM_DOM_ALIASES: %s\n", get_nt_error_msg(r_e.status)));
-                       p = (r_e.status == STATUS_MORE_ENTRIES);
-               }
-
-               if (p)
-               {
-                       uint32 i = (*num_sam_aliases);
-                       uint32 j = 0;
-                       uint32 name_idx = 0;
-
-                       (*num_sam_aliases) += r_e.num_entries2;
-                       (*sam) = (struct acct_info*) Realloc((*sam),
-                              sizeof(struct acct_info) * (*num_sam_aliases));
-                                   
-                       if ((*sam) == NULL)
-                       {
-                               (*num_sam_aliases) = 0;
-                               i = 0;
-                       }
-
-                       for (j = 0; i < (*num_sam_aliases) && j < r_e.num_entries2; j++, i++)
-                       {
-                               (*sam)[i].rid = r_e.sam[j].rid;
-                               (*sam)[i].acct_name[0] = 0;
-                               (*sam)[i].acct_desc[0] = 0;
-                               if (r_e.sam[j].hdr_name.buffer)
-                               {
-                                       unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
-                                       name_idx++;
-                               }
-                               DEBUG(5,("samr_enum_dom_aliases: idx: %4d rid: %8x acct: %s\n",
-                                         i, (*sam)[i].rid, (*sam)[i].acct_name));
-                       }
-                       (*start_idx) = r_e.next_idx;
-               }
-               else if (status == 0x0)
-               {
-                       status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-               }
-
-               if (r_e.sam != NULL)
-               {
-                       free(r_e.sam);
-               }
-               if (r_e.uni_grp_name != NULL)
-               {
-                       free(r_e.uni_grp_name);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return status;
-}
-
-/****************************************************************************
-do a SAMR enumerate users
-****************************************************************************/
-uint32 samr_enum_dom_users(  POLICY_HND *pol, uint32 *start_idx, 
-                               uint16 acb_mask, uint16 unk_1, uint32 size,
-                               struct acct_info **sam,
-                               uint32 *num_sam_users)
-{
-       uint32 status = 0x0;
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ENUM_DOM_USERS q_e;
-
-       DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
-
-       if (pol == NULL || num_sam_users == NULL)
-       {
-               return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-       }
-
-       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_enum_dom_users(&q_e, pol, *start_idx,
-                                  acb_mask, unk_1, size);
-
-       /* turn parameters into data stream */
-       samr_io_q_enum_dom_users("", &q_e, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_USERS, &data, &rdata))
-       {
-               SAMR_R_ENUM_DOM_USERS r_e;
-               BOOL p;
-
-               samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
-
-               status = r_e.status;
-               p = rdata.offset != 0;
-
-               if (p && r_e.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
-                       p = (r_e.status == STATUS_MORE_ENTRIES);
-               }
-
-               if (p)
-               {
-                       uint32 i = (*num_sam_users);
-                       uint32 j = 0;
-                       uint32 name_idx = 0;
-
-                       (*num_sam_users) += r_e.num_entries2;
-                       (*sam) = (struct acct_info*) Realloc((*sam),
-                              sizeof(struct acct_info) * (*num_sam_users));
-                                   
-                       if ((*sam) == NULL)
-                       {
-                               (*num_sam_users) = 0;
-                               i = 0;
-                       }
-
-                       for (j = 0; i < (*num_sam_users) && j < r_e.num_entries2; j++, i++)
-                       {
-                               (*sam)[i].rid = r_e.sam[j].rid;
-                               (*sam)[i].acct_name[0] = 0;
-                               (*sam)[i].acct_desc[0] = 0;
-                               if (r_e.sam[j].hdr_name.buffer)
-                               {
-                                       unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_acct_name[name_idx], sizeof((*sam)[i].acct_name)-1);
-                                       name_idx++;
-                               }
-                               DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
-                                         i, (*sam)[i].rid, (*sam)[i].acct_name));
-                       }
-                       (*start_idx) = r_e.next_idx;
-               }
-               else if (status == 0x0)
-               {
-                       status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-               }
-
-               if (r_e.sam != NULL)
-               {
-                       free(r_e.sam);
-               }
-               if (r_e.uni_acct_name != NULL)
-               {
-                       free(r_e.uni_acct_name);
-               }
-       }
-       else
-       {
-               status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return status;
-}
-
-/****************************************************************************
-do a SAMR Connect
-****************************************************************************/
-BOOL samr_connect(  const char *srv_name, uint32 unknown_0,
-                               POLICY_HND *connect_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_CONNECT q_o;
-       BOOL valid_pol = False;
-
-       struct cli_connection *con = NULL;
-
-       if (!cli_connection_init(srv_name, PIPE_SAMR, &con))
-       {
-               return False;
-       }
-
-       DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
-                               srv_name, unknown_0));
-
-       if (srv_name == NULL || connect_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_CONNECT */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_connect(&q_o, srv_name, unknown_0);
-
-       /* turn parameters into data stream */
-       samr_io_q_connect("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SAMR_CONNECT, &data, &rdata))
-       {
-               SAMR_R_CONNECT r_o;
-               BOOL p;
-
-               samr_io_r_connect("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
-                       valid_pol = register_policy_hnd(connect_pol) &&
-                                   set_policy_con(connect_pol, con,
-                                                        cli_connection_unlink);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Open User
-****************************************************************************/
-BOOL samr_open_user(  const POLICY_HND *pol,
-                               uint32 unk_0, uint32 rid, 
-                               POLICY_HND *user_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_OPEN_USER q_o;
-       BOOL valid_pol = False;
-
-       DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
-                 unk_0, rid));
-
-       if (pol == NULL || user_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_OPEN_USER */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_open_user(&q_o, pol, unk_0, rid);
-
-       /* turn parameters into data stream */
-       samr_io_q_open_user("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_OPEN_USER, &data, &rdata))
-       {
-               SAMR_R_OPEN_USER r_o;
-               BOOL p;
-
-               samr_io_r_open_user("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
-                       valid_pol = cli_pol_link(user_pol, pol);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Open Alias
-****************************************************************************/
-BOOL samr_open_alias(  const POLICY_HND *domain_pol,
-                               uint32 flags, uint32 rid,
-                               POLICY_HND *alias_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_OPEN_ALIAS q_o;
-       BOOL valid_pol = False;
-
-       DEBUG(4,("SAMR Open Alias. RID:%x\n", rid));
-
-       if (alias_pol == NULL || domain_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_open_alias(&q_o, domain_pol, flags, rid);
-
-       /* turn parameters into data stream */
-       samr_io_q_open_alias("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_ALIAS, &data, &rdata))
-       {
-               SAMR_R_OPEN_ALIAS r_o;
-               BOOL p;
-
-               samr_io_r_open_alias("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol));
-                       valid_pol = cli_pol_link(alias_pol, domain_pol);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Delete Alias Member
-****************************************************************************/
-BOOL samr_del_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_DEL_ALIASMEM q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL || sid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Delete Alias Member.\n"));
-
-       /* store the parameters */
-       make_samr_q_del_aliasmem(&q_o, alias_pol, sid);
-
-       /* turn parameters into data stream */
-       samr_io_q_del_aliasmem("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_DEL_ALIASMEM, &data, &rdata))
-       {
-               SAMR_R_DEL_ALIASMEM r_o;
-               BOOL p;
-
-               samr_io_r_del_aliasmem("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Add Alias Member
-****************************************************************************/
-BOOL samr_add_aliasmem(  POLICY_HND *alias_pol, DOM_SID *sid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ADD_ALIASMEM q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL || sid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_ADD_ALIASMEM */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Add Alias Member.\n"));
-
-       /* store the parameters */
-       make_samr_q_add_aliasmem(&q_o, alias_pol, sid);
-
-       /* turn parameters into data stream */
-       samr_io_q_add_aliasmem("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_ADD_ALIASMEM, &data, &rdata))
-       {
-               SAMR_R_ADD_ALIASMEM r_o;
-               BOOL p;
-
-               samr_io_r_add_aliasmem("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ADD_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Delete Domain Alias
-****************************************************************************/
-BOOL samr_delete_dom_alias(  POLICY_HND *alias_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_DELETE_DOM_ALIAS q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL) return False;
-
-       /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Delete Domain Alias.\n"));
-
-       /* store the parameters */
-       make_samr_q_delete_dom_alias(&q_o, alias_pol);
-
-       /* turn parameters into data stream */
-       samr_io_q_delete_dom_alias("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_DELETE_DOM_ALIAS, &data, &rdata))
-       {
-               SAMR_R_DELETE_DOM_ALIAS r_o;
-               BOOL p;
-
-               samr_io_r_delete_dom_alias("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Create Domain User
-****************************************************************************/
-uint32 samr_create_dom_user(  POLICY_HND *domain_pol, const char *acct_name,
-                               uint32 unk_0, uint32 unk_1,
-                               POLICY_HND *user_pol, uint32 *rid)
-{
-       prs_struct data;
-       prs_struct rdata;
-       uint32 status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
-
-       SAMR_Q_CREATE_USER q_o;
-
-       if (user_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_CREATE_USER */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Create Domain User. Name:%s\n", acct_name));
-
-       /* store the parameters */
-       make_samr_q_create_user(&q_o, domain_pol, acct_name, unk_0, unk_1);
-
-       /* turn parameters into data stream */
-       samr_io_q_create_user("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_USER, &data, &rdata))
-       {
-               SAMR_R_CREATE_USER r_o;
-               BOOL p;
-
-               samr_io_r_create_user("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               status = r_o.status;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status)));
-                       p = r_o.status != NT_STATUS_USER_EXISTS;
-               }
-
-               if (p)
-               {
-                       memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
-                       *rid = r_o.user_rid;
-                       if (!cli_pol_link(user_pol, domain_pol))
-                       {
-                               status = NT_STATUS_INVALID_HANDLE | 0xC0000000;
-                       }
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return status;
-}
-
-/****************************************************************************
-do a SAMR Create Domain Alias
-****************************************************************************/
-BOOL samr_create_dom_alias(  POLICY_HND *domain_pol, const char *acct_name,
-                               POLICY_HND *alias_pol, uint32 *rid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_CREATE_DOM_ALIAS q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
-
-       /* store the parameters */
-       make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
-
-       /* turn parameters into data stream */
-       samr_io_q_create_dom_alias("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
-       {
-               SAMR_R_CREATE_DOM_ALIAS r_o;
-               BOOL p;
-
-               samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
-                       *rid = r_o.rid;
-                       valid_pol = cli_pol_link(alias_pol, domain_pol);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Get Alias Info
-****************************************************************************/
-BOOL samr_query_aliasinfo(  POLICY_HND *alias_pol, uint16 switch_value,
-                               ALIAS_INFO_CTR *ctr)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_QUERY_ALIASINFO q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL || ctr == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_GET_ALIASINFO */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Get Alias Info\n"));
-
-       /* store the parameters */
-       make_samr_q_query_aliasinfo(&q_o, alias_pol, switch_value);
-
-       /* turn parameters into data stream */
-       samr_io_q_query_aliasinfo("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASINFO, &data, &rdata))
-       {
-               SAMR_R_QUERY_ALIASINFO r_o;
-               BOOL p;
-
-               /* get alias info */
-               r_o.ctr = ctr;
-
-               samr_io_r_query_aliasinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Set Alias Info
-****************************************************************************/
-BOOL samr_set_aliasinfo(  POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_SET_ALIASINFO q_o;
-       BOOL valid_pol = False;
-
-       if (alias_pol == NULL || ctr == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Set Alias Info\n"));
-
-       /* store the parameters */
-       make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
-
-       /* turn parameters into data stream */
-       samr_io_q_set_aliasinfo("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_SET_ALIASINFO, &data, &rdata))
-       {
-               SAMR_R_SET_ALIASINFO r_o;
-               BOOL p;
-
-               samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Open Group
-****************************************************************************/
-BOOL samr_open_group(  const POLICY_HND *domain_pol,
-                               uint32 flags, uint32 rid,
-                               POLICY_HND *group_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_OPEN_GROUP q_o;
-       BOOL valid_pol = False;
-
-       DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
-
-       if (group_pol == NULL || domain_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_open_group(&q_o, domain_pol, flags, rid);
-
-       /* turn parameters into data stream */
-       samr_io_q_open_group("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_GROUP, &data, &rdata))
-       {
-               SAMR_R_OPEN_GROUP r_o;
-               BOOL p;
-
-               samr_io_r_open_group("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
-                       valid_pol = cli_pol_link(group_pol, domain_pol);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Delete Group Member
-****************************************************************************/
-BOOL samr_del_groupmem(  POLICY_HND *group_pol, uint32 rid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_DEL_GROUPMEM q_o;
-       BOOL valid_pol = False;
-
-       if (group_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Delete Group Member.\n"));
-
-       /* store the parameters */
-       make_samr_q_del_groupmem(&q_o, group_pol, rid);
-
-       /* turn parameters into data stream */
-       samr_io_q_del_groupmem("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(group_pol, SAMR_DEL_GROUPMEM, &data, &rdata))
-       {
-               SAMR_R_DEL_GROUPMEM r_o;
-               BOOL p;
-
-               samr_io_r_del_groupmem("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Add Group Member
-****************************************************************************/
-BOOL samr_add_groupmem(  POLICY_HND *group_pol, uint32 rid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_ADD_GROUPMEM q_o;
-       BOOL valid_pol = False;
-
-       if (group_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Add Group Member.\n"));
-
-       /* store the parameters */
-       make_samr_q_add_groupmem(&q_o, group_pol, rid);
-
-       /* turn parameters into data stream */
-       samr_io_q_add_groupmem("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(group_pol, SAMR_ADD_GROUPMEM, &data, &rdata))
-       {
-               SAMR_R_ADD_GROUPMEM r_o;
-               BOOL p;
-
-               samr_io_r_add_groupmem("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Delete Domain Group
-****************************************************************************/
-BOOL samr_delete_dom_group(  POLICY_HND *group_pol)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_DELETE_DOM_GROUP q_o;
-       BOOL valid_pol = False;
-
-       if (group_pol == NULL) return False;
-
-       /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Delete Domain Group.\n"));
-
-       /* store the parameters */
-       make_samr_q_delete_dom_group(&q_o, group_pol);
-
-       /* turn parameters into data stream */
-       samr_io_q_delete_dom_group("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(group_pol, SAMR_DELETE_DOM_GROUP, &data, &rdata))
-       {
-               SAMR_R_DELETE_DOM_GROUP r_o;
-               BOOL p;
-
-               samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Create Domain Group
-****************************************************************************/
-BOOL samr_create_dom_group(  POLICY_HND *domain_pol, const char *acct_name,
-                               POLICY_HND *group_pol, uint32 *rid)
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_CREATE_DOM_GROUP q_o;
-       BOOL valid_pol = False;
-
-       if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
-
-       /* store the parameters */
-       make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
-
-       /* turn parameters into data stream */
-       samr_io_q_create_dom_group("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_GROUP, &data, &rdata))
-       {
-               SAMR_R_CREATE_DOM_GROUP r_o;
-               BOOL p;
-
-               samr_io_r_create_dom_group("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
-                       *rid = r_o.rid;
-                       valid_pol = cli_pol_link(group_pol, domain_pol);
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Set Group Info
+do a SAMR query user groups
 ****************************************************************************/
-BOOL samr_set_groupinfo(  POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
+BOOL get_samr_query_usergroups(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain, uint32 user_rid,
+                               uint32 *num_groups, DOM_GID *gid)
 {
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_SET_GROUPINFO q_o;
-       BOOL valid_pol = False;
-
-       if (group_pol == NULL || ctr == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Set Group Info\n"));
-
-       /* store the parameters */
-       make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
-
-       /* turn parameters into data stream */
-       samr_io_q_set_groupinfo("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(group_pol, SAMR_SET_GROUPINFO, &data, &rdata))
-       {
-               SAMR_R_SET_GROUPINFO r_o;
-               BOOL p;
-
-               samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_pol = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
-}
-
-/****************************************************************************
-do a SAMR Open Domain
-****************************************************************************/
-BOOL samr_open_domain(  const POLICY_HND *connect_pol,
-                               uint32 ace_perms,
-                               const DOM_SID *sid,
-                               POLICY_HND *domain_pol)
-{
-       pstring sid_str;
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_OPEN_DOMAIN q_o;
-       BOOL valid_pol = False;
+       POLICY_HND pol_open_user;
+       if (pol_open_domain == NULL || num_groups == NULL || gid == NULL)
+               return False;
 
-       if (DEBUGLEVEL >= 4)
+       /* send open domain (on user sid) */
+       if (!do_samr_open_user(cli,
+                               pol_open_domain,
+                               0x02011b, user_rid,
+                               &pol_open_user))
        {
-               sid_to_string(sid_str, sid);
-               DEBUG(4,("SAMR Open Domain.  SID:%s Permissions:%x\n",
-                                       sid_str, ace_perms));
+               return False;
        }
 
-       if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* store the parameters */
-       make_samr_q_open_domain(&q_o, connect_pol, ace_perms, sid);
-
-       /* turn parameters into data stream */
-       samr_io_q_open_domain("", &q_o,  &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(connect_pol, SAMR_OPEN_DOMAIN, &data, &rdata))
+       /* send user groups query */
+       if (!do_samr_query_usergroups(cli,
+                               &pol_open_user,
+                               num_groups, gid))
        {
-               SAMR_R_OPEN_DOMAIN r_o;
-               BOOL p;
-
-               samr_io_r_open_domain("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
-                       valid_pol = cli_pol_link(domain_pol, connect_pol);
-               }
+               DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_pol;
+       return do_samr_close(cli, &pol_open_user);
 }
 
 /****************************************************************************
-do a SAMR Query Lookup Domain
+do a SAMR query user info
 ****************************************************************************/
-BOOL samr_query_lookup_domain(  POLICY_HND *pol, const char *dom_name,
-                             DOM_SID *dom_sid)
+BOOL get_samr_query_userinfo(struct cli_state *cli, 
+                               POLICY_HND *pol_open_domain,
+                               uint32 info_level,
+                               uint32 user_rid, SAM_USER_INFO_21 *usr)
 {
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_LOOKUP_DOMAIN q_o;
-       BOOL valid_query = False;
-
-       if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False;
-
-       /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Query Lookup Domain.\n"));
-
-       /* store the parameters */
-       make_samr_q_lookup_domain(&q_o, pol, dom_name);
+       POLICY_HND pol_open_user;
+       if (pol_open_domain == NULL || usr == NULL)
+               return False;
 
-       /* turn parameters into data stream */
-       samr_io_q_lookup_domain("", &q_o, &data, 0);
+       memset((char *)usr, '\0', sizeof(*usr));
 
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_DOMAIN, &data, &rdata))
+       /* send open domain (on user sid) */
+       if (!do_samr_open_user(cli,
+                               pol_open_domain,
+                               0x02011b, user_rid,
+                               &pol_open_user))
        {
-               SAMR_R_LOOKUP_DOMAIN r_o;
-               BOOL p;
-
-               samr_io_r_lookup_domain("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p && r_o.ptr_sid != 0)
-               {
-                       sid_copy(dom_sid, &r_o.dom_sid.sid);
-                       valid_query = True;
-               }
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_query;
-}
-
-/****************************************************************************
-do a SAMR Query Lookup Names
-****************************************************************************/
-BOOL samr_query_lookup_names(  POLICY_HND *pol, uint32 flags,
-                               uint32 num_names, char **names,
-                               uint32 *num_rids,
-                               uint32 rid[MAX_LOOKUP_SIDS],
-                               uint32 type[MAX_LOOKUP_SIDS])
-{
-       prs_struct data;
-       prs_struct rdata;
-
-       SAMR_Q_LOOKUP_NAMES q_o;
-       BOOL valid_query = False;
-
-       if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
-           num_rids == NULL || rid == NULL || type == NULL ) return False;
-
-       /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       DEBUG(4,("SAMR Query Lookup NAMES.\n"));
-
-       /* store the parameters */
-       make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
-
-       /* turn parameters into data stream */
-       samr_io_q_lookup_names("", &q_o, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_NAMES, &data, &rdata))
+       /* send user info query */
+       if (!do_samr_query_userinfo(cli,
+                               &pol_open_user,
+                               info_level, (void*)usr))
        {
-               SAMR_R_LOOKUP_NAMES r_o;
-               BOOL p;
-
-               samr_io_r_lookup_names("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
-                       p = r_o.status == 0x107;
-               }
-
-               if (p)
-               {
-                       if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
-                           r_o.num_types1 == r_o.num_rids1)
-                       {
-                               uint32 i;
-
-                               valid_query = True;
-                               *num_rids = r_o.num_rids1;
-
-                               for (i = 0; i < r_o.num_rids1; i++)
-                               {
-                                       rid[i] = r_o.rid[i];
-                               }
-                               for (i = 0; i < r_o.num_types1; i++)
-                               {
-                                       type[i] = r_o.type[i];
-                               }
-                       }
-                       else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
-                       {
-                               valid_query = True;
-                               *num_rids = 0;
-                       }
-                       else
-                       {
-                               p = False;
-                       }
-               }
+               DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
+                         info_level));
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-
-       return valid_query;
+       return do_samr_close(cli, &pol_open_user);
 }
 
 /****************************************************************************
-do a SAMR Query Lookup RIDS
+do a SAMR change user password command
 ****************************************************************************/
-BOOL samr_query_lookup_rids(  const POLICY_HND *pol, uint32 flags,
-                               uint32 num_rids, uint32 *rids,
-                               uint32 *num_names,
-                               char   ***names,
-                               uint32 **type)
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+               char *srv_name, char *user_name,
+               char nt_newpass[516], uchar nt_oldhash[16],
+               char lm_newpass[516], uchar lm_oldhash[16])
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_CHGPASSWD_USER q_e;
+       SAMR_R_CHGPASSWD_USER r_e;
 
-       SAMR_Q_LOOKUP_RIDS q_o;
-       BOOL valid_query = False;
-
-       if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL ||
-           num_names == NULL || names == NULL || type == NULL ) return False;
-
-       /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */
+       /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       DEBUG(4,("SAMR Query Lookup RIDs.\n"));
+       DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
+               srv_name, user_name));
 
-       /* store the parameters */
-       make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids);
+       init_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
+                                  nt_newpass, nt_oldhash,
+                                  lm_newpass, lm_oldhash);
 
        /* turn parameters into data stream */
-       samr_io_q_lookup_rids("", &q_o,  &data, 0);
+       if(!samr_io_q_chgpasswd_user("", &q_e, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_RIDS, &data, &rdata))
-       {
-               SAMR_R_LOOKUP_RIDS r_o;
-               BOOL p;
-               ZERO_STRUCT(r_o);
+       if (!rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_lookup_rids("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&data);
 
-               if (p)
-               {
-                       if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
-                           r_o.num_types1 == r_o.num_names1)
-                       {
-                               uint32 i;
-                               valid_query = True;
-
-                               (*num_names) = 0;
-                               (*names) = NULL;
-
-                               for (i = 0; i < r_o.num_names1; i++)
-                               {
-                                       fstring tmp;
-                                       unistr2_to_ascii(tmp, &r_o.uni_name[i], sizeof(tmp)-1);
-                                       add_chars_to_array(num_names, names, tmp);
-                               }
-
-                               if ((*num_names) != 0)
-                               {
-                                       (*type) = (uint32*)malloc((*num_names) * sizeof(**type));
-                               }
-
-                               for (i = 0; (*type) != NULL && i < r_o.num_types1; i++)
-                               {
-                                       (*type)[i] = r_o.type[i];
-                               }
-                       }
-                       else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
-                       {
-                               valid_query = True;
-                               *num_names = 0;
-                               *names = NULL;
-                               *type = NULL;
-                       }
-                       else
-                       {
-                               p = False;
-                       }
-               }
+       if(!samr_io_r_chgpasswd_user("", &r_e, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_free_r_lookup_rids(&r_o);
+       if (r_e.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query Alias Members
+do a SAMR unknown 0x38 command
 ****************************************************************************/
-BOOL samr_query_aliasmem(  const POLICY_HND *alias_pol, 
-                               uint32 *num_mem, DOM_SID2 *sid)
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name)
 {
        prs_struct data;
        prs_struct rdata;
 
-       SAMR_Q_QUERY_ALIASMEM q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query Alias Members.\n"));
+       SAMR_Q_UNKNOWN_38 q_e;
+       SAMR_R_UNKNOWN_38 r_e;
 
-       if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False;
+       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
 
-       /* store the parameters */
-       make_samr_q_query_aliasmem(&q_o, alias_pol);
+       init_samr_q_unknown_38(&q_e, srv_name);
 
        /* turn parameters into data stream */
-       samr_io_q_query_aliasmem("", &q_o,  &data, 0);
+       if(!samr_io_q_unknown_38("", &q_e, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASMEM, &data, &rdata))
-       {
-               SAMR_R_QUERY_ALIASMEM r_o;
-               BOOL p;
-
-               /* get user info */
-               r_o.sid = sid;
+       if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_query_aliasmem("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&data);
 
-               if (p && r_o.ptr != 0)
-               {
-                       valid_query = True;
-                       *num_mem = r_o.num_sids;
-               }
+       if(!samr_io_r_unknown_38("", &r_e, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
 
+       if (r_e.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query User Aliases
+do a SAMR unknown 0x8 command
 ****************************************************************************/
-BOOL samr_query_useraliases(  const POLICY_HND *pol,
-                               uint32 *ptr_sid, DOM_SID2 *sid,
-                               uint32 *num_aliases, uint32 **rid)
+BOOL do_samr_query_dom_info(struct cli_state *cli, 
+                               POLICY_HND *domain_pol, uint16 switch_value)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_QUERY_DOMAIN_INFO q_e;
+       SAMR_R_QUERY_DOMAIN_INFO r_e;
 
-       SAMR_Q_QUERY_USERALIASES q_o;
-       BOOL valid_query = False;
-       ZERO_STRUCT(q_o);
-
-       DEBUG(4,("SAMR Query User Aliases.\n"));
+       if (domain_pol == NULL)
+               return False;
 
-       if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
+       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
 
        /* store the parameters */
-       make_samr_q_query_useraliases(&q_o, pol, ptr_sid, sid);
+       init_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
 
        /* turn parameters into data stream */
-       samr_io_q_query_useraliases("", &q_o,  &data, 0);
+       if(!samr_io_q_query_dom_info("", &q_e, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERALIASES, &data, &rdata))
-       {
-               SAMR_R_QUERY_USERALIASES r_o;
-               BOOL p;
-
-               r_o.rid = NULL;
+       if (!rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_query_useraliases("", &r_o, &rdata, 0);
-               *rid = r_o.rid;
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&data);
 
-               if (p && r_o.ptr != 0)
-               {
-                       valid_query = True;
-                       *num_aliases = r_o.num_entries;
-               }
+       if(!samr_io_r_query_dom_info("", &r_e, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
 
+       if (r_e.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query Group Members
+do a SAMR enumerate users
 ****************************************************************************/
-BOOL samr_query_groupmem(  POLICY_HND *group_pol, 
-                               uint32 *num_mem, uint32 **rid, uint32 **attr)
+BOOL do_samr_enum_dom_users(struct cli_state *cli, 
+                               POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+                               uint16 acb_mask, uint16 unk_1, uint32 size,
+                               struct acct_info **sam,
+                               int *num_sam_users)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_ENUM_DOM_USERS q_e;
+       SAMR_R_ENUM_DOM_USERS r_e;
+       int i;
+       int name_idx = 0;
 
-       SAMR_Q_QUERY_GROUPMEM q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query Group Members.\n"));
+       if (pol == NULL || num_sam_users == NULL)
+               return False;
 
-       if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False;
+       /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
 
        /* store the parameters */
-       make_samr_q_query_groupmem(&q_o, group_pol);
+       init_samr_q_enum_dom_users(&q_e, pol,
+                                  num_entries, unk_0,
+                                  acb_mask, unk_1, size);
 
        /* turn parameters into data stream */
-       samr_io_q_query_groupmem("", &q_o,  &data, 0);
+       if(!samr_io_q_enum_dom_users("", &q_e, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(group_pol, SAMR_QUERY_GROUPMEM, &data, &rdata))
-       {
-               SAMR_R_QUERY_GROUPMEM r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               r_o.rid  = NULL;
-               r_o.attr = NULL;
+       prs_mem_free(&data);
 
-               samr_io_r_query_groupmem("", &r_o, &rdata, 0);
-               *rid  = r_o.rid ;
-               *attr = r_o.attr;
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!samr_io_r_enum_dom_users("", &r_e, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       if (r_e.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       *num_sam_users = r_e.num_entries2;
+       if (*num_sam_users > MAX_SAM_ENTRIES) {
+               *num_sam_users = MAX_SAM_ENTRIES;
+               DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
+                         *num_sam_users));
+       }
+
+       *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
+                                   
+       if ((*sam) == NULL)
+               *num_sam_users = 0;
 
-               if (p && r_o.ptr != 0 &&
-                   r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 &&
-                   r_o.num_rids == r_o.num_attrs)
-               {
-                       valid_query = True;
-                       *num_mem = r_o.num_rids;
+       for (i = 0; i < *num_sam_users; i++) {
+               (*sam)[i].smb_userid = r_e.sam[i].rid;
+               if (r_e.sam[i].hdr_name.buffer) {
+                       char *acct_name = dos_unistrn2(r_e.uni_acct_name[name_idx].buffer,
+                                                  r_e.uni_acct_name[name_idx].uni_str_len);
+                       fstrcpy((*sam)[i].acct_name, acct_name);
+                       name_idx++;
+               } else {
+                       memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name));
                }
 
+               DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
+                         i, (*sam)[i].smb_userid, (*sam)[i].acct_name));
        }
 
-       prs_mem_free(&data   );
        prs_mem_free(&rdata  );
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query User Groups
+do a SAMR Connect
 ****************************************************************************/
-BOOL samr_query_usergroups(  POLICY_HND *pol, uint32 *num_groups,
-                               DOM_GID **gid)
+BOOL do_samr_connect(struct cli_state *cli, 
+                               char *srv_name, uint32 unknown_0,
+                               POLICY_HND *connect_pol)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_CONNECT q_o;
+       SAMR_R_CONNECT r_o;
 
-       SAMR_Q_QUERY_USERGROUPS q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query User Groups.\n"));
+       if (srv_name == NULL || connect_pol == NULL)
+               return False;
 
-       if (pol == NULL || gid == NULL || num_groups == 0) return False;
+       /* create and send a MSRPC command with api SAMR_CONNECT */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
+                               srv_name, unknown_0));
 
        /* store the parameters */
-       make_samr_q_query_usergroups(&q_o, pol);
+       init_samr_q_connect(&q_o, srv_name, unknown_0);
 
        /* turn parameters into data stream */
-       samr_io_q_query_usergroups("", &q_o,  &data, 0);
+       if(!samr_io_q_connect("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERGROUPS, &data, &rdata))
-       {
-               SAMR_R_QUERY_USERGROUPS r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               /* get user info */
-               r_o.gid = NULL;
+       prs_mem_free(&data);
 
-               samr_io_r_query_usergroups("", &r_o, &rdata, 0);
-               *gid = r_o.gid;
-               p = rdata.offset != 0;
+       if(!samr_io_r_connect("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p && r_o.ptr_0 != 0)
-               {
-                       valid_query = True;
-                       *num_groups = r_o.num_entries;
-               }
-
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
 
-       return valid_query;
+       prs_mem_free(&rdata);
+
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query Group Info
+do a SAMR Open User
 ****************************************************************************/
-BOOL samr_query_groupinfo(  POLICY_HND *pol,
-                               uint16 switch_value, GROUP_INFO_CTR* ctr)
+BOOL do_samr_open_user(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 unk_0, uint32 rid, 
+                               POLICY_HND *user_pol)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_OPEN_USER q_o;
+       SAMR_R_OPEN_USER r_o;
 
-       SAMR_Q_QUERY_GROUPINFO q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query Group Info.  level: %d\n", switch_value));
+       if (pol == NULL || user_pol == NULL)
+               return False;
 
-       if (pol == NULL || ctr == NULL || switch_value == 0) return False;
+       /* create and send a MSRPC command with api SAMR_OPEN_USER */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Open User.  unk_0: %08x RID:%x\n",
+                 unk_0, rid));
 
        /* store the parameters */
-       make_samr_q_query_groupinfo(&q_o, pol, switch_value);
+       init_samr_q_open_user(&q_o, pol, unk_0, rid);
 
        /* turn parameters into data stream */
-       samr_io_q_query_groupinfo("", &q_o,  &data, 0);
+       if(!samr_io_q_open_user("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_QUERY_GROUPINFO, &data, &rdata))
-       {
-               SAMR_R_QUERY_GROUPINFO r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               /* get group info */
-               r_o.ctr = ctr;
+       prs_mem_free(&data);
 
-               samr_io_r_query_groupinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
+       if(!samr_io_r_open_user("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p && r_o.ctr->switch_value1 != switch_value)
-               {
-                       DEBUG(4,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n",
-                                 r_o.ctr->switch_value1));
-               }
-
-               if (p && r_o.ptr != 0)
-               {
-                       valid_query = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
+
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Set User Info
+do a SAMR Open Domain
 ****************************************************************************/
-BOOL samr_set_userinfo2(  POLICY_HND *pol, uint16 switch_value,
-                               void* usr)
+BOOL do_samr_open_domain(struct cli_state *cli, 
+                               POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+                               POLICY_HND *domain_pol)
 {
        prs_struct data;
        prs_struct rdata;
+       pstring sid_str;
+       SAMR_Q_OPEN_DOMAIN q_o;
+       SAMR_R_OPEN_DOMAIN r_o;
 
-       SAMR_Q_SET_USERINFO2 q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Set User Info 2.  level: %d\n", switch_value));
+       if (connect_pol == NULL || sid == NULL || domain_pol == NULL)
+               return False;
 
-       if (pol == NULL || usr == NULL || switch_value == 0) return False;
+       /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
 
-       /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       sid_to_string(sid_str, sid);
+       DEBUG(4,("SAMR Open Domain.  SID:%s RID:%x\n", sid_str, rid));
 
        /* store the parameters */
-       make_samr_q_set_userinfo2(&q_o, pol, switch_value, usr);
+       init_samr_q_open_domain(&q_o, connect_pol, rid, sid);
 
        /* turn parameters into data stream */
-       samr_io_q_set_userinfo2("", &q_o,  &data, 0);
+       if(!samr_io_q_open_domain("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO2, &data, &rdata))
-       {
-               SAMR_R_SET_USERINFO2 r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_set_userinfo2("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&data);
 
-               if (p)
-               {
-                       valid_query = True;
-               }
+       if(!samr_io_r_open_domain("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
 
-       return valid_query;
+       prs_mem_free(&rdata);
+
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Set User Info
+do a SAMR Query Unknown 12
 ****************************************************************************/
-BOOL samr_set_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
+BOOL do_samr_query_unknown_12(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
+                               uint32 *num_aliases,
+                               fstring als_names    [MAX_LOOKUP_SIDS],
+                               uint32  num_als_users[MAX_LOOKUP_SIDS])
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_UNKNOWN_12 q_o;
+       SAMR_R_UNKNOWN_12 r_o;
 
-       SAMR_Q_SET_USERINFO q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Set User Info.  level: %d\n", switch_value));
+       if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
+           num_aliases == NULL || als_names == NULL || num_als_users == NULL )
+                       return False;
 
-       if (pol == NULL || usr == NULL || switch_value == 0) return False;
+       /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
 
-       /* create and send a MSRPC command with api SAMR_SET_USERINFO */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Query Unknown 12.\n"));
 
        /* store the parameters */
-       make_samr_q_set_userinfo(&q_o, pol, switch_value, usr);
+       init_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
 
        /* turn parameters into data stream */
-       samr_io_q_set_userinfo("", &q_o,  &data, 0);
+       if(!samr_io_q_unknown_12("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO, &data, &rdata))
-       {
-               SAMR_R_SET_USERINFO r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       prs_mem_free(&data);
 
-               samr_io_r_set_userinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
+       if(!samr_io_r_unknown_12("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
+           r_o.num_als_usrs1 == r_o.num_aliases1) {
+               int i;
 
-               if (p)
-               {
-                       valid_query = True;
+               *num_aliases = r_o.num_aliases1;
+
+               for (i = 0; i < r_o.num_aliases1; i++) {
+                       fstrcpy(als_names[i], dos_unistrn2(r_o.uni_als_name[i].buffer,
+                                               r_o.uni_als_name[i].uni_str_len));
+               }
+               for (i = 0; i < r_o.num_als_usrs1; i++) {
+                       num_als_users[i] = r_o.num_als_usrs[i];
                }
+       } else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0) {
+               *num_aliases = 0;
+       } else {
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Query User Info
+do a SAMR Query User Groups
 ****************************************************************************/
-BOOL samr_query_userinfo(  POLICY_HND *pol, uint16 switch_value, void* usr)
+BOOL do_samr_query_usergroups(struct cli_state *cli, 
+                               POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_QUERY_USERGROUPS q_o;
+       SAMR_R_QUERY_USERGROUPS r_o;
 
-       SAMR_Q_QUERY_USERINFO q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
+       if (pol == NULL || gid == NULL || num_groups == 0)
+               return False;
 
-       if (pol == NULL || usr == NULL || switch_value == 0) return False;
+       /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
 
-       /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Query User Groups.\n"));
 
        /* store the parameters */
-       make_samr_q_query_userinfo(&q_o, pol, switch_value);
+       init_samr_q_query_usergroups(&q_o, pol);
 
        /* turn parameters into data stream */
-       samr_io_q_query_userinfo("", &q_o,  &data, 0);
+       if(!samr_io_q_query_usergroups("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERINFO, &data, &rdata))
-       {
-               SAMR_R_QUERY_USERINFO r_o;
-               BOOL p;
-
-               /* get user info */
-               r_o.info.id = usr;
+       if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_query_userinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       prs_mem_free(&data);
 
-               if (p && r_o.switch_value != switch_value)
-               {
-                       DEBUG(4,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
-                                 r_o.switch_value));
-               }
+       /* get user info */
+       r_o.gid = gid;
 
-               if (p && r_o.ptr != 0)
-               {
-                       valid_query = True;
-               }
+       if(!samr_io_r_query_usergroups("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
+               
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       *num_groups = r_o.num_entries;
+
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
 
 /****************************************************************************
-do a SAMR Close
+do a SAMR Query User Info
 ****************************************************************************/
-BOOL samr_close(  POLICY_HND *hnd)
+BOOL do_samr_query_userinfo(struct cli_state *cli, 
+                               POLICY_HND *pol, uint16 switch_value, void* usr)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_QUERY_USERINFO q_o;
+       SAMR_R_QUERY_USERINFO r_o;
 
-       SAMR_Q_CLOSE_HND q_c;
-       BOOL valid_close = False;
-
-       DEBUG(4,("SAMR Close\n"));
+       if (pol == NULL || usr == NULL || switch_value == 0)
+               return False;
 
-       if (hnd == NULL) return False;
+       /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
-       /* create and send a MSRPC command with api SAMR_CLOSE_HND */
+       DEBUG(4,("SAMR Query User Info.  level: %d\n", switch_value));
 
        /* store the parameters */
-       make_samr_q_close_hnd(&q_c, hnd);
+       init_samr_q_query_userinfo(&q_o, pol, switch_value);
 
        /* turn parameters into data stream */
-       samr_io_q_close_hnd("", &q_c,  &data, 0);
+       if(!samr_io_q_query_userinfo("", &q_o,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(hnd, SAMR_CLOSE_HND, &data, &rdata))
-       {
-               SAMR_R_CLOSE_HND r_c;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               samr_io_r_close_hnd("", &r_c, &rdata, 0);
-               p = rdata.offset != 0;
+       prs_mem_free(&data);
 
-               if (p && r_c.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
-                       p = False;
-               }
+       /* get user info */
+       r_o.info.id = usr;
 
-               if (p)
-               {
-                       /* check that the returned policy handle is all zeros */
-                       uint32 i;
-                       valid_close = True;
-
-                       for (i = 0; i < sizeof(r_c.pol.data); i++)
-                       {
-                               if (r_c.pol.data[i] != 0)
-                               {
-                                       valid_close = False;
-                                       break;
-                               }
-                       }       
-                       if (!valid_close)
-                       {
-                               DEBUG(4,("SAMR_CLOSE_HND: non-zero handle returned\n"));
-                       }
-               }
+       if(!samr_io_r_query_userinfo("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
+               
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       if (r_o.switch_value != switch_value) {
+               DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
+                         r_o.switch_value));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-       close_policy_hnd(hnd);
+       if (r_o.ptr == 0) {
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-       return valid_close;
+       prs_mem_free(&rdata);
+
+       return True;
 }
 
 /****************************************************************************
-do a SAMR query display info
+do a SAMR Close
 ****************************************************************************/
-BOOL samr_query_dispinfo(  POLICY_HND *pol_domain, uint16 level,
-                               uint32 *num_entries,
-                               SAM_DISPINFO_CTR *ctr)
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd)
 {
        prs_struct data;
        prs_struct rdata;
+       SAMR_Q_CLOSE_HND q_c;
+       SAMR_R_CLOSE_HND r_c;
+       int i;
 
-       SAMR_Q_QUERY_DISPINFO q_o;
-       BOOL valid_query = False;
-
-       DEBUG(4,("SAMR Query Display Info.  level: %d\n", level));
-
-       if (pol_domain == NULL || num_entries == NULL || ctr == NULL ||
-           level == 0)
-       {
+       if (hnd == NULL)
                return False;
-       }
 
-       /* create and send a MSRPC command with api SAMR_QUERY_DISPINFO */
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
+
+       /* create and send a MSRPC command with api SAMR_CLOSE_HND */
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       DEBUG(4,("SAMR Close\n"));
 
        /* store the parameters */
-       make_samr_q_query_dispinfo(&q_o, pol_domain, level, 0, 0xffffffff);
+       init_samr_q_close_hnd(&q_c, hnd);
 
        /* turn parameters into data stream */
-       samr_io_q_query_dispinfo("", &q_o,  &data, 0);
+       if(!samr_io_q_close_hnd("", &q_c,  &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_hnd_pipe_req(pol_domain, SAMR_QUERY_DISPINFO, &data, &rdata))
-       {
-               SAMR_R_QUERY_DISPINFO r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               /* get user info */
-               r_o.ctr = ctr;
+       prs_mem_free(&data);
 
-               samr_io_r_query_dispinfo("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(4,("SAMR_R_QUERY_DISPINFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
+       if(!samr_io_r_close_hnd("", &r_c, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               if (p && r_o.switch_level != level)
-               {
-                       DEBUG(4,("SAMR_R_QUERY_DISPINFO: received incorrect level %d\n",
-                                 r_o.switch_level));
-               }
+       if (r_c.status != 0) {
+               /* report error code */
+               DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               if (p && r_o.ptr_entries != 0)
-               {
-                       valid_query = True;
-                       (*num_entries) = r_o.num_entries;
+       /* check that the returned policy handle is all zeros */
+
+       for (i = 0; i < sizeof(r_c.pol.data); i++) {
+               if (r_c.pol.data[i] != 0) {
+                       DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
+                       prs_mem_free(&rdata);
+                       return False;
                }
-       }
+       }       
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
 
-       return valid_query;
+       return True;
 }
-
index 4180141cbaae4fe8efc7e41fd568748e4e560cf3..b883cc19425d891a76e83e395043236894385b8a 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Jeremy Allison                    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
 
 extern int DEBUGLEVEL;
 
-/****************************************************************************
-do a server net tprt enum
-****************************************************************************/
-BOOL srv_net_srv_tprt_enum(
-                       const char *srv_name, 
-                       uint32 switch_value, SRV_TPRT_INFO_CTR *ctr,
-                       uint32 preferred_len,
-                       ENUM_HND *hnd)
-{
-       prs_struct data; 
-       prs_struct rdata;
-       SRV_Q_NET_TPRT_ENUM q_o;
-       BOOL valid_enum = False;
-       struct cli_connection *con = NULL;
-
-       if (ctr == NULL || preferred_len == 0) return False;
-
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
-               return False;
-       }
-
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api SRV_NETTPRTENUM */
-
-       DEBUG(4,("SRV Net Server Transport Enum, level %d, enum:%8x\n",
-                               switch_value, get_enum_hnd(hnd)));
-                               
-       ctr->switch_value = switch_value;
-       ctr->ptr_tprt_ctr = 1;
-       ctr->tprt.info0.num_entries_read = 0;
-       ctr->tprt.info0.ptr_tprt_info    = 1;
-
-       /* store the parameters */
-       make_srv_q_net_tprt_enum(&q_o, srv_name,
-                                switch_value, ctr,
-                                preferred_len,
-                                hnd);
-
-       /* turn parameters into data stream */
-       srv_io_q_net_tprt_enum("", &q_o, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NETTRANSPORTENUM, &data, &rdata))
-       {
-               SRV_R_NET_TPRT_ENUM r_o;
-               BOOL p;
-
-               r_o.ctr = ctr;
-
-               srv_io_r_net_tprt_enum("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_TPRT_ENUM: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_enum = True;
-               }
-       }
-
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
-
-       return valid_enum;
-}
-
 /****************************************************************************
 do a server net conn enum
 ****************************************************************************/
-BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd)
@@ -127,23 +44,18 @@ BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
        prs_struct data; 
        prs_struct rdata;
        SRV_Q_NET_CONN_ENUM q_o;
-       BOOL valid_enum = False;
-       struct cli_connection *con = NULL;
-
-       if (ctr == NULL || preferred_len == 0) return False;
+       SRV_R_NET_CONN_ENUM r_o;
 
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if (server_name == NULL || ctr == NULL || preferred_len == 0)
                return False;
-       }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api SRV_NETCONNENUM */
 
-       DEBUG(4,("SRV Net Server Connection Enum %s), level %d, enum:%8x\n",
-                               qual_name, switch_value, get_enum_hnd(hnd)));
+       DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n",
+                               server_name, qual_name, switch_value, get_enum_hnd(hnd)));
                                
        ctr->switch_value = switch_value;
        ctr->ptr_conn_ctr = 1;
@@ -151,59 +63,60 @@ BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
        ctr->conn.info0.ptr_conn_info    = 1;
 
        /* store the parameters */
-       make_srv_q_net_conn_enum(&q_o, srv_name, qual_name,
+       init_srv_q_net_conn_enum(&q_o, server_name, qual_name,
                                 switch_value, ctr,
                                 preferred_len,
                                 hnd);
 
        /* turn parameters into data stream */
-       srv_io_q_net_conn_enum("", &q_o, &data, 0);
+       if(!srv_io_q_net_conn_enum("", &q_o, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NETCONNENUM, &data, &rdata))
-       {
-               SRV_R_NET_CONN_ENUM r_o;
-               BOOL p;
+       if(!rpc_api_pipe_req(cli, SRV_NETCONNENUM, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               r_o.ctr = ctr;
+       prs_mem_free(&data);
 
-               srv_io_r_net_conn_enum("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_enum = True;
-               }
+       r_o.ctr = ctr;
+
+       if(!srv_io_r_net_conn_enum("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-       return valid_enum;
+       if (r_o.ctr->switch_value != switch_value) {
+               /* different switch levels.  oops. */
+               DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
+                       r_o.ctr->switch_value, switch_value));
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       prs_mem_free(&rdata);
+       
+       return True;
 }
 
 /****************************************************************************
 do a server net sess enum
 ****************************************************************************/
-BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
+
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd)
@@ -211,23 +124,18 @@ BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
        prs_struct data; 
        prs_struct rdata;
        SRV_Q_NET_SESS_ENUM q_o;
-       BOOL valid_enum = False;
-       struct cli_connection *con = NULL;
-
-       if (ctr == NULL || preferred_len == 0) return False;
+       SRV_R_NET_SESS_ENUM r_o;
 
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if (server_name == NULL || ctr == NULL || preferred_len == 0)
                return False;
-       }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api SRV_NETSESSENUM */
 
-       DEBUG(4,("SRV Net Session Enum, level %d, enum:%8x\n",
-                               switch_value, get_enum_hnd(hnd)));
+       DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n",
+                               server_name, switch_value, get_enum_hnd(hnd)));
                                
        ctr->switch_value = switch_value;
        ctr->ptr_sess_ctr = 1;
@@ -235,145 +143,130 @@ BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
        ctr->sess.info0.ptr_sess_info    = 1;
 
        /* store the parameters */
-       make_srv_q_net_sess_enum(&q_o, srv_name, qual_name, user_name,
+       init_srv_q_net_sess_enum(&q_o, server_name, qual_name,
                                 switch_value, ctr,
                                 preferred_len,
                                 hnd);
 
        /* turn parameters into data stream */
-       srv_io_q_net_sess_enum("", &q_o, &data, 0);
+       if(!srv_io_q_net_sess_enum("", &q_o, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NETSESSENUM, &data, &rdata))
-       {
-               SRV_R_NET_SESS_ENUM r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SRV_NETSESSENUM, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
+
+       prs_mem_free(&data);
 
-               r_o.ctr = ctr;
+       r_o.ctr = ctr;
 
-               srv_io_r_net_sess_enum("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
+       if(!srv_io_r_net_sess_enum("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_enum = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
+       if (r_o.ctr->switch_value != switch_value) {
+               /* different switch levels.  oops. */
+               DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
+                       r_o.ctr->switch_value, switch_value));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-       return valid_enum;
+       prs_mem_free(&rdata);
+       
+       return True;
 }
 
 /****************************************************************************
 do a server net share enum
 ****************************************************************************/
-BOOL srv_net_srv_share_enum( char *srv_name, 
-                       uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
-                       uint32 preferred_len,
-                       ENUM_HND *hnd)
+BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
+                       char *server_name, 
+                       uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
+                       uint32 preferred_len, ENUM_HND *hnd)
 {
        prs_struct data; 
        prs_struct rdata;
        SRV_Q_NET_SHARE_ENUM q_o;
-       BOOL valid_enum = False;
-       struct cli_connection *con = NULL;
-
-       if (ctr == NULL || preferred_len == 0) return False;
 
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if (server_name == NULL || preferred_len == 0)
                return False;
-       }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api SRV_NETSHAREENUM */
 
-       DEBUG(4,("SRV Get Share Info, level %d, enum:%8x\n",
-                               switch_value, get_enum_hnd(hnd)));
+       DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n",
+                               server_name, switch_value, get_enum_hnd(hnd)));
                                
-       q_o.share_level = switch_value;
-
-       ctr->switch_value = switch_value;
-       ctr->ptr_share_ctr = 1;
-       ctr->share.info1.num_entries_read = 0;
-       ctr->share.info1.ptr_share_info    = 1;
-
        /* store the parameters */
-       make_srv_q_net_share_enum(&q_o, srv_name, 
-                                switch_value, ctr,
-                                preferred_len,
-                                hnd);
+       init_srv_q_net_share_enum(&q_o, server_name, switch_value,
+                                 preferred_len, hnd);
 
        /* turn parameters into data stream */
-       srv_io_q_net_share_enum("", &q_o, &data, 0);
+       if(!srv_io_q_net_share_enum("", &q_o, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NETSHAREENUM, &data, &rdata))
-       {
-               SRV_R_NET_SHARE_ENUM r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SRV_NETSHAREENUM, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               r_o.ctr = ctr;
+       prs_mem_free(&data);
 
-               srv_io_r_net_share_enum("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
+       if(!srv_io_r_net_share_enum("", r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_SHARE_ENUM: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_enum = True;
-               }
+       if (r_o->status != 0) {
+               /* report error code */
+               DEBUG(0,("SRV_R_NET_SHARE_ENUM: %s\n", get_nt_error_msg(r_o->status)));
+               prs_mem_free(&rdata);
+               free_srv_r_net_share_enum(r_o);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
+       if (r_o->ctr.switch_value != switch_value) {
+               /* different switch levels.  oops. */
+               DEBUG(0,("SRV_R_NET_SHARE_ENUM: info class %d does not match request %d\n",
+                       r_o->ctr.switch_value, switch_value));
+               prs_mem_free(&rdata);
+               free_srv_r_net_share_enum(r_o);
+               return False;
+       }
 
-       return valid_enum;
+       prs_mem_free(&rdata);
+       
+       return True;
 }
 
 /****************************************************************************
 do a server net file enum
 ****************************************************************************/
-BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
+
+BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
+                       char *server_name, char *qual_name,
                        uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
                        uint32 preferred_len,
                        ENUM_HND *hnd)
@@ -381,23 +274,18 @@ BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
        prs_struct data; 
        prs_struct rdata;
        SRV_Q_NET_FILE_ENUM q_o;
-       BOOL valid_enum = False;
-       struct cli_connection *con = NULL;
+       SRV_R_NET_FILE_ENUM r_o;
 
-       if (ctr == NULL || preferred_len == 0) return False;
-
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if (server_name == NULL || ctr == NULL || preferred_len == 0)
                return False;
-       }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api SRV_NETFILEENUM */
 
-       DEBUG(4,("SRV Get File Info level %d, enum:%8x\n",
-                               switch_value, get_enum_hnd(hnd)));
+       DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n",
+                               server_name, switch_value, get_enum_hnd(hnd)));
                                
        q_o.file_level = switch_value;
 
@@ -407,189 +295,117 @@ BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
        ctr->file.info3.ptr_file_info    = 1;
 
        /* store the parameters */
-       make_srv_q_net_file_enum(&q_o, srv_name, qual_name, file_id,
+       init_srv_q_net_file_enum(&q_o, server_name, qual_name,
                                 switch_value, ctr,
                                 preferred_len,
                                 hnd);
 
        /* turn parameters into data stream */
-       srv_io_q_net_file_enum("", &q_o, &data, 0);
+       if(!srv_io_q_net_file_enum("", &q_o, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NETFILEENUM, &data, &rdata))
-       {
-               SRV_R_NET_FILE_ENUM r_o;
-               BOOL p;
+       if (!rpc_api_pipe_req(cli, SRV_NETFILEENUM, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               r_o.ctr = ctr;
+       prs_mem_free(&data);
 
-               srv_io_r_net_file_enum("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
+       r_o.ctr = ctr;
+
+       if(!srv_io_r_net_file_enum("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
+               return False;
+       }
                
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_FILE_ENUM: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_enum = True;
-               }
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SRV_R_NET_FILE_ENUM: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
+       if (r_o.ctr->switch_value != switch_value) {
+               /* different switch levels.  oops. */
+               DEBUG(0,("SRV_R_NET_FILE_ENUM: info class %d does not match request %d\n",
+                       r_o.ctr->switch_value, switch_value));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-       return valid_enum;
+       prs_mem_free(&rdata);
+       
+       return True;
 }
 
 /****************************************************************************
 do a server get info 
 ****************************************************************************/
-BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value,
-                               SRV_INFO_CTR *ctr)
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+                       char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr)
 {
        prs_struct data; 
        prs_struct rdata;
        SRV_Q_NET_SRV_GET_INFO q_o;
-       BOOL valid_info = False;
-       struct cli_connection *con = NULL;
-
-       if (switch_value == 0 || ctr == NULL) return False;
+       SRV_R_NET_SRV_GET_INFO r_o;
 
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if (server_name == NULL || switch_value == 0 || ctr == NULL)
                return False;
-       }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rdata, 0, 4, UNMARSHALL);
 
        /* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */
 
-       DEBUG(4,("SRV Get Server Info level %d\n", switch_value));
+       DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value));
 
        /* store the parameters */
-       make_srv_q_net_srv_get_info(&q_o, srv_name, switch_value);
+       init_srv_q_net_srv_get_info(&q_o, server_name, switch_value);
 
        /* turn parameters into data stream */
-       srv_io_q_net_srv_get_info("", &q_o, &data, 0);
+       if(!srv_io_q_net_srv_get_info("", &q_o, &data, 0)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NET_SRV_GET_INFO, &data, &rdata))
-       {
-               SRV_R_NET_SRV_GET_INFO r_o;
-               BOOL p;
-
-               r_o.ctr = ctr;
-
-               srv_io_r_net_srv_get_info("", &r_o, &rdata, 0);
-               p = rdata.offset != 0;
-               p = rdata.offset != 0;
-               
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = 0;
-               }
-
-               if (p && r_o.ctr->switch_value != q_o.switch_value)
-               {
-                       /* different switch levels.  oops. */
-                       DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
-                               r_o.ctr->switch_value, q_o.switch_value));
-                       p = 0;
-               }
-
-               if (p)
-               {
-                       /* ok, at last: we're happy. */
-                       valid_info = True;
-               }
+       if (!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata)) {
+               prs_mem_free(&data);
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
-       
-       cli_connection_unlink(con);
+       prs_mem_free(&data);
 
-       return valid_info;
-}
+       r_o.ctr = ctr;
 
-/****************************************************************************
-get server time
-****************************************************************************/
-BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod)
-{
-       prs_struct data; 
-       prs_struct rdata;
-       SRV_Q_NET_REMOTE_TOD q_t;
-       BOOL valid_info = False;
-       struct cli_connection *con = NULL;
-
-       if (tod == NULL) return False;
-
-       if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
-       {
+       if(!srv_io_r_net_srv_get_info("", &r_o, &rdata, 0)) {
+               prs_mem_free(&rdata);
                return False;
        }
 
-       prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
-
-       /* create and send a MSRPC command with api SRV_NET_REMOTE_TOD */
-
-       DEBUG(4,("SRV Remote TOD (%s)\n", srv_name));
-
-       /* store the parameters */
-       make_srv_q_net_remote_tod(&q_t, srv_name);
-
-       /* turn parameters into data stream */
-       srv_io_q_net_remote_tod("", &q_t, &data, 0);
-
-       /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, SRV_NET_REMOTE_TOD, &data, &rdata))
-       {
-               SRV_R_NET_REMOTE_TOD r_t;
-               BOOL p;
-
-               r_t.tod = tod;
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rdata);
+               return False;
+       }
 
-               srv_io_r_net_remote_tod("", &r_t, &rdata, 0);
-               p = rdata.offset != 0;
-               p = rdata.offset != 0;
-               
-               if (p && r_t.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("SRV_R_NET_REMOTE_TOD: %s\n", get_nt_error_msg(r_t.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_info = True;
-               }
+       if (r_o.ctr->switch_value != q_o.switch_value) {
+               /* different switch levels.  oops. */
+               DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
+                       r_o.ctr->switch_value, q_o.switch_value));
+               prs_mem_free(&rdata);
+               return False;
        }
 
-       prs_mem_free(&data   );
-       prs_mem_free(&rdata  );
+       prs_mem_free(&rdata);
        
-       cli_connection_unlink(con);
-
-       return valid_info;
+       return True;
 }
index 99141bae6ce044937b4ce69378a7f63df5af5eb2..ae0d5d8231a23a4f2ea81dfc91bdcd83a1844b06 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Jeremy Allison                    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
@@ -34,64 +35,59 @@ extern int DEBUGLEVEL;
 /****************************************************************************
 do a WKS Open Policy
 ****************************************************************************/
-BOOL wks_query_info( char *srv_name, uint32 switch_value,
+BOOL do_wks_query_info(struct cli_state *cli, 
+                       char *server_name, uint32 switch_value,
                        WKS_INFO_100 *wks100)
 {
        prs_struct rbuf;
        prs_struct buf; 
        WKS_Q_QUERY_INFO q_o;
-       BOOL valid_info = False;
-       struct cli_connection *con = NULL;
+       WKS_R_QUERY_INFO r_o;
 
-       if (wks100 == NULL) return False;
-
-       if (!cli_connection_init(srv_name, PIPE_WKSSVC, &con))
-       {
+       if (server_name == 0 || wks100 == NULL)
                return False;
-       }
 
-       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+       prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
+       prs_init(&rbuf, 0, 4, UNMARSHALL );
 
        /* create and send a MSRPC command with api WKS_QUERY_INFO */
 
        DEBUG(4,("WKS Query Info\n"));
 
        /* store the parameters */
-       make_wks_q_query_info(&q_o, srv_name, switch_value);
+       init_wks_q_query_info(&q_o, server_name, switch_value);
 
        /* turn parameters into data stream */
-       wks_io_q_query_info("", &q_o, &buf, 0);
+       if(!wks_io_q_query_info("", &q_o, &buf, 0)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
        /* send the data on \PIPE\ */
-       if (rpc_con_pipe_req(con, WKS_QUERY_INFO, &buf, &rbuf))
-       {
-               WKS_R_QUERY_INFO r_o;
-               BOOL p;
-
-               r_o.wks100 = wks100;
-
-               wks_io_r_query_info("", &r_o, &rbuf, 0);
-               p = rbuf.offset != 0;
-
-               if (p && r_o.status != 0)
-               {
-                       /* report error code */
-                       DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
-               }
-
-               if (p)
-               {
-                       valid_info = True;
-               }
+       if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
+               prs_mem_free(&buf);
+               prs_mem_free(&rbuf);
+               return False;
        }
 
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
+       prs_mem_free(&buf);
 
-       cli_connection_unlink(con);
+       r_o.wks100 = wks100;
 
-       return valid_info;
-}
+       if(!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
+               prs_mem_free(&rbuf);
+               return False;
+       }
+
+       if (r_o.status != 0) {
+               /* report error code */
+               DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
+               prs_mem_free(&rbuf);
+               return False;
+       }
 
+       prs_mem_free(&rbuf);
+
+       return True;
+}
index 0486017181747b0c46f0fcc04c89cf59af43036b..8ef193fa893d126bc520e3636acdcc32a21aee0d 100644 (file)
@@ -34,7 +34,7 @@ extern int DEBUGLEVEL;
  check workstation trust account status
  ************************************************************************/
 BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
-                               char *myhostname, char *domain, fstring mach_acct,
+                               char *hostname, char *domain, fstring mach_acct,
                                fstring new_mach_pwd)
 {
        pstring tmp;
@@ -53,7 +53,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
        char *change_mach_pwd;
 
        /* initial machine password */
-       fstrcpy(mach_pwd, myhostname);
+       fstrcpy(mach_pwd, hostname);
        strlower(mach_pwd);
 
        slprintf(tmp, sizeof(tmp) - 1,"Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:",
@@ -91,9 +91,9 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
 
        DEBUG(1,("server connect for cli_trust\n"));
 
-       if (!server_connect_init(&cli_trust, myhostname, dest_ip, dest_host))
+       if (!server_connect_init(&cli_trust, hostname, dest_ip, dest_host))
        {
-               cli_error(&cli_trust, &err_cls, &err_num);
+               cli_error(&cli_trust, &err_cls, &err_num, NULL);
                DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust)));
 
                cli_shutdown(&cli_trust);
@@ -141,7 +141,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
                return False;
        }
 
-       cli_error(&cli_trust, &err_cls, &err_num);
+       cli_error(&cli_trust, &err_cls, &err_num, NULL);
 
        if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT))
        {
index d3b895dc1a6a52009356132cece7d0cea3050cb4..771e7c31d4521f0cf6e2a3d657b827b255361591 100644 (file)
@@ -2,9 +2,9 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
  *  
  *  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
 
 extern int DEBUGLEVEL;
 
+static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth);
+
 /*******************************************************************
-creates a LSA_TRANS_NAME structure.
+ Inits a LSA_TRANS_NAME structure.
 ********************************************************************/
-BOOL make_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
+
+void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
                        uint32 sid_name_use, char *name, uint32 idx)
 {
        int len_name = strlen(name);
 
+       if(len_name == 0)
+               len_name = 1;
+
        trn->sid_name_use = sid_name_use;
-       make_uni_hdr(&(trn->hdr_name), len_name);
-       make_unistr2(uni_name, name, len_name);
+       init_uni_hdr(&trn->hdr_name, len_name);
+       init_unistr2(uni_name, name, len_name);
        trn->domain_idx = idx;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a LSA_TRANS_NAME structure.
+ Reads or writes a LSA_TRANS_NAME structure.
 ********************************************************************/
+
 static BOOL lsa_io_trans_name(char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, int depth)
 {
-       if (trn == NULL) return False;
+       if (trn == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_trans_name");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("sid_name_use", ps, depth, &(trn->sid_name_use));
-       smb_io_unihdr ("hdr_name", &(trn->hdr_name), ps, depth);
-       prs_uint32("domain_idx  ", ps, depth, &(trn->domain_idx  ));
+       if(!prs_uint32("sid_name_use", ps, depth, &trn->sid_name_use))
+               return False;
+       if(!smb_io_unihdr ("hdr_name", &trn->hdr_name, ps, depth))
+               return False;
+       if(!prs_uint32("domain_idx  ", ps, depth, &trn->domain_idx))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_R_REF structure.
+ Reads or writes a DOM_R_REF structure.
 ********************************************************************/
-static BOOL lsa_io_dom_r_ref(char *desc,  DOM_R_REF *r_r, prs_struct *ps, int depth)
+
+static BOOL lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int depth)
 {
-       uint32 i, s, n;
+       int i, s, n;
 
-       prs_debug(ps, depth, desc, "smb_io_dom_r_ref");
+       prs_debug(ps, depth, desc, "lsa_io_dom_r_ref");
        depth++;
 
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("num_ref_doms_1", ps, depth, &(r_r->num_ref_doms_1)); /* num referenced domains? */
-       prs_uint32("ptr_ref_dom   ", ps, depth, &(r_r->ptr_ref_dom   )); /* undocumented buffer pointer. */
-       prs_uint32("max_entries   ", ps, depth, &(r_r->max_entries   )); /* 32 - max number of entries */
+       if(!prs_uint32("num_ref_doms_1", ps, depth, &r_r->num_ref_doms_1)) /* num referenced domains? */
+               return False;
+       if(!prs_uint32("ptr_ref_dom   ", ps, depth, &r_r->ptr_ref_dom)) /* undocumented buffer pointer. */
+               return False;
+       if(!prs_uint32("max_entries   ", ps, depth, &r_r->max_entries)) /* 32 - max number of entries */
+               return False;
 
        SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1);
 
-       if (r_r->ptr_ref_dom != 0)
-       {
-               prs_uint32("num_ref_doms_2", ps, depth, &(r_r->num_ref_doms_2)); /* 4 - num referenced domains? */
+       if (r_r->ptr_ref_dom != 0) {
+               if(!prs_uint32("num_ref_doms_2", ps, depth, &r_r->num_ref_doms_2)) /* 4 - num referenced domains? */
+                       return False;
+
                SMB_ASSERT_ARRAY(r_r->ref_dom, r_r->num_ref_doms_2);
 
-               for (i = 0; i < r_r->num_ref_doms_1; i++)
-               {
+               for (i = 0; i < r_r->num_ref_doms_1; i++) {
                        fstring t;
 
                        slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
-                       smb_io_unihdr(t, &(r_r->hdr_ref_dom[i].hdr_dom_name), ps, depth);
+                       if(!smb_io_unihdr(t, &r_r->hdr_ref_dom[i].hdr_dom_name, ps, depth))
+                               return False;
 
                        slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
-                       prs_uint32(t, ps, depth, &(r_r->hdr_ref_dom[i].ptr_dom_sid));
+                       if(!prs_uint32(t, ps, depth, &r_r->hdr_ref_dom[i].ptr_dom_sid))
+                               return False;
                }
 
-               for (i = 0, n = 0, s = 0; i < r_r->num_ref_doms_2; i++)
-               {
+               for (i = 0, n = 0, s = 0; i < r_r->num_ref_doms_2; i++) {
                        fstring t;
 
-                       if (r_r->hdr_ref_dom[i].hdr_dom_name.buffer != 0)
-                       {
+                       if (r_r->hdr_ref_dom[i].hdr_dom_name.buffer != 0) {
                                slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
-                               smb_io_unistr2(t, &(r_r->ref_dom[n].uni_dom_name), True, ps, depth); /* domain name unicode string */
-                               prs_align(ps);
+                               if(!smb_io_unistr2(t, &r_r->ref_dom[n].uni_dom_name, True, ps, depth)) /* domain name unicode string */
+                                       return False;
                                n++;
                        }
 
-                       if (r_r->hdr_ref_dom[i].ptr_dom_sid != 0)
-                       {
+                       if (r_r->hdr_ref_dom[i].ptr_dom_sid != 0) {
                                slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
-                               smb_io_dom_sid2("", &(r_r->ref_dom[s].ref_dom), ps, depth); /* referenced domain SIDs */
+                               if(!smb_io_dom_sid2("", &r_r->ref_dom[s].ref_dom, ps, depth)) /* referenced domain SIDs */
+                                       return False;
                                s++;
                        }
                }
@@ -121,55 +137,58 @@ static BOOL lsa_io_dom_r_ref(char *desc,  DOM_R_REF *r_r, prs_struct *ps, int de
        return True;
 }
 
-
 /*******************************************************************
-makes an LSA_SEC_QOS structure.
+ Inits an LSA_SEC_QOS structure.
 ********************************************************************/
-BOOL make_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
+
+void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
                                uint32 unknown)
 {
-       if (qos == NULL) return False;
-
-       DEBUG(5,("make_lsa_sec_qos\n"));
+       DEBUG(5,("init_lsa_sec_qos\n"));
 
        qos->len = 0x0c; /* length of quality of service block, in bytes */
        qos->sec_imp_level = imp_lev;
        qos->sec_ctxt_mode = ctxt;
        qos->effective_only = eff;
        qos->unknown = unknown;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_SEC_QOS structure.
+ Reads or writes an LSA_SEC_QOS structure.
 ********************************************************************/
+
 static BOOL lsa_io_sec_qos(char *desc,  LSA_SEC_QOS *qos, prs_struct *ps, int depth)
 {
-       int start;
+       uint32 start;
 
-       if (qos == NULL) return False;
+       if (qos == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_obj_qos");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       start = ps->offset;
+       start = prs_offset(ps);
 
        /* these pointers had _better_ be zero, because we don't know
           what they point to!
         */
-       prs_uint32("len           ", ps, depth, &(qos->len           )); /* 0x18 - length (in bytes) inc. the length field. */
-       prs_uint16("sec_imp_level ", ps, depth, &(qos->sec_imp_level )); 
-       prs_uint8 ("sec_ctxt_mode ", ps, depth, &(qos->sec_ctxt_mode )); 
-       prs_uint8 ("effective_only", ps, depth, &(qos->effective_only)); 
-       prs_uint32("unknown       ", ps, depth, &(qos->unknown       )); 
-
-       if (qos->len != ps->offset - start)
-       {
+       if(!prs_uint32("len           ", ps, depth, &qos->len)) /* 0x18 - length (in bytes) inc. the length field. */
+               return False;
+       if(!prs_uint16("sec_imp_level ", ps, depth, &qos->sec_imp_level ))
+               return False;
+       if(!prs_uint8 ("sec_ctxt_mode ", ps, depth, &qos->sec_ctxt_mode ))
+               return False;
+       if(!prs_uint8 ("effective_only", ps, depth, &qos->effective_only))
+               return False;
+       if(!prs_uint32("unknown       ", ps, depth, &qos->unknown))
+               return False;
+
+       if (qos->len != prs_offset(ps) - start) {
                DEBUG(3,("lsa_io_sec_qos: length %x does not match size %x\n",
-                        qos->len, ps->offset - start));
+                        qos->len, prs_offset(ps) - start));
        }
 
        return True;
@@ -177,12 +196,11 @@ static BOOL lsa_io_sec_qos(char *desc,  LSA_SEC_QOS *qos, prs_struct *ps, int de
 
 
 /*******************************************************************
-makes an LSA_OBJ_ATTR structure.
+ Inits an LSA_OBJ_ATTR structure.
 ********************************************************************/
-BOOL make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
-{
-       if (attr == NULL) return False;
 
+void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
+{
        DEBUG(5,("make_lsa_obj_attr\n"));
 
        attr->len = 0x18; /* length of object attribute block, in bytes */
@@ -191,55 +209,58 @@ BOOL make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
        attr->attributes = attributes;
        attr->ptr_sec_desc = 0;
        
-       if (qos != NULL)
-       {
+       if (qos != NULL) {
                attr->ptr_sec_qos = 1;
                attr->sec_qos = qos;
-       }
-       else
-       {
+       } else {
                attr->ptr_sec_qos = 0;
                attr->sec_qos = NULL;
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_OBJ_ATTR structure.
+ Reads or writes an LSA_OBJ_ATTR structure.
 ********************************************************************/
-static BOOL lsa_io_obj_attr(char *desc,  LSA_OBJ_ATTR *attr, prs_struct *ps, int depth)
+
+static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int depth)
 {
-       int start;
+       uint32 start;
 
-       if (attr == NULL) return False;
+       if (attr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_obj_attr");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       start = ps->offset;
+       start = prs_offset(ps);
 
        /* these pointers had _better_ be zero, because we don't know
           what they point to!
         */
-       prs_uint32("len         ", ps, depth, &(attr->len         )); /* 0x18 - length (in bytes) inc. the length field. */
-       prs_uint32("ptr_root_dir", ps, depth, &(attr->ptr_root_dir)); /* 0 - root directory (pointer) */
-       prs_uint32("ptr_obj_name", ps, depth, &(attr->ptr_obj_name)); /* 0 - object name (pointer) */
-       prs_uint32("attributes  ", ps, depth, &(attr->attributes  )); /* 0 - attributes (undocumented) */
-       prs_uint32("ptr_sec_desc", ps, depth, &(attr->ptr_sec_desc)); /* 0 - security descriptior (pointer) */
-       prs_uint32("ptr_sec_qos ", ps, depth, &(attr->ptr_sec_qos )); /* security quality of service (pointer) */
-
-       if (attr->len != ps->offset - start)
-       {
+       if(!prs_uint32("len         ", ps, depth, &attr->len)) /* 0x18 - length (in bytes) inc. the length field. */
+               return False;
+       if(!prs_uint32("ptr_root_dir", ps, depth, &attr->ptr_root_dir)) /* 0 - root directory (pointer) */
+               return False;
+       if(!prs_uint32("ptr_obj_name", ps, depth, &attr->ptr_obj_name)) /* 0 - object name (pointer) */
+               return False;
+       if(!prs_uint32("attributes  ", ps, depth, &attr->attributes)) /* 0 - attributes (undocumented) */
+               return False;
+       if(!prs_uint32("ptr_sec_desc", ps, depth, &attr->ptr_sec_desc)) /* 0 - security descriptior (pointer) */
+               return False;
+       if(!prs_uint32("ptr_sec_qos ", ps, depth, &attr->ptr_sec_qos )) /* security quality of service (pointer) */
+               return False;
+
+       if (attr->len != prs_offset(ps) - start) {
                DEBUG(3,("lsa_io_obj_attr: length %x does not match size %x\n",
-                        attr->len, ps->offset - start));
+                        attr->len, prs_offset(ps) - start));
        }
 
-       if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL)
-       {
-               lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth);
+       if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL) {
+               if(!lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth))
+                       return False;
        }
 
        return True;
@@ -247,688 +268,515 @@ static BOOL lsa_io_obj_attr(char *desc,  LSA_OBJ_ATTR *attr, prs_struct *ps, int
 
 
 /*******************************************************************
-makes an LSA_Q_OPEN_POL structure.
+ Inits an LSA_Q_OPEN_POL structure.
 ********************************************************************/
-BOOL make_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
+
+void init_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
                        uint32 attributes,
                        uint32 desired_access,
                        LSA_SEC_QOS *qos)
 {
-       if (r_q == NULL) return False;
-
        DEBUG(5,("make_open_pol: attr:%d da:%d\n", attributes, desired_access));
 
        r_q->ptr = 1; /* undocumented pointer */
 
        if (qos == NULL)
-       {
                r_q->des_access = desired_access;
-       }
 
        r_q->system_name = system_name;
-       make_lsa_obj_attr(&(r_q->attr           ), attributes, qos);
-
-       return True;
+       init_lsa_obj_attr(&r_q->attr, attributes, qos);
 }
 
 /*******************************************************************
-reads or writes an LSA_Q_OPEN_POL structure.
+ Reads or writes an LSA_Q_OPEN_POL structure.
 ********************************************************************/
-BOOL lsa_io_q_open_pol(char *desc,  LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth)
+
+BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_q_open_pol");
        depth++;
 
-       prs_uint32("ptr       ", ps, depth, &(r_q->ptr       ));
-       prs_uint16("system_name", ps, depth, &(r_q->system_name ));
-       prs_align ( ps );
+       if(!prs_uint32("ptr       ", ps, depth, &r_q->ptr))
+               return False;
+       if(!prs_uint16("system_name", ps, depth, &r_q->system_name))
+               return False;
+       if(!prs_align( ps ))
+               return False;
 
-       lsa_io_obj_attr("", &(r_q->attr           ), ps, depth);
+       if(!lsa_io_obj_attr("", &r_q->attr, ps, depth))
+               return False;
 
-       if (r_q->attr.ptr_sec_qos == 0)
-       {
-               prs_uint32("des_access", ps, depth, &(r_q->des_access));
+       if (r_q->attr.ptr_sec_qos == 0) {
+               if(!prs_uint32("des_access", ps, depth, &r_q->des_access))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_R_OPEN_POL structure.
+ Reads or writes an LSA_R_OPEN_POL structure.
 ********************************************************************/
-BOOL lsa_io_r_open_pol(char *desc,  LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth)
 {
-       if (r_p == NULL) return False;
+       if (r_p == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_open_pol");
        depth++;
 
-       smb_io_pol_hnd("", &(r_p->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_p->status));
+       if(!prs_uint32("status", ps, depth, &r_p->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an LSA_Q_OPEN_POL2 structure.
+ Inits an LSA_Q_OPEN_POL2 structure.
 ********************************************************************/
-BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, const char *server_name,
+
+void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name,
                        uint32 attributes,
                        uint32 desired_access,
                        LSA_SEC_QOS *qos)
 {
-       if (r_q == NULL) return False;
-
        DEBUG(5,("make_open_pol2: attr:%d da:%d\n", attributes, desired_access));
 
        r_q->ptr = 1; /* undocumented pointer */
 
        if (qos == NULL)
-       {
                r_q->des_access = desired_access;
-       }
 
-       make_unistr2     (&(r_q->uni_server_name), server_name, strlen(server_name));
-       make_lsa_obj_attr(&(r_q->attr           ), attributes, qos);
-
-       return True;
+       init_unistr2(&r_q->uni_server_name, server_name, strlen(server_name));
+       init_lsa_obj_attr(&r_q->attr, attributes, qos);
 }
 
 /*******************************************************************
-reads or writes an LSA_Q_OPEN_POL2 structure.
+ Reads or writes an LSA_Q_OPEN_POL2 structure.
 ********************************************************************/
-BOOL lsa_io_q_open_pol2(char *desc,  LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth)
+
+BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth)
 {
-       if (r_q == NULL) return False;
+       if (r_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_q_open_pol2");
        depth++;
 
-       prs_uint32("ptr       ", ps, depth, &(r_q->ptr       ));
+       if(!prs_uint32("ptr       ", ps, depth, &r_q->ptr))
+               return False;
 
-       smb_io_unistr2 ("", &(r_q->uni_server_name), r_q->ptr, ps, depth);
-       lsa_io_obj_attr("", &(r_q->attr           ), ps, depth);
+       if(!smb_io_unistr2 ("", &r_q->uni_server_name, r_q->ptr, ps, depth))
+               return False;
+       if(!lsa_io_obj_attr("", &r_q->attr, ps, depth))
+               return False;
 
-       if (r_q->attr.ptr_sec_qos == 0)
-       {
-               prs_uint32("des_access", ps, depth, &(r_q->des_access));
+       if (r_q->attr.ptr_sec_qos == 0) {
+               if(!prs_uint32("des_access", ps, depth, &r_q->des_access))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_R_OPEN_POL2 structure.
+ Reads or writes an LSA_R_OPEN_POL2 structure.
 ********************************************************************/
-BOOL lsa_io_r_open_pol2(char *desc,  LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth)
 {
-       if (r_p == NULL) return False;
+       if (r_p == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_open_pol2");
        depth++;
 
-       smb_io_pol_hnd("", &(r_p->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_p->status));
-
-       return True;
+       if(!prs_uint32("status", ps, depth, &r_p->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an LSA_Q_QUERY_INFO structure.
+ Inits an LSA_Q_QUERY_INFO structure.
 ********************************************************************/
-BOOL make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class)
-{
-       if (q_q == NULL || hnd == NULL) return False;
 
+void init_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class)
+{
        DEBUG(5,("make_q_query\n"));
 
-       memcpy(&(q_q->pol), hnd, sizeof(q_q->pol));
+       memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
 
        q_q->info_class = info_class;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_Q_QUERY_INFO structure.
+ Reads or writes an LSA_Q_QUERY_INFO structure.
 ********************************************************************/
-BOOL lsa_io_q_query(char *desc,  LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth)
-{
-       if (q_q == NULL) return False;
-
-       prs_debug(ps, depth, desc, "lsa_io_q_query");
-       depth++;
-
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth);
-
-       prs_uint16("info_class", ps, depth, &(q_q->info_class));
-
-       return True;
-}
-
-/*******************************************************************
-makes an LSA_Q_OPEN_SECRET structure.
-********************************************************************/
-BOOL make_q_open_secret(LSA_Q_OPEN_SECRET *q_o, const POLICY_HND *pol_hnd,
-                       const char *secret_name, uint32 desired_access)
-{
-       int len = strlen(secret_name);
-
-       if (q_o == NULL) return False;
-
-       DEBUG(5,("make_q_open_secret"));
-
-       memcpy(&(q_o->pol), pol_hnd, sizeof(q_o->pol));
-
-       make_uni_hdr(&(q_o->hdr_secret), len);
-       make_unistr2(&(q_o->uni_secret), secret_name, len);
-
-       q_o->des_access = desired_access;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_OPEN_SECRET structure.
-********************************************************************/
-BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_o, prs_struct *ps, int depth)
-{
-       if (q_o == NULL) return False;
-
-       prs_debug(ps, depth, desc, "lsa_io_q_open_secret");
-       depth++;
-
-       smb_io_pol_hnd("", &(q_o->pol), ps, depth);
-
-       prs_align(ps);
-       smb_io_unihdr ("", &(q_o->hdr_secret), ps, depth);
-       smb_io_unistr2("", &(q_o->uni_secret), 1, ps, depth);
-
-       prs_align(ps);
-       prs_uint32("des_access", ps, depth, &(q_o->des_access));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_R_OPEN_SECRET structure.
-********************************************************************/
-BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_o, prs_struct *ps, int depth)
-{
-       if (r_o == NULL) return False;
-
-       prs_debug(ps, depth, desc, "lsa_io_r_open_secret");
-       depth++;
-
-       smb_io_pol_hnd("", &(r_o->pol), ps, depth);
-
-       prs_uint32("status", ps, depth, &(r_o->status));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_SECRET_VALUE structure.
-********************************************************************/
-BOOL lsa_io_secret_value(char *desc, LSA_SECRET_VALUE *value, prs_struct *ps, int depth)
-{
-       if (value == NULL) return False;
-
-       prs_debug(ps, depth, desc, "lsa_io_secret_value");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("ptr_secret", ps, depth, &(value->ptr_secret));
-
-       if (value->ptr_secret != 0)
-       {
-               smb_io_strhdr2("hdr_secret", &(value->hdr_secret), ps, depth);
-               smb_io_string2("secret"    , &(value->enc_secret),
-                              value->hdr_secret.buffer, ps, depth);
-       }
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_SECRET_INFO structure.
-********************************************************************/
-BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO *info, prs_struct *ps, int depth)
-{
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "lsa_io_secret_info");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("ptr_value ", ps, depth, &(info->ptr_value ));
-
-       if (info->ptr_value != 0)
-       {
-               lsa_io_secret_value("", &(info->value), ps, depth);
-       }
-
-       prs_align(ps);
-       prs_uint32("ptr_update", ps, depth, &(info->ptr_update));
-
-       if (info->ptr_update != 0)
-       {
-               ps->align = 8;
-               prs_align(ps);
-               ps->align = 4;
-
-               smb_io_time("last_update", &(info->last_update), ps, depth);
-       }
-
-       return True;
-}
-
-/*******************************************************************
-makes an LSA_Q_QUERY_SECRET structure.
-********************************************************************/
-BOOL make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol)
-{
-       if (q_q == NULL) return False;
-
-       DEBUG(5,("make_q_query_secret\n"));
-
-       memcpy(&(q_q->pol), pol, sizeof(q_q->pol));
-
-       /* Want secret */
-       q_q->info.ptr_value = 1;
-       q_q->info.value.ptr_secret = 0;
-
-       /* Want last change time */
-       q_q->info.ptr_update = 1;
-
-       /* Don't care about old info */
-       q_q->oldinfo.ptr_value = 0;
-       q_q->oldinfo.ptr_update = 0;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_QUERY_SECRET structure.
-********************************************************************/
-BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET *q_q, prs_struct *ps, int depth)
-{
-       if (q_q == NULL) return False;
 
-       prs_debug(ps, depth, desc, "lsa_io_q_query_secret");
-       depth++;
-
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth);
-
-       lsa_io_secret_info("", &(q_q->info   ), ps, depth);
-       lsa_io_secret_info("", &(q_q->oldinfo), ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_QUERY_SECRET structure.
-********************************************************************/
-BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, int depth)
+BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth)
 {
-       if (r_q == NULL) return False;
+       if (q_q == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "lsa_io_r_query_secret");
+       prs_debug(ps, depth, desc, "lsa_io_q_query");
        depth++;
 
-       lsa_io_secret_info("", &(r_q->info   ), ps, depth);
-       lsa_io_secret_info("", &(r_q->oldinfo), ps, depth);
+       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+               return False;
 
-       prs_align(ps);
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint16("info_class", ps, depth, &q_q->info_class))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an LSA_Q_ENUM_TRUST_DOM structure.
+ Reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
 ********************************************************************/
-BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
-                               POLICY_HND *pol,
-                               uint32 enum_context, uint32 preferred_len)
-{
-       if (q_e == NULL) return False;
-
-       DEBUG(5,("make_q_enum_trust_dom\n"));
-
-       memcpy(&(q_e->pol), pol, sizeof(q_e->pol));
-       q_e->enum_context = enum_context;
-       q_e->preferred_len = preferred_len;
 
-       return True;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
-********************************************************************/
-BOOL lsa_io_q_enum_trust_dom(char *desc,  LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth)
+BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth)
 {
-       if (q_e == NULL) return False;
+       if (q_e == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_q_enum_trust_dom");
        depth++;
 
 
-       smb_io_pol_hnd("", &(q_e->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &q_e->pol, ps, depth))
+               return False;
 
-       prs_uint32("enum_context ", ps, depth, &(q_e->enum_context ));
-       prs_uint32("preferred_len", ps, depth, &(q_e->preferred_len));
+       if(!prs_uint32("enum_context ", ps, depth, &q_e->enum_context))
+               return False;
+       if(!prs_uint32("preferred_len", ps, depth, &q_e->preferred_len))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an LSA_R_ENUM_TRUST_DOM structure.
+ Inits an LSA_R_ENUM_TRUST_DOM structure.
 ********************************************************************/
-BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
-                               int32 enum_context,
-                               char *domain_name, DOM_SID *domain_sid,
-                               uint32 status)
-{
-       if (r_e == NULL) return False;
 
+void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
+                           uint32 enum_context, char *domain_name, DOM_SID *domain_sid,
+                           uint32 status)
+{
        DEBUG(5,("make_r_enum_trust_dom\n"));
 
        r_e->enum_context = enum_context;
 
-       if (status == 0)
-       {
+       if (status == 0) {
                int len_domain_name = strlen(domain_name);
 
                r_e->num_domains  = 1;
                r_e->ptr_enum_domains = 1;
                r_e->num_domains2 = 1;
 
-               make_uni_hdr2(&(r_e->hdr_domain_name[0]), len_domain_name);
-               make_unistr2 (&(r_e->uni_domain_name[0]), domain_name, len_domain_name);
-               make_dom_sid2(&(r_e->domain_sid[0]), domain_sid);
-       }
-       else
-       {
+               init_uni_hdr2(&r_e->hdr_domain_name, len_domain_name);
+               init_unistr2 (&r_e->uni_domain_name, domain_name, len_domain_name);
+               init_dom_sid2(&r_e->other_domain_sid, domain_sid);
+       } else {
                r_e->num_domains = 0;
                r_e->ptr_enum_domains = 0;
        }
 
        r_e->status = status;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_R_ENUM_TRUST_DOM structure.
+ Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
 ********************************************************************/
-BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_enum_trust_dom(char *desc,  LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth)
 {
-       if (r_e == NULL) return False;
+       if (r_e == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
        depth++;
 
-       prs_uint32("enum_context    ", ps, depth, &(r_e->enum_context    ));
-       prs_uint32("num_domains     ", ps, depth, &(r_e->num_domains     ));
-       prs_uint32("ptr_enum_domains", ps, depth, &(r_e->ptr_enum_domains));
-
-       if (r_e->ptr_enum_domains != 0)
-       {
-               uint32 i;
-               prs_uint32("num_domains2", ps, depth, &(r_e->num_domains2));
-
-               for (i = 0; i < r_e->num_domains2; i++)
-               {
+       if(!prs_uint32("enum_context    ", ps, depth, &r_e->enum_context))
+               return False;
+       if(!prs_uint32("num_domains     ", ps, depth, &r_e->num_domains))
+               return False;
+       if(!prs_uint32("ptr_enum_domains", ps, depth, &r_e->ptr_enum_domains))
+               return False;
 
-                       smb_io_unihdr2 ("", &(r_e->hdr_domain_name[i]), ps, depth);
-               }
-
-               for (i = 0; i < r_e->num_domains2; i++)
-               {
-                       smb_io_unistr2 ("", &(r_e->uni_domain_name[i] ), r_e->hdr_domain_name[i].buffer, ps, depth);
-                       prs_align(ps);
-                       smb_io_dom_sid2("", &(r_e->domain_sid[i]), ps, depth);
-               }
+       if (r_e->ptr_enum_domains != 0) {
+               if(!prs_uint32("num_domains2", ps, depth, &r_e->num_domains2))
+                       return False;
+               if(!smb_io_unihdr2 ("", &r_e->hdr_domain_name, ps, depth))
+                       return False;
+               if(!smb_io_unistr2 ("", &r_e->uni_domain_name, r_e->hdr_domain_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_dom_sid2("", &r_e->other_domain_sid, ps, depth))
+                       return False;
        }
 
-       prs_uint32("status", ps, depth, &(r_e->status));
+       if(!prs_uint32("status", ps, depth, &r_e->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_Q_QUERY_INFO structure.
+ Reads or writes an LSA_Q_QUERY_INFO structure.
 ********************************************************************/
-BOOL lsa_io_r_query(char *desc,  LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_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, "lsa_io_r_query");
        depth++;
 
-       prs_uint32("undoc_buffer", ps, depth, &(r_q->undoc_buffer));
+       if(!prs_uint32("undoc_buffer", ps, depth, &r_q->undoc_buffer))
+               return False;
 
-       if (r_q->undoc_buffer != 0)
-       {
-               prs_uint16("info_class", ps, depth, &(r_q->info_class));
+       if (r_q->undoc_buffer != 0) {
+               if(!prs_uint16("info_class", ps, depth, &r_q->info_class))
+                       return False;
 
-               switch (r_q->info_class)
-               {
-                       case 3:
-                       {
-                               smb_io_dom_query_3("", &(r_q->dom.id3), ps, depth);
-                               break;
-                       }
-                       case 5:
-                       {
-                               smb_io_dom_query_5("", &(r_q->dom.id3), ps, depth);
-                               break;
-                       }
-                       default:
-                       {
-                               /* PANIC! */
-                               break;
-                       }
+               switch (r_q->info_class) {
+               case 3:
+                       if(!smb_io_dom_query_3("", &r_q->dom.id3, ps, depth))
+                               return False;
+                       break;
+               case 5:
+                       if(!smb_io_dom_query_5("", &r_q->dom.id3, ps, depth))
+                               return False;
+                       break;
+               default:
+                       /* PANIC! */
+                       break;
                }
        }
 
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a LSA_SID_ENUM structure.
+ Inits a LSA_SID_ENUM structure.
 ********************************************************************/
-BOOL make_lsa_sid_enum(LSA_SID_ENUM *sen, uint32 num_entries, DOM_SID **sids)
+
+void init_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids)
 {
-       uint32 i, i2;
-       if (sen == NULL || sids == NULL) return False;
+       int i, i2;
 
        DEBUG(5,("make_lsa_sid_enum\n"));
 
        sen->num_entries  = num_entries;
-       sen->ptr_sid_enum = num_entries != 0 ? 1 : 0;
+       sen->ptr_sid_enum = (num_entries != 0) ? 1 : 0;
        sen->num_entries2 = num_entries;
 
        SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
 
-       for (i = 0, i2 = 0; i < num_entries; i++)
-       {
-               if (sids[i] != NULL)
-               {
+       for (i = 0, i2 = 0; i < num_entries; i++) {
+               if (sids[i] != NULL) {
                        sen->ptr_sid[i] = 1;
-                       make_dom_sid2(&(sen->sid[i2]), sids[i]);
+                       init_dom_sid2(&sen->sid[i2], sids[i]);
                        i2++;
-               }
-               else
-               {
+               } else {
                        sen->ptr_sid[i] = 0;
                }
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a LSA_SID_ENUM structure.
+ Reads or writes a LSA_SID_ENUM structure.
 ********************************************************************/
+
 static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen,
                                prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (sen == NULL) return False;
+       if (sen == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_sid_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("num_entries ", ps, depth, &(sen->num_entries));
-       prs_uint32("ptr_sid_enum", ps, depth, &(sen->ptr_sid_enum)); 
-       prs_uint32("num_entries2", ps, depth, &(sen->num_entries2)); 
+       if(!prs_uint32("num_entries ", ps, depth, &sen->num_entries))
+               return False;
+       if(!prs_uint32("ptr_sid_enum", ps, depth, &sen->ptr_sid_enum))
+               return False;
+       if(!prs_uint32("num_entries2", ps, depth, &sen->num_entries2))
+               return False;
 
        SMB_ASSERT_ARRAY(sen->ptr_sid, sen->num_entries);
 
-       for (i = 0; i < sen->num_entries; i++)
-       {       
+       for (i = 0; i < sen->num_entries; i++) {        
                fstring temp;
                slprintf(temp, sizeof(temp) - 1, "ptr_sid[%d]", i);
-               prs_uint32(temp, ps, depth, &(sen->ptr_sid[i])); /* domain SID pointers to be looked up. */
+               if(!prs_uint32(temp, ps, depth, &sen->ptr_sid[i])) /* domain SID pointers to be looked up. */
+                       return False;
        }
 
        SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
 
-       for (i = 0; i < sen->num_entries; i++)
-       {
+       for (i = 0; i < sen->num_entries; i++) {
                fstring temp;
                slprintf(temp, sizeof(temp) - 1, "sid[%d]", i);
-               smb_io_dom_sid2(temp, &(sen->sid[i]), ps, depth); /* domain SIDs to be looked up. */
+               if(!smb_io_dom_sid2(temp, &sen->sid[i], ps, depth)) /* domain SIDs to be looked up. */
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits an LSA_R_ENUM_TRUST_DOM structure.
 ********************************************************************/
-static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn,
-                               prs_struct *ps, int depth)
+
+void init_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
+                               int num_sids, DOM_SID **sids,
+                               uint16 level)
 {
-       uint32 i;
+       DEBUG(5,("make_r_enum_trust_dom\n"));
 
-       if (trn == NULL) return False;
+       memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
+       init_lsa_sid_enum(&q_l->sids, num_sids, sids);
 
-       prs_debug(ps, depth, desc, "lsa_io_trans_names");
-       depth++;
+       q_l->names.num_entries     = 0;
+       q_l->names.ptr_trans_names = 0;
+       q_l->names.num_entries2    = 0;
 
-       prs_align(ps);
-       
-       prs_uint32("num_entries    ", ps, depth, &(trn->num_entries));
-       prs_uint32("ptr_trans_names", ps, depth, &(trn->ptr_trans_names));
+       q_l->level.value = level;
+}
 
-       if (trn->ptr_trans_names != 0)
-       {
-               prs_uint32("num_entries2   ", ps, depth, &(trn->num_entries2));
-               SMB_ASSERT_ARRAY(trn->name, trn->num_entries);
+/*******************************************************************
+ Reads or writes a LSA_Q_LOOKUP_SIDS structure.
+********************************************************************/
 
-               for (i = 0; i < trn->num_entries2; i++)
-               {
-                       fstring t;
-                       slprintf(t, sizeof(t) - 1, "name[%d] ", i);
+BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth)
+{
+       if (q_s == NULL)
+               return False;
 
-                       lsa_io_trans_name(t, &(trn->name[i]), ps, depth); /* translated name */
+       prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids");
+       depth++;
 
-               }
-               for (i = 0; i < trn->num_entries2; i++)
-               {
-                       fstring t;
-                       slprintf(t, sizeof(t) - 1, "name[%d] ", i);
+       if(!prs_align(ps))
+               return False;
+       
+       if(!smb_io_pol_hnd("pol_hnd", &q_s->pol, ps, depth)) /* policy handle */
+               return False;
+       if(!lsa_io_sid_enum("sids   ", &q_s->sids, ps, depth)) /* sids to be looked up */
+               return False;
+       if(!lsa_io_trans_names("names  ", &q_s->names, ps, depth)) /* translated names */
+               return False;
+       if(!smb_io_lookup_level("switch ", &q_s->level, ps, depth)) /* lookup level */
+               return False;
 
-                       smb_io_unistr2(t, &(trn->uni_name[i]), trn->name[i].hdr_name.buffer, ps, depth);
-                       prs_align(ps);
-               }
-       }
+       if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
-                               int num_sids, DOM_SID **sids,
-                               uint16 level)
+
+static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn,
+                prs_struct *ps, int depth)
 {
-       if (q_l == NULL) return False;
+       int i;
 
-       DEBUG(5,("make_q_lookup_sids\n"));
+       if (trn == NULL)
+               return False;
 
-       memcpy(&(q_l->pol), hnd, sizeof(q_l->pol));
-       make_lsa_sid_enum(&(q_l->sids), num_sids, sids);
+       prs_debug(ps, depth, desc, "lsa_io_trans_names");
+       depth++;
 
-       q_l->names.ptr_trans_names = 0;
-       q_l->names.num_entries     = 0;
+       if(!prs_align(ps))
+               return False;
+   
+       if(!prs_uint32("num_entries    ", ps, depth, &trn->num_entries))
+               return False;
+       if(!prs_uint32("ptr_trans_names", ps, depth, &trn->ptr_trans_names))
+               return False;
 
-       q_l->level.value = level;
-
-       return True;
-}
+       if (trn->ptr_trans_names != 0) {
+               if(!prs_uint32("num_entries2   ", ps, depth, &trn->num_entries2))
+                       return False;
+               SMB_ASSERT_ARRAY(trn->name, trn->num_entries);
 
-/*******************************************************************
-reads or writes a LSA_Q_LOOKUP_SIDS structure.
-********************************************************************/
-BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth)
-{
-       if (q_s == NULL) return False;
+               for (i = 0; i < trn->num_entries2; i++) {
+                       fstring t;
+                       slprintf(t, sizeof(t) - 1, "name[%d] ", i);
 
-       prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids");
-       depth++;
+                       if(!lsa_io_trans_name(t, &trn->name[i], ps, depth)) /* translated name */
+                               return False;
+               }
 
-       prs_align(ps);
-       
-       smb_io_pol_hnd     ("pol_hnd", &(q_s->pol), ps, depth); /* policy handle */
-       lsa_io_sid_enum    ("sids   ", &(q_s->sids   ), ps, depth); /* sids to be looked up */
-       lsa_io_trans_names ("names  ", &(q_s->names  ), ps, depth); /* translated names */
-       smb_io_lookup_level("switch ", &(q_s->level  ), ps, depth); /* lookup level */
+               for (i = 0; i < trn->num_entries2; i++) {
+                       fstring t;
+                       slprintf(t, sizeof(t) - 1, "name[%d] ", i);
 
-       prs_uint32("mapped_count", ps, depth, &(q_s->mapped_count));
+                       if(!smb_io_unistr2(t, &trn->uni_name[i], trn->name[i].hdr_name.buffer, ps, depth))
+                               return False;
+                       if(!prs_align(ps))
+                               return False;
+               }
+       }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth)
 {
-       if (r_s == NULL) return False;
+       if (r_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_dom_ref", ps, depth, &(r_s->ptr_dom_ref));
+       if(!prs_uint32("ptr_dom_ref", ps, depth, &r_s->ptr_dom_ref))
+               return False;
+
        if (r_s->ptr_dom_ref != 0)
-       {
-               lsa_io_dom_r_ref  ("dom_ref", r_s->dom_ref, ps, depth); /* domain reference info */
-       }
-       lsa_io_trans_names("names  ", r_s->names  , ps, depth); /* translated names */
+               if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */
+                       return False;
+
+       if(!lsa_io_trans_names("names  ", r_s->names, ps, depth)) /* translated names */
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("mapped_count", ps, depth, &(r_s->mapped_count));
+       if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count))
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_s->status));
+       if(!prs_uint32("status      ", ps, depth, &r_s->status))
+               return False;
 
        return True;
 }
@@ -936,73 +784,81 @@ BOOL lsa_io_r_lookup_sids(char *desc,  LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, i
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
-                               uint32 num_names, char **names)
+
+void init_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
+                int num_names, char **names)
 {
-       uint32 i;
-       if (q_l == NULL) return False;
+       int i;
 
-       DEBUG(5,("make_q_lookup_names\n"));
+       DEBUG(5,("init_q_lookup_names\n"));
 
-       memcpy(&(q_l->pol), hnd, sizeof(q_l->pol));
+       memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
 
-       q_l->num_entries     = num_names;
-       q_l->num_entries2    = num_names;
+       q_l->num_entries = num_names;
+       q_l->num_entries2 = num_names;
 
        SMB_ASSERT_ARRAY(q_l->uni_name, q_l->num_entries);
 
-       for (i = 0; i < num_names; i++)
-       {
-               const char* name = names[i];
+       for (i = 0; i < num_names; i++) {
+               char* name = names[i];
                int len = strlen(name);
-               make_uni_hdr(&q_l->hdr_name[i], len);
-               make_unistr2(&q_l->uni_name[i], name, len);
+               init_uni_hdr(&q_l->hdr_name[i], len);
+               init_unistr2(&q_l->uni_name[i], name, len);
        }
 
        q_l->num_trans_entries  = 0;
        q_l->ptr_trans_sids  = 0;
        q_l->lookup_level = 1;
        q_l->mapped_count = 0;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL lsa_io_q_lookup_names(char *desc,  LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth)
+
+BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (q_r == NULL) return False;
+       if (q_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_q_lookup_names");
        depth++;
 
-       prs_align(ps);
-       
-       smb_io_pol_hnd("", &(q_r->pol), ps, depth); /* policy handle */
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */
+               return False;
 
-       prs_uint32("num_entries    ", ps, depth, &(q_r->num_entries));
-       prs_uint32("num_entries2   ", ps, depth, &(q_r->num_entries2));
+       if(!prs_uint32("num_entries    ", ps, depth, &q_r->num_entries))
+               return False;
+       if(!prs_uint32("num_entries2   ", ps, depth, &q_r->num_entries2))
+               return False;
 
        SMB_ASSERT_ARRAY(q_r->uni_name, q_r->num_entries);
 
-       for (i = 0; i < q_r->num_entries; i++)
-       {
-               smb_io_unihdr("hdr_name", &(q_r->hdr_name[i]), ps, depth); /* pointer names */
+       for (i = 0; i < q_r->num_entries; i++) {
+               if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */
+                       return False;
        }
 
-       for (i = 0; i < q_r->num_entries; i++)
-       {
-               smb_io_unistr2("dom_name", &(q_r->uni_name[i]), q_r->hdr_name[i].buffer, ps, depth); /* names to be looked up */
-               prs_align(ps);
+       for (i = 0; i < q_r->num_entries; i++) {
+               if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */
+                       return False;
+               if(!prs_align(ps))
+                       return False;
        }
 
-       prs_uint32("num_trans_entries ", ps, depth, &(q_r->num_trans_entries));
-       prs_uint32("ptr_trans_sids ", ps, depth, &(q_r->ptr_trans_sids));
-       prs_uint32("lookup_level   ", ps, depth, &(q_r->lookup_level  ));
-       prs_uint32("mapped_count   ", ps, depth, &(q_r->mapped_count  ));
+       if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries))
+               return False;
+       if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids))
+               return False;
+       if(!prs_uint32("lookup_level   ", ps, depth, &q_r->lookup_level))
+               return False;
+       if(!prs_uint32("mapped_count   ", ps, depth, &q_r->mapped_count))
+               return False;
 
        return True;
 }
@@ -1010,93 +866,102 @@ BOOL lsa_io_q_lookup_names(char *desc,  LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-BOOL lsa_io_r_lookup_names(char *desc,  LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth)
+
+BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (r_r == NULL) return False;
+       if (r_r == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_lookup_names");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("ptr_dom_ref", ps, depth, &(r_r->ptr_dom_ref));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_dom_ref", ps, depth, &r_r->ptr_dom_ref))
+               return False;
+
        if (r_r->ptr_dom_ref != 0)
-       {
-               lsa_io_dom_r_ref("", r_r->dom_ref, ps, depth);
-       }
+               if(!lsa_io_dom_r_ref("", r_r->dom_ref, ps, depth))
+                       return False;
 
-       prs_uint32("num_entries", ps, depth, &(r_r->num_entries));
-       prs_uint32("ptr_entries", ps, depth, &(r_r->ptr_entries));
+       if(!prs_uint32("num_entries", ps, depth, &r_r->num_entries))
+               return False;
+       if(!prs_uint32("ptr_entries", ps, depth, &r_r->ptr_entries))
+               return False;
 
-       if (r_r->ptr_entries != 0)
-       {
-               prs_uint32("num_entries2", ps, depth, &(r_r->num_entries2));
+       if (r_r->ptr_entries != 0) {
+               if(!prs_uint32("num_entries2", ps, depth, &r_r->num_entries2))
+                       return False;
 
-               if (r_r->num_entries2 != r_r->num_entries)
-               {
+               if (r_r->num_entries2 != r_r->num_entries) {
                        /* RPC fault */
                        return False;
                }
 
                for (i = 0; i < r_r->num_entries2; i++)
-               {
-                       smb_io_dom_rid2("", &(r_r->dom_rid[i]), ps, depth); /* domain RIDs being looked up */
-               }
+                       if(!smb_io_dom_rid2("", &r_r->dom_rid[i], ps, depth)) /* domain RIDs being looked up */
+                               return False;
        }
 
-       prs_uint32("mapped_count", ps, depth, &(r_r->mapped_count));
+       if(!prs_uint32("mapped_count", ps, depth, &r_r->mapped_count))
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_r->status));
+       if(!prs_uint32("status      ", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes an LSA_Q_CLOSE structure.
+ Inits an LSA_Q_CLOSE structure.
 ********************************************************************/
-BOOL make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd)
-{
-       if (q_c == NULL || hnd == NULL) return False;
 
+void init_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd)
+{
        DEBUG(5,("make_lsa_q_close\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
-
-       return True;
+       memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
 }
 
 /*******************************************************************
-reads or writes an LSA_Q_CLOSE structure.
+ Reads or writes an LSA_Q_CLOSE structure.
 ********************************************************************/
-BOOL lsa_io_q_close(char *desc,  LSA_Q_CLOSE *q_c, prs_struct *ps, int depth)
+
+BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth)
 {
-       if (q_c == NULL) return False;
+       if (q_c == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_q_close");
        depth++;
 
-       smb_io_pol_hnd("", &(q_c->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &q_c->pol, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an LSA_R_CLOSE structure.
+ Reads or writes an LSA_R_CLOSE structure.
 ********************************************************************/
+
 BOOL lsa_io_r_close(char *desc,  LSA_R_CLOSE *r_c, prs_struct *ps, int depth)
 {
-       if (r_c == NULL) return False;
+       if (r_c == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_r_close");
        depth++;
 
-       smb_io_pol_hnd("", &(r_c->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_c->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_c->status));
+       if(!prs_uint32("status", ps, depth, &r_c->status))
+               return False;
 
        return True;
 }
-
index b38f55983de0c25633e99af53ec1460f4e533991..5277825767f016e0cbf05e1b184800cdb304f8ea 100644 (file)
@@ -1,4 +1,3 @@
-
 /* 
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
 
 extern int DEBUGLEVEL;
 
-
 /*******************************************************************
-reads or writes a BIGINT structure.
+ Reads or writes a UTIME type.
 ********************************************************************/
-BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth)
-{
-       if (bigint == NULL) return False;
 
-       prs_debug(ps, depth, desc, "smb_io_bigint");
-       depth++;
-
-       prs_align(ps);
-       
-       prs_uint32("low ", ps, depth, &(bigint->low ));
-       prs_uint32("high", ps, depth, &(bigint->high));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a UTIME type.
-********************************************************************/
-static BOOL smb_io_utime(char *desc,  UTIME *t, prs_struct *ps, int depth)
+static BOOL smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth)
 {
-       if (t == NULL) return False;
+       if (t == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_utime");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32 ("time", ps, depth, &(t->time));
+       if(!prs_uint32 ("time", ps, depth, &t->time))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an NTTIME structure.
+ Reads or writes an NTTIME structure.
 ********************************************************************/
-BOOL smb_io_time(char *desc,  NTTIME *nttime, prs_struct *ps, int depth)
+
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth)
 {
-       if (nttime == NULL) return False;
+       if (nttime == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_time");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("low ", ps, depth, &(nttime->low )); /* low part */
-       prs_uint32("high", ps, depth, &(nttime->high)); /* high part */
+       if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
+               return False;
+       if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a LOOKUP_LEVEL structure.
+ Reads or writes a LOOKUP_LEVEL structure.
 ********************************************************************/
+
 BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
 {
-       if (level == NULL) return False;
+       if (level == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_lookup_level");
        depth++;
 
-       prs_align(ps);
-       prs_uint16("value", ps, depth, &(level->value));
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint16("value", ps, depth, &level->value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-gets an enumeration handle from an ENUM_HND structure.
+ Gets an enumeration handle from an ENUM_HND structure.
 ********************************************************************/
+
 uint32 get_enum_hnd(ENUM_HND *enh)
 {
        return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
-
-       return True;
 }
 
 /*******************************************************************
-makes an ENUM_HND structure.
+ Inits an ENUM_HND structure.
 ********************************************************************/
-BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd)
-{
-       if (enh == NULL) return False;
 
+void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
+{
        DEBUG(5,("smb_io_enum_hnd\n"));
 
        enh->ptr_hnd = (hnd != 0) ? 1 : 0;
        enh->handle = hnd;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an ENUM_HND structure.
+ Reads or writes an ENUM_HND structure.
 ********************************************************************/
-BOOL smb_io_enum_hnd(char *desc,  ENUM_HND *hnd, prs_struct *ps, int depth)
+
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
 {
-       if (hnd == NULL) return False;
+       if (hnd == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_enum_hnd");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_hnd", ps, depth, &(hnd->ptr_hnd)); /* pointer */
-       if (hnd->ptr_hnd != 0)
-       {
-               prs_uint32("handle ", ps, depth, &(hnd->handle )); /* enum handle */
+       if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
+               return False;
+
+       if (hnd->ptr_hnd != 0) {
+               if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_SID structure.
+ Reads or writes a DOM_SID structure.
 ********************************************************************/
-BOOL smb_io_dom_sid(char *desc,  DOM_SID *sid, prs_struct *ps, int depth)
+
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth)
 {
        int i;
 
-       if (sid == NULL) return False;
+       if (sid == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_dom_sid");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint8 ("sid_rev_num", ps, depth, &(sid->sid_rev_num)); 
-       prs_uint8 ("num_auths  ", ps, depth, &(sid->num_auths));
+       if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
+               return False;
+       if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
+               return False;
 
        for (i = 0; i < 6; i++)
        {
                fstring tmp;
                slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
-               prs_uint8 (tmp, ps, depth, &(sid->id_auth[i]));
+               if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
+                       return False;
        }
 
        /* oops! XXXX should really issue a warning here... */
-       if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
+       if (sid->num_auths > MAXSUBAUTHS)
+               sid->num_auths = MAXSUBAUTHS;
 
-       prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths);
+       if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a DOM_SID2 structure.
+ Inits a DOM_SID structure.
+
+ BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 
+ identauth >= 2^32 can be detected because it will be specified in hex
 ********************************************************************/
-BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
+
+void init_dom_sid(DOM_SID *sid, char *str_sid)
 {
-        sid_copy(&sid2->sid, sid);
-       sid2->num_auths = sid2->sid.num_auths;
+       pstring domsid;
+       int identauth;
+       char *p;
 
-       return True;
-}
+       if (str_sid == NULL)
+       {
+               DEBUG(4,("netlogon domain SID: none\n"));
+               sid->sid_rev_num = 0;
+               sid->num_auths = 0;
+               return;
+       }
+               
+       pstrcpy(domsid, str_sid);
 
-/*******************************************************************
-reads or writes a DOM_SID2 structure.
-********************************************************************/
-BOOL smb_io_dom_sid2(char *desc,  DOM_SID2 *sid, prs_struct *ps, int depth)
-{
-       if (sid == NULL) return False;
+       DEBUG(4,("init_dom_sid %d SID:  %s\n", __LINE__, domsid));
 
-       prs_debug(ps, depth, desc, "smb_io_dom_sid2");
-       depth++;
+       /* assume, but should check, that domsid starts "S-" */
+       p = strtok(domsid+2,"-");
+       sid->sid_rev_num = atoi(p);
 
-       prs_align(ps);
-       
-       prs_uint32("num_auths", ps, depth, &(sid->num_auths));
+       /* identauth in decimal should be <  2^32 */
+       /* identauth in hex     should be >= 2^32 */
+       identauth = atoi(strtok(0,"-"));
 
-       smb_io_dom_sid("sid", &(sid->sid), ps, depth);
+       DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
+       DEBUG(4,("netlogon %s ia %d\n", p, identauth));
 
-       return True;
+       sid->id_auth[0] = 0;
+       sid->id_auth[1] = 0;
+       sid->id_auth[2] = (identauth & 0xff000000) >> 24;
+       sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
+       sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
+       sid->id_auth[5] = (identauth & 0x000000ff);
+
+       sid->num_auths = 0;
+
+       while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
+               sid->sub_auths[sid->num_auths++] = atoi(p);
+
+       DEBUG(4,("init_dom_sid: %d SID:  %s\n", __LINE__, domsid));
 }
 
 /*******************************************************************
-creates a STRHDR structure.
+ Inits a DOM_SID2 structure.
 ********************************************************************/
-BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
-{
-       hdr->str_max_len = max_len;
-       hdr->str_str_len = len;
-       hdr->buffer      = buffer;
 
-       return True;
+void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid)
+{
+       sid2->sid = *sid;
+       sid2->num_auths = sid2->sid.num_auths;
 }
 
 /*******************************************************************
-reads or writes a STRHDR structure.
+ Reads or writes a DOM_SID2 structure.
 ********************************************************************/
-BOOL smb_io_strhdr(char *desc,  STRHDR *hdr, prs_struct *ps, int depth)
+
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
 {
-       if (hdr == NULL) return False;
+       if (sid == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "smb_io_strhdr");
+       prs_debug(ps, depth, desc, "smb_io_dom_sid2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint16("str_str_len", ps, depth, &(hdr->str_str_len));
-       prs_uint16("str_max_len", ps, depth, &(hdr->str_max_len));
-       prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
+       if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
+               return False;
 
-       /* oops! XXXX maybe issue a warning that this is happening... */
-       if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
-       if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
+       if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a STRHDR2 structure.
+creates a STRHDR structure.
 ********************************************************************/
-BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer)
+
+void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
 {
        hdr->str_max_len = max_len;
        hdr->str_str_len = len;
        hdr->buffer      = buffer;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a STRHDR2 structure.
+ Reads or writes a STRHDR structure.
 ********************************************************************/
-BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth)
+
+BOOL smb_io_strhdr(char *desc,  STRHDR *hdr, prs_struct *ps, int depth)
 {
-       if (hdr == NULL) return False;
+       if (hdr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_strhdr");
        depth++;
 
        prs_align(ps);
        
-       prs_uint32("str_str_len", ps, depth, &(hdr->str_str_len));
-       prs_uint32("str_max_len", ps, depth, &(hdr->str_max_len));
-       prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
+       if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
+               return False;
+       if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
+               return False;
+       if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
+               return False;
 
        /* oops! XXXX maybe issue a warning that this is happening... */
-       if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
-       if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
+       if (hdr->str_max_len > MAX_STRINGLEN)
+               hdr->str_max_len = MAX_STRINGLEN;
+       if (hdr->str_str_len > MAX_STRINGLEN)
+               hdr->str_str_len = MAX_STRINGLEN;
 
        return True;
 }
 
 /*******************************************************************
-creates a UNIHDR structure.
+ Inits a UNIHDR structure.
 ********************************************************************/
-BOOL make_uni_hdr(UNIHDR *hdr, int len)
+
+void init_uni_hdr(UNIHDR *hdr, int len)
 {
        hdr->uni_str_len = 2 * len;
        hdr->uni_max_len = 2 * len;
        hdr->buffer      = len != 0 ? 1 : 0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a UNIHDR structure.
+ Reads or writes a UNIHDR structure.
 ********************************************************************/
-BOOL smb_io_unihdr(char *desc,  UNIHDR *hdr, prs_struct *ps, int depth)
+
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
 {
-       if (hdr == NULL) return False;
+       if (hdr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_unihdr");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint16("uni_str_len", ps, depth, &(hdr->uni_str_len));
-       prs_uint16("uni_max_len", ps, depth, &(hdr->uni_max_len));
-       prs_uint32("buffer     ", ps, depth, &(hdr->buffer     ));
+       if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
+               return False;
+       if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
+               return False;
+       if(!prs_uint32("buffer     ", ps, depth, &hdr->buffer))
+               return False;
 
        /* oops! XXXX maybe issue a warning that this is happening... */
-       if (hdr->uni_max_len > MAX_UNISTRLEN) hdr->uni_max_len = MAX_UNISTRLEN;
-       if (hdr->uni_str_len > MAX_UNISTRLEN) hdr->uni_str_len = MAX_UNISTRLEN;
+       if (hdr->uni_max_len > MAX_UNISTRLEN)
+               hdr->uni_max_len = MAX_UNISTRLEN;
+       if (hdr->uni_str_len > MAX_UNISTRLEN)
+               hdr->uni_str_len = MAX_UNISTRLEN;
 
        return True;
 }
 
 /*******************************************************************
-creates a BUFHDR structure.
+ Inits a BUFHDR structure.
 ********************************************************************/
-BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len)
+
+void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
 {
        hdr->buf_max_len = max_len;
        hdr->buf_len     = len;
-
-       return True;
 }
 
 /*******************************************************************
- prs_uint16 wrapper.  call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading
+ prs_uint16 wrapper. Call this and it sets up a pointer to where the
+ uint16 should be stored, or gets the size if reading.
  ********************************************************************/
-BOOL smb_io_hdrbuf_pre(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
+
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
 {
-       (*offset) = ps->offset;
-       if (ps->io)
-       {
+       (*offset) = prs_offset(ps);
+       if (ps->io) {
+
                /* reading. */
-               smb_io_hdrbuf(desc, hdr, ps, depth);
-       }
-       else
-       {
-               ps->offset += sizeof(uint32) * 2;
+
+               if(!smb_io_hdrbuf(desc, hdr, ps, depth))
+                       return False;
+
+       } else {
+
+               /* writing. */
+
+               if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
- smb_io_hdrbuf wrapper.  call this and it retrospectively stores the size.
does nothing on reading, as that is already handled by ...._pre()
+ smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
Does nothing on reading, as that is already handled by ...._pre()
  ********************************************************************/
-BOOL smb_io_hdrbuf_post(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth, 
+
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, 
                                uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
 {
-       if (!ps->io)
-       {
-               /* storing: go back and do a retrospective job.  i hate this */
-               uint32 old_offset = ps->offset;
+       if (!ps->io) {
+               /* writing: go back and do a retrospective job.  i hate this */
+
+               uint32 old_offset = prs_offset(ps);
 
-               make_buf_hdr(hdr, max_len, len);
-               ps->offset = ptr_hdrbuf;
-               smb_io_hdrbuf(desc, hdr, ps, depth);
-               ps->offset = old_offset;
+               init_buf_hdr(hdr, max_len, len);
+               if(!prs_set_offset(ps, ptr_hdrbuf))
+                       return False;
+               if(!smb_io_hdrbuf(desc, hdr, ps, depth))
+                       return False;
+
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a BUFHDR structure.
+ Reads or writes a BUFHDR structure.
 ********************************************************************/
-BOOL smb_io_hdrbuf(char *desc,  BUFHDR *hdr, prs_struct *ps, int depth)
+
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
 {
-       if (hdr == NULL) return False;
+       if (hdr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_hdrbuf");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("buf_max_len", ps, depth, &(hdr->buf_max_len));
-       prs_uint32("buf_len    ", ps, depth, &(hdr->buf_len    ));
+       if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
+               return False;
+       if(!prs_uint32("buf_len    ", ps, depth, &hdr->buf_len))
+               return False;
 
        /* oops! XXXX maybe issue a warning that this is happening... */
-       if (hdr->buf_max_len > MAX_BUFFERLEN) hdr->buf_max_len = MAX_BUFFERLEN;
-       if (hdr->buf_len     > MAX_BUFFERLEN) hdr->buf_len     = MAX_BUFFERLEN;
+       if (hdr->buf_max_len > MAX_BUFFERLEN)
+               hdr->buf_max_len = MAX_BUFFERLEN;
+       if (hdr->buf_len > MAX_BUFFERLEN)
+               hdr->buf_len = MAX_BUFFERLEN;
 
        return True;
 }
 
 /*******************************************************************
-creates a BUFHDR2 structure.
+creates a UNIHDR2 structure.
 ********************************************************************/
-BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
-{
-       hdr->info_level = info_level;
-       hdr->length     = length;
-       hdr->buffer     = buffer;
-
-       return True;
-}
 
-/*******************************************************************
-reads or writes a BUFHDR2 structure.
-********************************************************************/
-BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
+void init_uni_hdr2(UNIHDR2 *hdr, int len)
 {
-       if (hdr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "smb_io_bufhdr2");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("info_level", ps, depth, &(hdr->info_level));
-       prs_uint32("length    ", ps, depth, &(hdr->length    ));
-       prs_uint32("buffer    ", ps, depth, &(hdr->buffer    ));
-
-       return True;
+       init_uni_hdr(&hdr->unihdr, len);
+       hdr->buffer = (len > 0) ? 1 : 0;
 }
 
 /*******************************************************************
-creates a UNIHDR2 structure.
+ Reads or writes a UNIHDR2 structure.
 ********************************************************************/
-BOOL make_uni_hdr2(UNIHDR2 *hdr, int len)
-{
-       make_uni_hdr(&(hdr->unihdr), len);
-       hdr->buffer = len > 0 ? 1 : 0;
-
-       return True;
-}
 
-/*******************************************************************
-reads or writes a UNIHDR2 structure.
-********************************************************************/
-BOOL smb_io_unihdr2(char *desc,  UNIHDR2 *hdr2, prs_struct *ps, int depth)
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
 {
-       if (hdr2 == NULL) return False;
+       if (hdr2 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_unihdr2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unihdr("hdr", &(hdr2->unihdr), ps, depth);
-       prs_uint32("buffer", ps, depth, &(hdr2->buffer));
+       if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
+               return False;
+       if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a UNISTR structure.
+ Inits a UNISTR structure.
 ********************************************************************/
-BOOL make_unistr(UNISTR *str, char *buf)
-{
-       ascii_to_unistr(str->buffer, buf, sizeof(str->buffer)-1);
 
-       return True;
+void init_unistr(UNISTR *str, char *buf)
+{
+       /* store the string (null-terminated copy) */
+       dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
 }
 
 /*******************************************************************
 reads or writes a UNISTR structure.
 XXXX NOTE: UNISTR structures NEED to be null-terminated.
 ********************************************************************/
-BOOL smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps, int depth)
+
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
 {
-       if (uni == NULL) return False;
+       if (uni == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_unistr");
        depth++;
 
-       prs_unistr("unistr", ps, depth, uni);
+       if(!prs_align(ps))
+               return False;
+       if(!prs_unistr("unistr", ps, depth, uni))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a BUFFER3 structure from a uint32
+ Inits a BUFFER3 structure from a uint32
 ********************************************************************/
-BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val)
+
+void init_buffer3_uint32(BUFFER3 *str, uint32 val)
 {
        ZERO_STRUCTP(str);
 
@@ -482,14 +515,13 @@ BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val)
        str->buf_len     = sizeof(uint32);
 
        SIVAL(str->buffer, 0, val);
-
-       return True;
 }
 
 /*******************************************************************
-creates a BUFFER3 structure.
+ Inits a BUFFER3 structure.
 ********************************************************************/
-BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len)
+
+void init_buffer3_str(BUFFER3 *str, char *buf, int len)
 {
        ZERO_STRUCTP(str);
 
@@ -497,364 +529,238 @@ BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len)
        str->buf_max_len = len * 2;
        str->buf_len     = len * 2;
 
-       /* store the string (little endian buffer) */
-       ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
-
-       return True;
+       /* store the string (null-terminated 8 bit chars into 16 bit chars) */
+       dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
 }
 
 /*******************************************************************
-creates a BUFFER3 structure from a hex string.
+ Inits a BUFFER3 structure from a hex string.
 ********************************************************************/
-BOOL make_buffer3_hex(BUFFER3 *str, char *buf)
+
+void init_buffer3_hex(BUFFER3 *str, char *buf)
 {
        ZERO_STRUCTP(str);
        str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
-
-       return True;
 }
 
 /*******************************************************************
-creates a BUFFER3 structure.
+ Inits a BUFFER3 structure.
 ********************************************************************/
-BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
+
+void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
 {
        ZERO_STRUCTP(str);
 
        /* max buffer size (allocated size) */
        str->buf_max_len = len;
        if (buf != NULL)
-       {
                memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer)));
-       }
        str->buf_len = buf != NULL ? len : 0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a BUFFER3 structure.
-     the uni_max_len member tells you how large the buffer is.
-     the uni_str_len member tells you how much of the buffer is really used.
+ Reads or writes a BUFFER3 structure.
+   the uni_max_len member tells you how large the buffer is.
+   the uni_str_len member tells you how much of the buffer is really used.
 ********************************************************************/
-BOOL smb_io_buffer3(char *desc,  BUFFER3 *buf3, prs_struct *ps, int depth)
-{
-       if (buf3 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "smb_io_buffer3");
-       depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("uni_max_len", ps, depth, &(buf3->buf_max_len));
-       if (buf3->buf_max_len > MAX_UNISTRLEN) buf3->buf_max_len = MAX_UNISTRLEN;
-
-       prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len);
-
-       prs_uint32("buf_len    ", ps, depth, &(buf3->buf_len));
-       if (buf3->buf_len     > MAX_UNISTRLEN) buf3->buf_len     = MAX_UNISTRLEN;
-
-       return True;
-}
-
-/*******************************************************************
-creates a BUFFER4 structure.
-********************************************************************/
-BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len)
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
 {
-       ZERO_STRUCTP(str);
-
-       /* set up string lengths. */
-       str->buf_len     = len * 2;
+       if (buf3 == NULL)
+               return False;
 
-       /* store the string (little endian buffer) */
-       ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a BUFFER4 structure.
-********************************************************************/
-BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
-{
-       if ((buf4 == NULL) || (buffer == 0)) return False;
-
-       prs_debug(ps, depth, desc, "smb_io_buffer4");
+       prs_debug(ps, depth, desc, "smb_io_buffer3");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
-
-       if (buf4->buf_len > MAX_BUFFERLEN)
-       {
-               buf4->buf_len = MAX_BUFFERLEN;
-       }
-
-       prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
-
-       return True;
-}
-
-/*******************************************************************
-initialise a BUFFER5 structure.
-********************************************************************/
-BOOL init_buffer5(BUFFER5 **str)
-{
-       BUFFER5 *buf5;
-               
-       buf5=(BUFFER5 *)malloc( sizeof(BUFFER5) );
-       
-       buf5->buf_len=0;
-       buf5->buffer=NULL;      
-       *str=buf5;
-
-       return True;
-}
-
-/*******************************************************************
-clear a BUFFER5 structure.
-********************************************************************/
-BOOL clear_buffer5(BUFFER5 **str)
-{
-       BUFFER5 *buf5;
+       if(!prs_align(ps))
+               return False;
        
-       buf5=*str;      
-       if (buf5->buffer != NULL )
-       {
-               free(buf5->buffer);
-       }
-       free(buf5);
-       *str=NULL;
+       if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
+               return False;
 
-       return True;
-}
+       if (buf3->buf_max_len > MAX_UNISTRLEN)
+               buf3->buf_max_len = MAX_UNISTRLEN;
 
-/*******************************************************************
-creates a BUFFER5 structure.
-********************************************************************/
-BOOL make_buffer5(BUFFER5 *str, char *buf, int len)
-{
+       if(!prs_uint8s(True, "buffer     ", ps, depth, buf3->buffer, buf3->buf_max_len))
+               return False;
 
-       /* max buffer size (allocated size) */
-       str->buf_len = len;     
-       str->buffer = (uint16 *)malloc( sizeof(uint16) * len ); 
-       ascii_to_unistr(str->buffer, buf, len);
+       if(!prs_uint32("buf_len    ", ps, depth, &buf3->buf_len))
+               return False;
+       if (buf3->buf_len > MAX_UNISTRLEN)
+               buf3->buf_len = MAX_UNISTRLEN;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a BUFFER5 structure.
-the buf_len member tells you how large the buffer is.
+ Inits a BUFFER2 structure.
 ********************************************************************/
-BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
-{
-       prs_debug(ps, depth, desc, "smb_io_buffer4");
-       depth++;
-
-       if (buf5 == NULL) return False;
-
-       prs_align(ps);
-       prs_uint32("buf_len", ps, depth, &(buf5->buf_len));
-
-       /* reading: alloc the buffer first */
-       if ( ps->io )
-       {
-               buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len );
-       }
-       
-       prs_uint16s(True, "buffer     ", ps, depth, buf5->buffer, buf5->buf_len);
-
-       return True;
-}
 
-/*******************************************************************
-creates a BUFFER2 structure.
-********************************************************************/
-BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num)
+void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
 {
-       int i;
-       char *dest = (char*)str->buffer;
-       size_t max_len = sizeof(str->buffer)-1;
-
        ZERO_STRUCTP(str);
 
-       str->buf_max_len = 0;
+       /* max buffer size (allocated size) */
+       str->buf_max_len = len;
        str->undoc       = 0;
+       str->buf_len = buf != NULL ? len : 0;
 
-       for (i = 0; i < num && max_len > 0; i++)
-       {
-               size_t len = buf[i] != NULL ? strlen(buf[i]) : 0;
-
-               str->buf_max_len += len * 2;
-               str->buf_len     += len * 2;
-
-               ascii_to_unibuf(dest, buf[i], max_len);
-       
-               dest += len * 2 + 2;
-               max_len -= len * 2 + 2;
-       }
-
-       return True;
+       if (buf != NULL)
+               memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer)));
 }
 
 /*******************************************************************
-creates a BUFFER2 structure.
+ Reads or writes a BUFFER2 structure.
+   the uni_max_len member tells you how large the buffer is.
+   the uni_str_len member tells you how much of the buffer is really used.
 ********************************************************************/
-BOOL make_buffer2(BUFFER2 *str, const char *buf, int len)
-{
-       ZERO_STRUCTP(str);
 
-       /* set up string lengths. */
-       str->buf_max_len = str->buf_len = len * 2;
-       str->undoc       = 0;
-
-       /* store the string */
-       ascii_to_unibuf((char*)str->buffer, buf,
-                        MIN(str->buf_len, sizeof(str->buffer)-1));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a BUFFER2 structure.
-     the uni_max_len member tells you how large the buffer is.
-     the uni_str_len member tells you how much of the buffer is really used.
-********************************************************************/
-BOOL smb_io_buffer2(char *desc,  BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
 {
-       if (buf2 == NULL) return False;
+       if (buf2 == NULL)
+               return False;
+
+       if (buffer) {
 
-       if (buffer)
-       {
                prs_debug(ps, depth, desc, "smb_io_buffer2");
                depth++;
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
                
-               prs_uint32("buf_max_len", ps, depth, &(buf2->buf_max_len));
-               prs_uint32("undoc      ", ps, depth, &(buf2->undoc      ));
-               prs_uint32("buf_len    ", ps, depth, &(buf2->buf_len));
+               if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
+                       return False;
+               if(!prs_uint32("undoc      ", ps, depth, &buf2->undoc))
+                       return False;
+               if(!prs_uint32("buf_len    ", ps, depth, &buf2->buf_len))
+                       return False;
 
                /* oops! XXXX maybe issue a warning that this is happening... */
-               if (buf2->buf_max_len > MAX_UNISTRLEN) buf2->buf_max_len = MAX_UNISTRLEN;
-               if (buf2->buf_len     > MAX_UNISTRLEN) buf2->buf_len     = MAX_UNISTRLEN;
+               if (buf2->buf_max_len > MAX_UNISTRLEN)
+                       buf2->buf_max_len = MAX_UNISTRLEN;
+               if (buf2->buf_len > MAX_UNISTRLEN)
+                       buf2->buf_len = MAX_UNISTRLEN;
 
                /* buffer advanced by indicated length of string
                   NOT by searching for null-termination */
-               prs_buffer2(True, "buffer     ", ps, depth, buf2);
-       }
-       else
-       {
+
+               if(!prs_buffer2(True, "buffer     ", ps, depth, buf2))
+                       return False;
+
+       } else {
+
                prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
                depth++;
-               bzero(buf2, sizeof(*buf2));
-       }
+               memset((char *)buf2, '\0', sizeof(*buf2));
 
+       }
        return True;
 }
 
 /*******************************************************************
 creates a UNISTR2 structure: sets up the buffer, too
 ********************************************************************/
-BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
+
+void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf)
 {
-       if (buf != NULL)
-       {
+       if (buf != NULL) {
+
                *ptr = 1;
-               make_unistr2(str, buf, strlen(buf)+1);
-       }
-       else
-       {
+               init_unistr2(str, buf, strlen(buf)+1);
+
+       } else {
+
                *ptr = 0;
-               make_unistr2(str, "", 0);
-       }
+               init_unistr2(str, "", 0);
 
-       return True;
+       }
 }
 
 /*******************************************************************
-creates a STRING2 structure.
+ Copies a UNISTR2 structure.
 ********************************************************************/
-BOOL make_string2(STRING2 *str, const char *buf, int len)
-{
-       /* set up string lengths. */
-       str->str_max_len = len;
-       str->undoc       = 0;
-       str->str_str_len = len;
 
-       /* store the string */
-       if(len != 0)
-       {
-               memcpy(str->buffer, buf, len);
-       }
+void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
+{
+       /* set up string lengths. add one if string is not null-terminated */
+       str->uni_max_len = from->uni_max_len;
+       str->undoc       = from->undoc;
+       str->uni_str_len = from->uni_str_len;
 
-       return True;
+       /* copy the string */
+       memcpy(str->buffer, from->buffer, sizeof(from->buffer));
 }
 
 /*******************************************************************
-creates a STRING2 structure: sets up the buffer, too
+ Creates a STRING2 structure.
 ********************************************************************/
-BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf)
+
+void init_string2(STRING2 *str, char *buf, int len)
 {
-       if (buf != NULL)
-       {
-               *ptr = 1;
-               make_string2(str, buf, strlen(buf)+1);
-       }
-       else
-       {
-               *ptr = 0;
-               make_string2(str, "", 0);
-       }
+  /* set up string lengths. */
+  str->str_max_len = len;
+  str->undoc       = 0;
+  str->str_str_len = len;
 
-       return True;
+  /* store the string */
+  if(len != 0)
+    memcpy(str->buffer, buf, len);
 }
 
 /*******************************************************************
-reads or writes a STRING2 structure.
-XXXX NOTE: STRING2 structures need NOT be null-terminated.
-     the str_str_len member tells you how long the string is;
-     the str_max_len member tells you how large the buffer is.
+ Reads or writes a STRING2 structure.
+ XXXX NOTE: STRING2 structures need NOT be null-terminated.
+   the str_str_len member tells you how long the string is;
+   the str_max_len member tells you how large the buffer is.
 ********************************************************************/
-BOOL smb_io_string2(char *desc,  STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
+
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
 {
-       if (str2 == NULL) return False;
+       if (str2 == NULL)
+               return False;
+
+       if (buffer) {
 
-       if (buffer)
-       {
                prs_debug(ps, depth, desc, "smb_io_string2");
                depth++;
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
                
-               prs_uint32("str_max_len", ps, depth, &(str2->str_max_len));
-               prs_uint32("undoc      ", ps, depth, &(str2->undoc      ));
-               prs_uint32("str_str_len", ps, depth, &(str2->str_str_len));
+               if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
+                       return False;
+               if(!prs_uint32("undoc      ", ps, depth, &str2->undoc))
+                       return False;
+               if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
+                       return False;
 
                /* oops! XXXX maybe issue a warning that this is happening... */
-               if (str2->str_max_len > MAX_STRINGLEN) str2->str_max_len = MAX_STRINGLEN;
-               if (str2->str_str_len > MAX_STRINGLEN) str2->str_str_len = MAX_STRINGLEN;
+               if (str2->str_max_len > MAX_STRINGLEN)
+                       str2->str_max_len = MAX_STRINGLEN;
+               if (str2->str_str_len > MAX_STRINGLEN)
+                       str2->str_str_len = MAX_STRINGLEN;
 
                /* buffer advanced by indicated length of string
                   NOT by searching for null-termination */
-               prs_string2(True, "buffer     ", ps, depth, str2);
-       }
-       else
-       {
+               if(!prs_string2(True, "buffer     ", ps, depth, str2))
+                       return False;
+
+       } else {
+
                prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
                depth++;
-               bzero(str2, sizeof(*str2));
+               memset((char *)str2, '\0', sizeof(*str2));
+
        }
 
        return True;
 }
 
 /*******************************************************************
-creates a UNISTR2 structure.
+ Inits a UNISTR2 structure.
 ********************************************************************/
-BOOL make_unistr2(UNISTR2 *str, const char *buf, int len)
+
+void init_unistr2(UNISTR2 *str, char *buf, int len)
 {
        ZERO_STRUCTP(str);
 
@@ -863,79 +769,93 @@ BOOL make_unistr2(UNISTR2 *str, const char *buf, int len)
        str->undoc       = 0;
        str->uni_str_len = len;
 
-       /* store the string (wide chars) */
-       ascii_to_unistr(str->buffer, buf, len);
-
-       return True;
+       /* store the string (null-terminated 8 bit chars into 16 bit chars) */
+       dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
 }
 
 /*******************************************************************
-reads or writes a UNISTR2 structure.
-XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
-     the uni_str_len member tells you how long the string is;
-     the uni_max_len member tells you how large the buffer is.
+ Reads or writes a UNISTR2 structure.
+ XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
+   the uni_str_len member tells you how long the string is;
+   the uni_max_len member tells you how large the buffer is.
 ********************************************************************/
-BOOL smb_io_unistr2(char *desc,  UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
+
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
 {
-       if (uni2 == NULL) return False;
+       if (uni2 == NULL)
+               return False;
+
+       if (buffer) {
 
-       if (buffer)
-       {
                prs_debug(ps, depth, desc, "smb_io_unistr2");
                depth++;
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
                
-               prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len));
-               prs_uint32("undoc      ", ps, depth, &(uni2->undoc      ));
-               prs_uint32("uni_str_len", ps, depth, &(uni2->uni_str_len));
+               if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
+                       return False;
+               if(!prs_uint32("undoc      ", ps, depth, &uni2->undoc))
+                       return False;
+               if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
+                       return False;
 
                /* oops! XXXX maybe issue a warning that this is happening... */
-               if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
-               if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
+               if (uni2->uni_max_len > MAX_UNISTRLEN)
+                       uni2->uni_max_len = MAX_UNISTRLEN;
+               if (uni2->uni_str_len > MAX_UNISTRLEN)
+                       uni2->uni_str_len = MAX_UNISTRLEN;
 
                /* buffer advanced by indicated length of string
                   NOT by searching for null-termination */
-               prs_unistr2(True, "buffer     ", ps, depth, uni2);
-       }
-       else
-       {
+               if(!prs_unistr2(True, "buffer     ", ps, depth, uni2))
+                       return False;
+
+       } else {
+
                prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
                depth++;
-               bzero(uni2, sizeof(*uni2));
+               memset((char *)uni2, '\0', sizeof(*uni2));
+
        }
 
        return True;
 }
 
 /*******************************************************************
-creates a DOM_RID2 structure.
+ Inits a DOM_RID2 structure.
 ********************************************************************/
-BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
+
+void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
 {
        rid2->type    = type;
        rid2->rid     = rid;
        rid2->rid_idx = idx;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_RID2 structure.
+ Reads or writes a DOM_RID2 structure.
 ********************************************************************/
-BOOL smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps, int depth)
+
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
 {
-       if (rid2 == NULL) return False;
+       if (rid2 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_dom_rid2");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint8("type   ", ps, depth, &(rid2->type));
-       prs_align(ps);
-       prs_uint32("rid    ", ps, depth, &(rid2->rid     ));
-       prs_uint32("rid_idx", ps, depth, &(rid2->rid_idx ));
+       if(!prs_align(ps))
+               return False;
+   
+       if(!prs_uint8("type   ", ps, depth, &rid2->type))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("rid    ", ps, depth, &rid2->rid))
+               return False;
+       if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
+               return False;
 
        return True;
 }
@@ -943,414 +863,495 @@ BOOL smb_io_dom_rid2(char *desc,  DOM_RID2 *rid2, prs_struct *ps, int depth)
 /*******************************************************************
 creates a DOM_RID3 structure.
 ********************************************************************/
-BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
-{
-       rid3->rid      = rid;
-       rid3->type1    = type;
-       rid3->ptr_type = 0x1; /* non-zero, basically. */
-       rid3->type2    = 0x1;
-       rid3->unk      = type;
 
-       return True;
+void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
+{
+    rid3->rid      = rid;
+    rid3->type1    = type;
+    rid3->ptr_type = 0x1; /* non-zero, basically. */
+    rid3->type2    = 0x1;
+    rid3->unk      = type;
 }
 
 /*******************************************************************
 reads or writes a DOM_RID3 structure.
 ********************************************************************/
-BOOL smb_io_dom_rid3(char *desc,  DOM_RID3 *rid3, prs_struct *ps, int depth)
+
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
 {
-       if (rid3 == NULL) return False;
+       if (rid3 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_dom_rid3");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("rid     ", ps, depth, &(rid3->rid     ));
-       prs_uint32("type1   ", ps, depth, &(rid3->type1   ));
-       prs_uint32("ptr_type", ps, depth, &(rid3->ptr_type));
-       prs_uint32("type2   ", ps, depth, &(rid3->type2   ));
-       prs_uint32("unk     ", ps, depth, &(rid3->unk     ));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("rid     ", ps, depth, &rid3->rid))
+               return False;
+       if(!prs_uint32("type1   ", ps, depth, &rid3->type1))
+               return False;
+       if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
+               return False;
+       if(!prs_uint32("type2   ", ps, depth, &rid3->type2))
+               return False;
+       if(!prs_uint32("unk     ", ps, depth, &rid3->unk))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a DOM_CLNT_SRV structure.
+ Inits a DOM_RID4 structure.
 ********************************************************************/
-static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
-                               const char *logon_srv, 
-                               const char *comp_name)
+
+void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
 {
-       if (log == NULL) return False;
+    rid4->unknown = unknown;
+    rid4->attr    = attr;
+    rid4->rid     = rid;
+}
 
-       DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
+/*******************************************************************
+ Inits a DOM_CLNT_SRV structure.
+********************************************************************/
 
-       if (logon_srv != NULL)
-       {
+static void init_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name)
+{
+       DEBUG(5,("init_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);
-       }
-       else
-       {
+               init_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
+       } else {
                log->undoc_buffer = 0;
        }
 
-       if (comp_name != NULL)
-       {
+       if (comp_name != NULL) {
                log->undoc_buffer2 = 1;
-               make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
-       }
-       else
-       {
+               init_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+       } else {
                log->undoc_buffer2 = 0;
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_CLNT_SRV structure.
+ Inits 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);
+       if(!prs_align(ps))
+               return False;
        
-       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);
+       if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
+               return False;
+
+       if (log->undoc_buffer != 0) {
+               if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
+                       return False;
        }
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       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);
+       if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
+               return False;
+
+       if (log->undoc_buffer2 != 0) {
+               if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-makes a DOM_LOG_INFO structure.
+ Inits 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)
-{
-       if (log == NULL) return False;
 
+void init_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
+               uint16 sec_chan, char *comp_name)
+{
        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);
+       init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
+       init_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);
-
-       return True;
+       init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
 }
 
 /*******************************************************************
-reads or writes a DOM_LOG_INFO structure.
+ 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);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
+       if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
+               return False;
 
-       smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
-       smb_io_unistr2("unistr2", &(log->uni_acct_name), True, ps, depth);
+       if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
+               return False;
 
-       prs_uint16("sec_chan", ps, depth, &(log->sec_chan));
+       if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
+               return False;
 
-       smb_io_unistr2("unistr2", &(log->uni_comp_name), True, ps, depth);
+       if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_CHAL structure.
+ Reads or writes a DOM_CHAL structure.
 ********************************************************************/
-BOOL smb_io_chal(char *desc,  DOM_CHAL *chal, prs_struct *ps, int depth)
+
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
 {
-       if (chal == NULL) return False;
+       if (chal == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_chal");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint8s (False, "data", ps, depth, chal->data, 8);
+       if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_CRED structure.
+ Reads or writes a DOM_CRED structure.
 ********************************************************************/
+
 BOOL smb_io_cred(char *desc,  DOM_CRED *cred, prs_struct *ps, int depth)
 {
-       if (cred == NULL) return False;
+       if (cred == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_cred");
        depth++;
 
-       prs_align(ps);
-       
-       smb_io_chal ("", &(cred->challenge), ps, depth);
-       smb_io_utime("", &(cred->timestamp), ps, depth);
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_chal ("", &cred->challenge, ps, depth))
+               return False;
+       if(!smb_io_utime("", &cred->timestamp, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a DOM_CLNT_INFO2 structure.
+ Inits a DOM_CLNT_INFO2 structure.
 ********************************************************************/
-BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
-                               const char *logon_srv, const char *comp_name,
+
+void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
+                               char *logon_srv, char *comp_name,
                                DOM_CRED *clnt_cred)
 {
-       if (clnt == NULL) return False;
-
        DEBUG(5,("make_clnt_info: %d\n", __LINE__));
 
-       make_clnt_srv(&(clnt->login), logon_srv, comp_name);
+       init_clnt_srv(&(clnt->login), logon_srv, comp_name);
 
-       if (clnt_cred != NULL)
-       {
+       if (clnt_cred != NULL) {
                clnt->ptr_cred = 1;
                memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
-       }
-       else
-       {
+       } else {
                clnt->ptr_cred = 0;
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_CLNT_INFO2 structure.
+ 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);
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_clnt_srv("", &(clnt->login), ps, depth);
+       if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
-       smb_io_cred    ("", &(clnt->cred ), ps, depth);
+       if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
+               return False;
+       if(!smb_io_cred("", &clnt->cred, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a DOM_CLNT_INFO structure.
+ Inits 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,
+
+void init_clnt_info(DOM_CLNT_INFO *clnt,
+               char *logon_srv, char *acct_name,
+               uint16 sec_chan, char *comp_name,
                                DOM_CRED *cred)
 {
-       if (clnt == NULL || cred == NULL) return False;
-
        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));
-
-       return True;
+       init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
+       memcpy(&clnt->cred, cred, sizeof(clnt->cred));
 }
 
 /*******************************************************************
-reads or writes a DOM_CLNT_INFO structure.
+ Reads or writes a DOM_CLNT_INFO structure.
 ********************************************************************/
+
 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);
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_log_info("", &(clnt->login), ps, depth);
-       smb_io_cred    ("", &(clnt->cred ), ps, depth);
+       if(!smb_io_log_info("", &clnt->login, ps, depth))
+               return False;
+       if(!smb_io_cred("", &clnt->cred, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an OWF_INFO structure.
+ Inits a DOM_LOGON_ID structure.
 ********************************************************************/
-BOOL make_owf_info(OWF_INFO *hash, uint8 data[16])
+
+void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
 {
-       if (hash == NULL) return False;
+       DEBUG(5,("make_logon_id: %d\n", __LINE__));
+
+       log->low  = log_id_low;
+       log->high = log_id_high;
+}
+
+/*******************************************************************
+ Reads or writes a DOM_LOGON_ID structure.
+********************************************************************/
 
-       DEBUG(5,("make_owf_info: %d\n", __LINE__));
+BOOL smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
+{
+       if (log == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "smb_io_logon_id");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       
+       if(!prs_uint32("low ", ps, depth, &log->low ))
+               return False;
+       if(!prs_uint32("high", ps, depth, &log->high))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Inits an OWF_INFO structure.
+********************************************************************/
+
+void init_owf_info(OWF_INFO *hash, uint8 data[16])
+{
+       DEBUG(5,("init_owf_info: %d\n", __LINE__));
        
        if (data != NULL)
-       {
                memcpy(hash->data, data, sizeof(hash->data));
-       }
        else
-       {
-               bzero(hash->data, sizeof(hash->data));
-       }
-
-       return True;
+               memset((char *)hash->data, '\0', sizeof(hash->data));
 }
 
 /*******************************************************************
-reads or writes an OWF_INFO structure.
+ Reads or writes an OWF_INFO structure.
 ********************************************************************/
+
 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);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint8s (False, "data", ps, depth, hash->data, 16);
+       if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_GID structure.
+ Reads or writes a DOM_GID structure.
 ********************************************************************/
+
 BOOL smb_io_gid(char *desc,  DOM_GID *gid, prs_struct *ps, int depth)
 {
-       if (gid == NULL) return False;
+       if (gid == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_gid");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("g_rid", ps, depth, &(gid->g_rid));
-       prs_uint32("attr ", ps, depth, &(gid->attr ));
+       if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
+               return False;
+       if(!prs_uint32("attr ", ps, depth, &gid->attr))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes an POLICY_HND structure.
+ Reads or writes an POLICY_HND structure.
 ********************************************************************/
-BOOL smb_io_pol_hnd(char *desc,  POLICY_HND *pol, prs_struct *ps, int depth)
+
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
 {
-       if (pol == NULL) return False;
+       if (pol == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_pol_hnd");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE);
+       if(!prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a dom query structure.
+ Reads or writes a dom query structure.
 ********************************************************************/
-static BOOL smb_io_dom_query(char *desc,  DOM_QUERY *d_q, prs_struct *ps, int depth)
+
+static BOOL smb_io_dom_query(char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth)
 {
-       if (d_q == NULL) return False;
+       if (d_q == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_dom_query");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint16("uni_dom_max_len", ps, depth, &(d_q->uni_dom_max_len)); /* domain name string length * 2 */
-       prs_uint16("uni_dom_str_len", ps, depth, &(d_q->uni_dom_str_len)); /* domain name string length * 2 */
-
-       prs_uint32("buffer_dom_name", ps, depth, &(d_q->buffer_dom_name)); /* undocumented domain name string buffer pointer */
-       prs_uint32("buffer_dom_sid ", ps, depth, &(d_q->buffer_dom_sid )); /* undocumented domain SID string buffer pointer */
+       if(!prs_uint16("uni_dom_max_len", ps, depth, &d_q->uni_dom_max_len)) /* domain name string length * 2 */
+               return False;
+       if(!prs_uint16("uni_dom_str_len", ps, depth, &d_q->uni_dom_str_len)) /* domain name string length * 2 */
+               return False;
 
-       smb_io_unistr2("unistr2", &(d_q->uni_domain_name), d_q->buffer_dom_name, ps, depth); /* domain name (unicode string) */
+       if(!prs_uint32("buffer_dom_name", ps, depth, &d_q->buffer_dom_name)) /* undocumented domain name string buffer pointer */
+               return False;
+       if(!prs_uint32("buffer_dom_sid ", ps, depth, &d_q->buffer_dom_sid)) /* undocumented domain SID string buffer pointer */
+               return False;
 
-       prs_align(ps);
+       if(!smb_io_unistr2("unistr2", &d_q->uni_domain_name, d_q->buffer_dom_name, ps, depth)) /* domain name (unicode string) */
+               return False;
 
-       if (d_q->buffer_dom_sid != 0)
-       {
-               smb_io_dom_sid2("", &(d_q->dom_sid), ps, depth); /* domain SID */
-       }
-       else
-       {
-               bzero(&(d_q->dom_sid), sizeof(d_q->dom_sid));
+       if(!prs_align(ps))
+               return False;
+       
+       if (d_q->buffer_dom_sid != 0) {
+               if(!smb_io_dom_sid2("", &d_q->dom_sid, ps, depth)) /* domain SID */
+                       return False;
+       } else {
+               memset((char *)&d_q->dom_sid, '\0', sizeof(d_q->dom_sid));
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a dom query structure.
+ Reads or writes a dom query structure.
 ********************************************************************/
-BOOL smb_io_dom_query_3(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
-{
-       smb_io_dom_query("", d_q, ps, depth);
 
-       return True;
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+{
+       return smb_io_dom_query("", d_q, ps, depth);
 }
 
 /*******************************************************************
-reads or writes a dom query structure.
+ Reads or writes a dom query structure.
 ********************************************************************/
-BOOL smb_io_dom_query_5(char *desc,  DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
-{
-       smb_io_dom_query("", d_q, ps, depth);
 
-       return True;
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+{
+       return smb_io_dom_query("", d_q, ps, depth);
 }
 
 
 /*******************************************************************
-reads or writes a UNISTR3 structure.
+ Reads or writes a UNISTR3 structure.
 ********************************************************************/
-BOOL smb_io_unistr3(char *desc,  UNISTR3 *name, prs_struct *ps, int depth)
+
+BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth)
 {
-       if (name == NULL) return False;
+       if (name == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_unistr3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("uni_str_len", ps, depth, &(name->uni_str_len));
+       if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
+               return False;
 
        /* don't know if len is specified by uni_str_len member... */
        /* assume unicode string is unicode-null-terminated, instead */
 
-       prs_unistr3(True, "unistr", name, ps, depth);
+       if(!prs_unistr3(True, "unistr", name, ps, depth))
+               return False;
 
        return True;
 }
-
index 277c2331b410f2978215fd9d328e6b4a0c56197f..9588d1c53b3332a9b1521be5b1cc005b811676ee 100644 (file)
 extern int DEBUGLEVEL;
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL net_io_neg_flags(char *desc,  NEG_FLAGS *neg, prs_struct *ps, int depth)
+
+static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
 {
-       if (neg == NULL) return False;
+       if (neg == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_neg_flags");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("neg_flags", ps, depth, &(neg->neg_flags));
+       if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a NETLOGON_INFO_3 structure.
+ Inits a NETLOGON_INFO_3 structure.
 ********************************************************************/
-static BOOL make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
+
+static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
 {
        info->flags          = flags;
        info->logon_attempts = logon_attempts;
@@ -55,67 +60,80 @@ static BOOL make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_att
        info->reserved_3     = 0x0;
        info->reserved_4     = 0x0;
        info->reserved_5     = 0x0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a NETLOGON_INFO_3 structure.
+ 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)
 {
-       if (info == NULL) return False;
+       if (info == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_netinfo_3");
        depth++;
 
-       prs_align(ps);
-       
-       prs_uint32("flags         ", ps, depth, &(info->flags         ));
-       prs_uint32("logon_attempts", ps, depth, &(info->logon_attempts));
-       prs_uint32("reserved_1    ", ps, depth, &(info->reserved_1    ));
-       prs_uint32("reserved_2    ", ps, depth, &(info->reserved_2    ));
-       prs_uint32("reserved_3    ", ps, depth, &(info->reserved_3    ));
-       prs_uint32("reserved_4    ", ps, depth, &(info->reserved_4    ));
-       prs_uint32("reserved_5    ", ps, depth, &(info->reserved_5    ));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("flags         ", ps, depth, &info->flags))
+               return False;
+       if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
+               return False;
+       if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
+               return False;
+       if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
+               return False;
+       if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
+               return False;
+       if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
+               return False;
+       if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-creates a NETLOGON_INFO_1 structure.
+ Inits a NETLOGON_INFO_1 structure.
 ********************************************************************/
-static BOOL make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
+
+static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
 {
        info->flags      = flags;
        info->pdc_status = pdc_status;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a NETLOGON_INFO_1 structure.
+ 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)
+
+static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
 {
-       if (info == NULL) return False;
+       if (info == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_netinfo_1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("flags     ", ps, depth, &(info->flags     ));
-       prs_uint32("pdc_status", ps, depth, &(info->pdc_status));
+       if(!prs_uint32("flags     ", ps, depth, &info->flags))
+               return False;
+       if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates a NETLOGON_INFO_2 structure.
+ Inits a NETLOGON_INFO_2 structure.
 ********************************************************************/
-static BOOL make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
+
+static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
                                uint32 tc_status, char *trusted_dc_name)
 {
        int len_dc_name = strlen(trusted_dc_name);
@@ -125,544 +143,499 @@ static BOOL make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_statu
        info->tc_status  = tc_status;
 
        if (trusted_dc_name != NULL)
-       {
-               make_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
-       }
+               init_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
        else
-       {
-               make_unistr2(&(info->uni_trusted_dc_name), "", 1);
-       }
-
-       return True;
+               init_unistr2(&(info->uni_trusted_dc_name), "", 1);
 }
 
 /*******************************************************************
-reads or writes a NETLOGON_INFO_2 structure.
+ 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)
+
+static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
 {
-       if (info == NULL) return False;
+       if (info == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_netinfo_2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("flags              ", ps, depth, &(info->flags              ));
-       prs_uint32("pdc_status         ", ps, depth, &(info->pdc_status         ));
-       prs_uint32("ptr_trusted_dc_name", ps, depth, &(info->ptr_trusted_dc_name));
-       prs_uint32("tc_status          ", ps, depth, &(info->tc_status          ));
-
-       if (info->ptr_trusted_dc_name != 0)
-       {
-               smb_io_unistr2("unistr2", &(info->uni_trusted_dc_name), info->ptr_trusted_dc_name, ps, depth);
+       if(!prs_uint32("flags              ", ps, depth, &info->flags))
+               return False;
+       if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
+               return False;
+       if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
+               return False;
+       if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
+               return False;
+
+       if (info->ptr_trusted_dc_name != 0) {
+               if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
+                       return False;
        }
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an NET_Q_LOGON_CTRL2 structure.
+ Reads or writes an NET_Q_LOGON_CTRL2 structure.
 ********************************************************************/
-BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, 
-                               const char* srv_name,
-                               uint32 function_code,
-                               uint32 query_level,
-                               uint32 switch_value)
-{
-       if (q_l == NULL) return False;
-
-       DEBUG(5,("make_q_logon_ctrl2\n"));
-
-       q_l->ptr = 1;
-
-       make_unistr2(&(q_l->uni_server_name ), srv_name , strlen(srv_name )+1);
 
-       q_l->function_code = function_code;
-       q_l->query_level   = query_level;
-       q_l->switch_value  = switch_value;
-
-       return True;
-}
-
-/*******************************************************************
-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)
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
 {
-       if (q_l == NULL) return False;
+       if (q_l == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr          ", ps, depth, &(q_l->ptr          ));
+       if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
+               return False;
 
-       smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
+       if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("function_code", ps, depth, &(q_l->function_code));
-       prs_uint32("query_level  ", ps, depth, &(q_l->query_level  ));
-       prs_uint32("switch_value ", ps, depth, &(q_l->switch_value ));
+       if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
+               return False;
+       if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
+               return False;
+       if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an NET_R_LOGON_CTRL2 structure.
+ Inits an NET_R_LOGON_CTRL2 structure.
 ********************************************************************/
-BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
+
+void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
                                uint32 flags, uint32 pdc_status, uint32 logon_attempts,
                                uint32 tc_status, char *trusted_domain_name)
 {
-       if (r_l == NULL) return False;
-
        DEBUG(5,("make_r_logon_ctrl2\n"));
 
        r_l->switch_value  = query_level; /* should only be 0x1 */
 
-       switch (query_level)
-       {
-               case 1:
-               {
-                       r_l->ptr = 1; /* undocumented pointer */
-                       make_netinfo_1(&(r_l->logon.info1), flags, pdc_status); 
-                       r_l->status = 0;
-
-                       break;
-               }
-               case 2:
-               {
-                       r_l->ptr = 1; /* undocumented pointer */
-                       make_netinfo_2(&(r_l->logon.info2), flags, pdc_status,
-                                      tc_status, trusted_domain_name); 
-                       r_l->status = 0;
-
-                       break;
-               }
-               case 3:
-               {
-                       r_l->ptr = 1; /* undocumented pointer */
-                       make_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
-                       r_l->status = 0;
-
-                       break;
-               }
-               default:
-               {
-                       DEBUG(2,("make_r_logon_ctrl2: unsupported switch value %d\n",
-                               r_l->switch_value));
-                       r_l->ptr = 0; /* undocumented pointer */
-
-                       /* take a guess at an error code... */
-                       r_l->status = NT_STATUS_INVALID_INFO_CLASS;
-
-                       break;
-               }
+       switch (query_level) {
+       case 1:
+               r_l->ptr = 1; /* undocumented pointer */
+               init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
+               r_l->status = 0;
+               break;
+       case 2:
+               r_l->ptr = 1; /* undocumented pointer */
+               init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
+                              tc_status, trusted_domain_name); 
+               r_l->status = 0;
+               break;
+       case 3:
+               r_l->ptr = 1; /* undocumented pointer */
+               init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
+               r_l->status = 0;
+               break;
+       default:
+               DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
+                       r_l->switch_value));
+               r_l->ptr = 0; /* undocumented pointer */
+
+               /* take a guess at an error code... */
+               r_l->status = NT_STATUS_INVALID_INFO_CLASS;
+               break;
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an NET_R_LOGON_CTRL2 structure.
+ 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)
+
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
 {
-       if (r_l == NULL) return False;
+       if (r_l == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
        depth++;
 
-       prs_uint32("switch_value ", ps, depth, &(r_l->switch_value ));
-       prs_uint32("ptr          ", ps, depth, &(r_l->ptr          ));
-
-       if (r_l->ptr != 0)
-       {
-               switch (r_l->switch_value)
-               {
-                       case 1:
-                       {
-                               net_io_netinfo_1("", &(r_l->logon.info1), ps, depth);
-                               break;
-                       }
-                       case 2:
-                       {
-                               net_io_netinfo_2("", &(r_l->logon.info2), ps, depth);
-                               break;
-                       }
-                       case 3:
-                       {
-                               net_io_netinfo_3("", &(r_l->logon.info3), ps, depth);
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
-                                       r_l->switch_value));
-                               break;
-                       }
+       if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
+               return False;
+       if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
+               return False;
+
+       if (r_l->ptr != 0) {
+               switch (r_l->switch_value) {
+               case 1:
+                       if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
+                               return False;
+                       break;
+               case 2:
+                       if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
+                               return False;
+                       break;
+               case 3:
+                       if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
+                               return False;
+                       break;
+               default:
+                       DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
+                               r_l->switch_value));
+                       break;
                }
        }
 
-       prs_uint32("status       ", ps, depth, &(r_l->status       ));
+       if(!prs_uint32("status       ", ps, depth, &r_l->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an NET_R_TRUST_DOM_LIST structure.
+ Inits an NET_R_TRUST_DOM_LIST structure.
 ********************************************************************/
-BOOL make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
-                       uint32 num_doms, char **dom_name)
+
+void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
+                       uint32 num_doms, char *dom_name)
 {
-       if (r_t == NULL) return False;
+       int i = 0;
 
        DEBUG(5,("make_r_trust_dom\n"));
 
-       make_buffer2_multi(&r_t->uni_trust_dom_name,
-                       dom_name, num_doms);
-       if (num_doms == 0)
-       {
-               r_t->uni_trust_dom_name.buf_max_len = 0x2;
-               r_t->uni_trust_dom_name.buf_len = 0x2;
+       for (i = 0; i < MAX_TRUST_DOMS; i++) {
+               r_t->uni_trust_dom_name[i].uni_str_len = 0;
+               r_t->uni_trust_dom_name[i].uni_max_len = 0;
+       }
+       if (num_doms > MAX_TRUST_DOMS)
+               num_doms = MAX_TRUST_DOMS;
+
+       for (i = 0; i < num_doms; i++) {
+               fstring domain_name;
+               fstrcpy(domain_name, dom_name);
+               strupper(domain_name);
+               init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
+               /* the use of UNISTR2 here is non-standard. */
+               r_t->uni_trust_dom_name[i].undoc = 0x1;
        }
-       r_t->uni_trust_dom_name.undoc = 0x1;
        
        r_t->status = 0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an NET_R_TRUST_DOM_LIST structure.
+ 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)
+
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
 {
-       if (r_t == NULL) return False;
+       int i;
+       if (r_t == NULL)
+                return False;
 
        prs_debug(ps, depth, desc, "net_io_r_trust_dom");
        depth++;
 
-       smb_io_buffer2("", &r_t->uni_trust_dom_name, True, ps, depth);
-       prs_align(ps);
+       for (i = 0; i < MAX_TRUST_DOMS; i++) {
+               if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
+                       break;
+               if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
+                        return False;
+       }
 
-       prs_uint32("status", ps, depth, &(r_t->status));
+       if(!prs_uint32("status", ps, depth, &r_t->status))
+                return False;
 
        return True;
 }
 
 
 /*******************************************************************
-reads or writes an NET_Q_TRUST_DOM_LIST structure.
+ 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)
+
+BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
 {
-       if (q_l == NULL) return False;
+       if (q_l == NULL)
+                return False;
 
        prs_debug(ps, depth, desc, "net_io_q_trust_dom");
        depth++;
 
-       prs_uint32("ptr", ps, depth, &(q_l->ptr));
-       smb_io_unistr2 ("name", &(q_l->uni_server_name), q_l->ptr, ps, depth);
+       if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
+                return False;
+       if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
+                return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+                return False;
 
-       prs_uint32("function_code", ps, depth, &(q_l->function_code));
+       if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
+                return False;
 
        return True;
 }
 
 /*******************************************************************
-makes an NET_Q_REQ_CHAL structure.
+ Inits an NET_Q_REQ_CHAL structure.
 ********************************************************************/
-BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
-                               const char *logon_srv, const char *logon_clnt,
+
+void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
+                               char *logon_srv, char *logon_clnt,
                                DOM_CHAL *clnt_chal)
 {
-       if (q_c == NULL) return False;
-
        DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
 
        q_c->undoc_buffer = 1; /* don't know what this buffer is */
 
-       make_unistr2(&(q_c->uni_logon_srv ), logon_srv , strlen(logon_srv )+1);
-       make_unistr2(&(q_c->uni_logon_clnt), logon_clnt, strlen(logon_clnt)+1);
+       init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
+       init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
 
        memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
 
        DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an NET_Q_REQ_CHAL structure.
+ 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, int depth)
 {
        int old_align;
-       if (q_c == NULL) return False;
+
+       if (q_c == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_req_chal");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       prs_uint32("undoc_buffer", ps, depth, &(q_c->undoc_buffer));
+       if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
+               return False;
 
-       smb_io_unistr2("", &(q_c->uni_logon_srv ), True, ps, depth); /* logon server unicode string */
-       smb_io_unistr2("", &(q_c->uni_logon_clnt), True, ps, depth); /* logon client unicode string */
+       if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
+               return False;
+       if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
+               return False;
 
        old_align = ps->align;
        ps->align = 0;
        /* client challenge is _not_ aligned after the unicode strings */
-       smb_io_chal("", &(q_c->clnt_chal), ps, depth); /* client challenge */
+       if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
+               /* client challenge */
+               ps->align = old_align;
+               return False;
+       }
        ps->align = old_align;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_req_chal(char *desc,  NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
+
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
 {
-       if (r_c == NULL) return False;
+       if (r_c == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_r_req_chal");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       smb_io_chal("", &(r_c->srv_chal), ps, depth); /* server challenge */
+       if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_c->status));
+       if(!prs_uint32("status", ps, depth, &r_c->status))
+               return False;
 
        return True;
 }
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-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)
-{
-       if (q_a == NULL) return False;
-
-       DEBUG(5,("make_q_auth: %d\n", __LINE__));
-
-       make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
-       memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
-
-       DEBUG(5,("make_q_auth: %d\n", __LINE__));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL net_io_q_auth(char *desc,  NET_Q_AUTH *q_a, prs_struct *ps, int depth)
-{
-       int old_align;
-       if (q_a == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_q_auth");
-       depth++;
-
-       prs_align(ps);
-    
-       smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
-       /* client challenge is _not_ aligned */
-       old_align = ps->align;
-       ps->align = 0;
-       smb_io_chal     ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
-       ps->align = old_align;
-
-       return True;
-}
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a NET_Q_AUTH_2 struct.
 ********************************************************************/
-BOOL net_io_r_auth(char *desc,  NET_R_AUTH *r_a, prs_struct *ps, int depth)
-{
-       if (r_a == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_r_auth");
-       depth++;
-
-       prs_align(ps);
-    
-       smb_io_chal     ("", &(r_a->srv_chal), ps, depth); /* server challenge */
-       prs_uint32("status", ps, depth, &(r_a->status));
-
-       return True;
-}
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-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,
+void init_q_auth_2(NET_Q_AUTH_2 *q_a,
+               char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
                DOM_CHAL *clnt_chal, uint32 clnt_flgs)
 {
-       if (q_a == NULL) return False;
-
-       DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
+       DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
 
-       make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
+       init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
        memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
        q_a->clnt_flgs.neg_flags = clnt_flgs;
 
-       DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
-
-       return True;
+       DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_auth_2(char *desc,  NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
+
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
 {
        int old_align;
-       if (q_a == NULL) return False;
+       if (q_a == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_auth_2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
+       if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
+               return False;
        /* client challenge is _not_ aligned */
        old_align = ps->align;
        ps->align = 0;
-       smb_io_chal     ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
+       if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
+               /* client-calculated credentials */
+               ps->align = old_align;
+               return False;
+       }
        ps->align = old_align;
-       net_io_neg_flags("", &(q_a->clnt_flgs), ps, depth);
+       if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
+
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
 {
-       if (r_a == NULL) return False;
+       if (r_a == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_r_auth_2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       smb_io_chal     ("", &(r_a->srv_chal), ps, depth); /* server challenge */
-       net_io_neg_flags("", &(r_a->srv_flgs), ps, depth);
+       if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
+               return False;
+       if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_a->status));
+       if(!prs_uint32("status", ps, depth, &r_a->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a NET_Q_SRV_PWSET.
 ********************************************************************/
-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])
-{
-       if (q_s == NULL || cred == NULL) return False;
 
+void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
+                uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
+{
        DEBUG(5,("make_q_srv_pwset\n"));
 
-       make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
+       init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
 
        memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
+
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
 {
-       if (q_s == NULL) return False;
+       if (q_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
-       prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
+       if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
+               return False;
+       if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
+
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
 {
-       if (r_s == NULL) return False;
+       if (r_s == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
     
-       smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
+       if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_s->status));
+       if(!prs_uint32("status", ps, depth, &r_s->status))
+               return False;
 
        return True;
 }
 
-
 /*************************************************************************
make DOM_SID2 array from a string containing multiple sids
Init DOM_SID2 array from a string containing multiple sids
  *************************************************************************/
-static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
+
+static int init_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
 {
        char *ptr;
        pstring s2;
-       int count;
+       int count = 0;
 
-       DEBUG(4,("make_dom_sid2s: %s\n", sids_str ? sids_str:""));
+       DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
 
-       if (sids_str == NULL || *sids_str == 0) return 0;
-
-       for (count = 0, ptr = sids_str; 
-            next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; 
-            count++) 
-       {
-                DOM_SID tmpsid;
-                string_to_sid(&tmpsid, s2);
-               make_dom_sid2(&sids[count], &tmpsid);
+       if(sids_str) {
+               for (count = 0, ptr = sids_str; 
+                 next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; count++) {
+                       DOM_SID tmpsid;
+                       string_to_sid(&tmpsid, s2);
+                       init_dom_sid2(&sids[count], &tmpsid);
+               }
        }
 
        return count;
-
-       return True;
 }
 
 /*******************************************************************
-makes a NET_ID_INFO_1 structure.
+ Inits a NET_ID_INFO_1 structure.
 ********************************************************************/
-BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+
+void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
                                uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
-                               const char *user_name, const char *wksta_name,
+                               char *user_name, char *wksta_name,
                                char sess_key[16],
                                unsigned char lm_cypher[16], unsigned char nt_cypher[16])
 {
@@ -673,30 +646,26 @@ BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
        unsigned char lm_owf[16];
        unsigned char nt_owf[16];
 
-       if (id == NULL) return False;
-
        DEBUG(5,("make_id_info1: %d\n", __LINE__));
 
        id->ptr_id_info1 = 1;
 
-       make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
+       init_uni_hdr(&id->hdr_domain_name, len_domain_name);
 
        id->param_ctrl = param_ctrl;
-       id->logon_id.low = log_id_low;
-       id->logon_id.high = log_id_high;
+       init_logon_id(&id->logon_id, log_id_low, log_id_high);
 
-       make_uni_hdr(&(id->hdr_user_name  ), len_user_name  );
-       make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
+       init_uni_hdr(&id->hdr_user_name, len_user_name);
+       init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
 
-       if (lm_cypher && nt_cypher)
-       {
+       if (lm_cypher && nt_cypher) {
                unsigned char key[16];
 #ifdef DEBUG_PASSWORD
                DEBUG(100,("lm cypher:"));
-               dump_data(100, lm_cypher, 16);
+               dump_data(100, (char *)lm_cypher, 16);
 
                DEBUG(100,("nt cypher:"));
-               dump_data(100, nt_cypher, 16);
+               dump_data(100, (char *)nt_cypher, 16);
 #endif
 
                memset(key, 0, 16);
@@ -709,63 +678,77 @@ BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
 
 #ifdef DEBUG_PASSWORD
                DEBUG(100,("encrypt of lm owf password:"));
-               dump_data(100, lm_owf, 16);
+               dump_data(100, (char *)lm_owf, 16);
 
                DEBUG(100,("encrypt of nt owf password:"));
-               dump_data(100, nt_owf, 16);
+               dump_data(100, (char *)nt_owf, 16);
 #endif
                /* set up pointers to cypher blocks */
                lm_cypher = lm_owf;
                nt_cypher = nt_owf;
        }
 
-       make_owf_info(&(id->lm_owf), lm_cypher);
-       make_owf_info(&(id->nt_owf), nt_cypher);
-
-       make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
-       make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
-       make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
+       init_owf_info(&id->lm_owf, lm_cypher);
+       init_owf_info(&id->nt_owf, nt_cypher);
 
-       return True;
+       init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
+       init_unistr2(&id->uni_user_name, user_name, len_user_name);
+       init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
 }
 
 /*******************************************************************
-reads or writes an NET_ID_INFO_1 structure.
+ 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, int depth)
 {
-       if (id == NULL) return False;
+       if (id == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_id_info1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
+       if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
+               return False;
 
-       if (id->ptr_id_info1 != 0)
-       {
-               smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
+       if (id->ptr_id_info1 != 0) {
+               if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
+                       return False;
 
-               prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
-               smb_io_bigint("", &(id->logon_id), ps, depth);
+               if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
+                       return False;
+               if(!smb_io_logon_id("", &id->logon_id, ps, depth))
+                       return False;
 
-               smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
-               smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
+               if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
+                       return False;
+               if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
+                       return False;
 
-               smb_io_owf_info("", &(id->lm_owf), ps, depth);
-               smb_io_owf_info("", &(id->nt_owf), ps, depth);
+               if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
+                       return False;
+               if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
+                       return False;
 
-               smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
-               smb_io_unistr2("unistr2", &(id->uni_user_name  ), id->hdr_user_name.buffer, ps, depth);
-               smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
+               if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
+                               id->hdr_domain_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_unistr2("unistr2", &id->uni_user_name,
+                               id->hdr_user_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
+                               id->hdr_wksta_name.buffer, ps, depth))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-makes a NET_ID_INFO_2 structure.
+Inits a NET_ID_INFO_2 structure.
 
 This is a network logon packet. The log_id parameters
 are what an NT server would generate for LUID once the
@@ -779,10 +762,9 @@ checking for a logon as it doesn't export the password
 hashes to anyone who has compromised the secure channel. JRA.
 ********************************************************************/
 
-BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
-                               uint32 param_ctrl,
-                               uint32 log_id_low, uint32 log_id_high,
-                               const char *user_name, const char *wksta_name,
+void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
+                               uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+                               char *user_name, char *wksta_name,
                                unsigned char lm_challenge[8],
                                unsigned char lm_chal_resp[24],
                                unsigned char nt_chal_resp[24])
@@ -790,87 +772,101 @@ BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
        int len_domain_name = strlen(domain_name);
        int len_user_name   = strlen(user_name  );
        int len_wksta_name  = strlen(wksta_name );
-       int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
+       int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
        int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
        unsigned char lm_owf[24];
        unsigned char nt_owf[24];
 
-       if (id == NULL) return False;
-
-       DEBUG(5,("make_id_info2: %d\n", __LINE__));
+       DEBUG(5,("init_id_info2: %d\n", __LINE__));
 
        id->ptr_id_info2 = 1;
 
-       make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
+       init_uni_hdr(&id->hdr_domain_name, len_domain_name);
 
        id->param_ctrl = param_ctrl;
-       id->logon_id.low = log_id_low;
-       id->logon_id.high = log_id_high;
+       init_logon_id(&id->logon_id, log_id_low, log_id_high);
 
-       make_uni_hdr(&(id->hdr_user_name  ), len_user_name  );
-       make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
+       init_uni_hdr(&id->hdr_user_name, len_user_name);
+       init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
 
-       if (nt_chal_resp)
-       {
+       if (nt_chal_resp) {
                /* oops.  can only send what-ever-it-is direct */
                memcpy(nt_owf, nt_chal_resp, 24);
                nt_chal_resp = nt_owf;
        }
-       if (lm_chal_resp)
-       {
+       if (lm_chal_resp) {
                /* oops.  can only send what-ever-it-is direct */
                memcpy(lm_owf, lm_chal_resp, 24);
                lm_chal_resp = lm_owf;
        }
 
        memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
-       make_str_hdr(&(id->hdr_nt_chal_resp), 24, nt_chal_resp_len, nt_chal_resp != NULL ? 1 : 0);
-       make_str_hdr(&(id->hdr_lm_chal_resp), 24, lm_chal_resp_len, lm_chal_resp != NULL ? 1 : 0);
-
-       make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
-       make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
-       make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
+       init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
+       init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
 
-       make_string2(&(id->nt_chal_resp ), (char *)nt_chal_resp , nt_chal_resp_len);
-       make_string2(&(id->lm_chal_resp ), (char *)lm_chal_resp , lm_chal_resp_len);
+       init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
+       init_unistr2(&id->uni_user_name, user_name, len_user_name);
+       init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
 
-       return True;
+       init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
+       init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
 }
 
 /*******************************************************************
-reads or writes an NET_ID_INFO_2 structure.
+ 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, int depth)
 {
-       if (id == NULL) return False;
+       if (id == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_id_info2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
+       if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
+               return False;
 
-       if (id->ptr_id_info2 != 0)
-       {
-               smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
+       if (id->ptr_id_info2 != 0) {
+               if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
+                       return False;
 
-               prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
-               smb_io_bigint("", &(id->logon_id), ps, depth);
+               if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
+                       return False;
+               if(!smb_io_logon_id("", &id->logon_id, ps, depth))
+                       return False;
 
-               smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
-               smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
+               if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
+                       return False;
+               if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
+                       return False;
 
-               prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
+               if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
+                       return False;
 
-               smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
-               smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
+               if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
+                       return False;
 
-               smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
-               smb_io_unistr2("uni_user_name  ", &(id->uni_user_name  ), id->hdr_user_name   .buffer, ps, depth);
-               smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name  .buffer, ps, depth);
-               smb_io_string2("nt_chal_resp"   , &(id->nt_chal_resp)   , id->hdr_nt_chal_resp.buffer, ps, depth);
-               smb_io_string2("lm_chal_resp"   , &(id->lm_chal_resp)   , id->hdr_lm_chal_resp.buffer, ps, depth);
+               if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
+                               id->hdr_domain_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
+                               id->hdr_user_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
+                               id->hdr_wksta_name.buffer, ps, depth))
+                       return False;
+               if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
+                               id->hdr_nt_chal_resp.buffer, ps, depth))
+                       return False;
+               if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
+                               id->hdr_lm_chal_resp.buffer, ps, depth))
+                       return False;
        }
 
        return True;
@@ -878,104 +874,103 @@ static BOOL net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int
 
 
 /*******************************************************************
-makes a DOM_SAM_INFO structure.
+ Inits a DOM_SAM_INFO structure.
 ********************************************************************/
-BOOL make_sam_info(DOM_SAM_INFO *sam,
-                               const char *logon_srv, const char *comp_name,
-                               DOM_CRED *clnt_cred,
+
+void init_sam_info(DOM_SAM_INFO *sam,
+                               char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
                                DOM_CRED *rtn_cred, uint16 logon_level,
                                NET_ID_INFO_CTR *ctr)
 {
-       if (sam == NULL) return False;
-
-       DEBUG(5,("make_sam_info: %d\n", __LINE__));
+       DEBUG(5,("init_sam_info: %d\n", __LINE__));
 
-       make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
+       init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
 
-       if (rtn_cred != NULL)
-       {
+       if (rtn_cred != NULL) {
                sam->ptr_rtn_cred = 1;
-               memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
-       }
-       else
-       {
+               memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
+       } else {
                sam->ptr_rtn_cred = 0;
        }
 
        sam->logon_level  = logon_level;
        sam->ctr          = ctr;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_SAM_INFO structure.
+ 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)
+
+static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ctr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_sam_info");
        depth++;
 
        /* don't 4-byte align here! */
 
-       prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
+       if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
+               return False;
 
-       switch (ctr->switch_value)
-       {
-               case 1:
-               {
-                       net_io_id_info1("", &(ctr->auth.id1), ps, depth);
-                       break;
-               }
-               case 2:
-               {
-                       net_io_id_info2("", &(ctr->auth.id2), ps, depth);
-                       break;
-               }
-               default:
-               {
-                       /* PANIC! */
-                       DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
-                       break;
-               }
+       switch (ctr->switch_value) {
+       case 1:
+               if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
+                       return False;
+               break;
+       case 2:
+               if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
+                       return False;
+               break;
+       default:
+               /* PANIC! */
+               DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
+               break;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a DOM_SAM_INFO structure.
-********************************************************************/
-static BOOL smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps, int depth)
+ Reads or writes a DOM_SAM_INFO structure.
+ ********************************************************************/
+
+static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_sam_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_clnt_info2("", &(sam->client  ), ps, depth);
+       if(!smb_io_clnt_info2("", &sam->client, ps, depth))
+               return False;
 
-       prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
-       smb_io_cred      ("", &(sam->rtn_cred), ps, depth);
+       if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
+               return False;
+       if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
+               return False;
 
-       prs_uint16("logon_level  ", ps, depth, &(sam->logon_level ));
+       if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
+               return False;
 
-       if (sam->logon_level != 0 && sam->ctr != NULL)
-       {
-               net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
+       if (sam->logon_level != 0 && sam->ctr != NULL) {
+               if(!net_io_id_info_ctr("logon_info", sam->ctr, ps, depth))
+                       return False;
        }
 
        return True;
 }
 
 /*************************************************************************
- make_net_user_info3
+ Init
  *************************************************************************/
-BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
+
+void init_net_user_info3(NET_USER_INFO_3 *usr,
 
        NTTIME *logon_time,
        NTTIME *logoff_time,
@@ -1010,7 +1005,7 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
 {
        /* only cope with one "other" sid, right now. */
        /* need to count the number of space-delimited sids */
-       uint32 i;
+       int i;
        int num_other_sids = 0;
 
        int len_user_name    = strlen(user_name   );
@@ -1023,6 +1018,8 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
        int len_logon_srv    = strlen(logon_srv);
        int len_logon_dom    = strlen(logon_dom);
 
+    memset(usr, '\0', sizeof(*usr));
+
        usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
 
        usr->logon_time            = *logon_time;
@@ -1032,12 +1029,12 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
        usr->pass_can_change_time  = *pass_can_change_time;
        usr->pass_must_change_time = *pass_must_change_time;
 
-       make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   );
-       make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   );
-       make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
-       make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
-       make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    );
-       make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   );
+       init_uni_hdr(&usr->hdr_user_name, len_user_name);
+       init_uni_hdr(&usr->hdr_full_name, len_full_name);
+       init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+       init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+       init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+       init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
 
        usr->logon_count = logon_count;
        usr->bad_pw_count = bad_pw_count;
@@ -1049,835 +1046,274 @@ BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
        usr->user_flgs = user_flgs;
 
        if (sess_key != NULL)
-       {
                memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
-       }
        else
-       {
-               bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
-       }
+               memset((char *)usr->user_sess_key, '\0', 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);
+       init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
+       init_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 */
 
-       bzero(usr->padding, sizeof(usr->padding));
+       memset((char *)usr->padding, '\0', sizeof(usr->padding));
 
-       num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
+       num_other_sids = init_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
 
        usr->num_other_sids = num_other_sids;
-       usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
+       usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
        
-       make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
-       make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
-       make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
-       make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
-       make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
-       make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
+       init_unistr2(&usr->uni_user_name, user_name, len_user_name);
+       init_unistr2(&usr->uni_full_name, full_name, len_full_name);
+       init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
+       init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
+       init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
+       init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
 
        usr->num_groups2 = num_groups;
 
        SMB_ASSERT_ARRAY(usr->gids, num_groups);
 
        for (i = 0; i < num_groups; i++)
-       {
                usr->gids[i] = gids[i];
-       }
 
-       make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
-       make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
+       init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
+       init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
 
-       make_dom_sid2(&(usr->dom_sid), dom_sid);
+       init_dom_sid2(&usr->dom_sid, dom_sid);
        /* "other" sids are set up above */
-
-       return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL net_io_user_info3(char *desc,  NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
+
+static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (usr == NULL) return False;
+       if (usr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
-
-       if (usr->ptr_user_info != 0)
-       {
-               smb_io_time("time", &(usr->logon_time)           , ps, depth); /* logon time */
-               smb_io_time("time", &(usr->logoff_time)          , ps, depth); /* logoff time */
-               smb_io_time("time", &(usr->kickoff_time)         , ps, depth); /* kickoff time */
-               smb_io_time("time", &(usr->pass_last_set_time)   , ps, depth); /* password last set time */
-               smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
-               smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
-
-               smb_io_unihdr("unihdr", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive unicode string header */
-
-               prs_uint16("logon_count   ", ps, depth, &(usr->logon_count ));  /* logon count */
-               prs_uint16("bad_pw_count  ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
-
-               prs_uint32("user_id       ", ps, depth, &(usr->user_id      ));       /* User ID */
-               prs_uint32("group_id      ", ps, depth, &(usr->group_id     ));      /* Group ID */
-               prs_uint32("num_groups    ", ps, depth, &(usr->num_groups   ));    /* num groups */
-               prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
-               prs_uint32("user_flgs     ", ps, depth, &(usr->user_flgs    ));     /* user flags */
-
-               prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
-
-               smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
-               smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
-
-               prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
-               prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40); /* unused padding bytes? */
-
-               prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
-               prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
+       if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
+               return False;
+
+       if (usr->ptr_user_info == 0)
+               return True;
+
+       if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
+               return False;
+       if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
+               return False;
+       if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
+               return False;
+       if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
+               return False;
+       if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
+               return False;
+       if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
+               return False;
+
+       if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
+               return False;
+
+       if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
+               return False;
+       if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
+               return False;
+
+       if(!prs_uint32("user_id       ", ps, depth, &usr->user_id))       /* User ID */
+               return False;
+       if(!prs_uint32("group_id      ", ps, depth, &usr->group_id))      /* Group ID */
+               return False;
+       if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
+               return False;
+       if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
+               return False;
+       if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
+               return False;
+
+       if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
+               return False;
+
+       if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
+               return False;
+
+       if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
+               return False;
+       if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
+               return False;
+
+       if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
+               return False;
+       if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
+               return False;
                
-               smb_io_unistr2("unistr2", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
-               smb_io_unistr2("unistr2", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
-               smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
-               smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
-               smb_io_unistr2("unistr2", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
-               smb_io_unistr2("unistr2", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
-
-               prs_align(ps);
-               prs_uint32("num_groups2   ", ps, depth, &(usr->num_groups2));        /* num groups */
-               SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
-               for (i = 0; i < usr->num_groups2; i++)
-               {
-                       smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
-               }
+       if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
+               return False;
+       SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
+       for (i = 0; i < usr->num_groups2; i++) {
+               if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
+                       return False;
+       }
 
-               smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
-               smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
+       if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
+               return False;
 
-               smb_io_dom_sid2("", &(usr->dom_sid), ps, depth);           /* domain SID */
+       if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
+               return False;
 
-               SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
+       SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
 
-               for (i = 0; i < usr->num_other_sids; i++)
-               {
-                       smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
-               }
+       for (i = 0; i < usr->num_other_sids; i++) {
+               if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
+
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
 {
-       if (q_l == NULL) return False;
+       if (q_l == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_sam_logon");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
-       prs_uint16("validation_level", ps, depth, &(q_l->validation_level));
+       if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
+               return False;
 
+       if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
+
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
 {
-       if (r_l == NULL) return False;
+       if (r_l == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_r_sam_logon");
        depth++;
 
-       prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
-       smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
+       if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
+               return False;
+       if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
+               return False;
 
-       prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
-       prs_align(ps);
+       if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       if (r_l->switch_value != 0)
-       {
-               net_io_user_info3("", r_l->user, ps, depth);
+       if (r_l->switch_value != 0) {
+               if(!net_io_user_info3("", r_l->user, ps, depth))
+                       return False;
        }
 
-       prs_uint32("auth_resp   ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
+       if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_l->status));
+       if(!prs_uint32("status      ", ps, depth, &r_l->status))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
 {
-       if (q_l == NULL) return False;
+       if (q_l == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
        depth++;
 
-       prs_align(ps);
-       
-       smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
-{
-       if (r_l == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
-       depth++;
-
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
-       smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
-
-       prs_uint32("status      ", ps, depth, &(r_l->status));
+       if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a NET_Q_SAM_SYNC structure.
+ Reads or writes a structure.
 ********************************************************************/
-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)
-{
-       if (q_s == NULL) return False;
-
-       DEBUG(5,("make_q_sam_sync\n"));
-
-       make_unistr2(&(q_s->uni_srv_name), srv_name, strlen(srv_name)+1);
-       make_unistr2(&(q_s->uni_cli_name), cli_name, strlen(cli_name)+1);
-
-       memcpy(&(q_s->cli_creds), cli_creds, sizeof(q_s->cli_creds));
-       memset(&(q_s->ret_creds), 0, sizeof(q_s->ret_creds));
 
-       q_s->database_id = database_id;
-       q_s->restart_state = 0;
-       q_s->sync_context = 0;
-       q_s->max_size = 0xffff;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth)
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
 {
-       if (q_s == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_q_sam_sync");
-       depth++;
-
-       smb_io_unistr2("", &(q_s->uni_srv_name), True, ps, depth);
-       smb_io_unistr2("", &(q_s->uni_cli_name), True, ps, depth);
-
-       smb_io_cred("", &(q_s->cli_creds), ps, depth);
-       smb_io_cred("", &(q_s->ret_creds), ps, depth);
-
-       prs_uint32("database_id  ", ps, depth, &(q_s->database_id  ));
-       prs_uint32("restart_state", ps, depth, &(q_s->restart_state));
-       prs_uint32("sync_context ", ps, depth, &(q_s->sync_context ));
-
-       prs_uint32("max_size", ps, depth, &(q_s->max_size));
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAM_DELTA_HDR structure.
-********************************************************************/
-BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid)
-{
-       if (delta == NULL) return False;
-
-       DEBUG(5,("make_sam_delta_hdr\n"));
-
-       delta->type2 = delta->type = type;
-       delta->target_rid = rid;
-
-       delta->type3 = type;
-       delta->ptr_delta = 1;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR *delta, prs_struct *ps, int depth)
-{
-       if (delta == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
-       depth++;
-
-       prs_uint16("type",       ps, depth, &(delta->type      ));
-       prs_uint16("type2",      ps, depth, &(delta->type2     ));
-       prs_uint32("target_rid", ps, depth, &(delta->target_rid));
-
-       prs_uint32("type3",      ps, depth, &(delta->type3     ));
-       prs_uint32("ptr_delta",  ps, depth, &(delta->ptr_delta ));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO *info, prs_struct *ps, int depth)
-{
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_domain_info");
-       depth++;
+       if (r_l == NULL)
+               return False;
 
-       smb_io_unihdr("hdr_dom_name" , &(info->hdr_dom_name) , ps, depth);
-       smb_io_unihdr("hdr_oem_info" , &(info->hdr_oem_info) , ps, depth);
-
-       smb_io_bigint("force_logoff" , &(info->force_logoff) , ps, depth);
-       prs_uint16("min_pwd_len"     , ps, depth, &(info->min_pwd_len    ));
-       prs_uint16("pwd_history_len" , ps, depth, &(info->pwd_history_len));
-       smb_io_bigint("max_pwd_age"  , &(info->max_pwd_age)  , ps, depth);
-       smb_io_bigint("min_pwd_age"  , &(info->min_pwd_age)  , ps, depth);
-       smb_io_bigint("dom_mod_count", &(info->dom_mod_count), ps, depth);
-       smb_io_time("creation_time"  , &(info->creation_time), ps, depth);
-
-       smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc) , ps, depth);
-       smb_io_unihdr ("hdr_unknown" , &(info->hdr_unknown)  , ps, depth);
-       ps->offset += 40;
-
-       smb_io_unistr2("uni_dom_name", &(info->uni_dom_name),
-                      info->hdr_dom_name.buffer, ps, depth);
-       smb_io_unistr2("buf_oem_info", &(info->buf_oem_info),
-                      info->hdr_oem_info.buffer, ps, depth);
-
-       smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
-                      info->hdr_sec_desc.buffer, ps, depth);
-       smb_io_unistr2("buf_unknown" , &(info->buf_unknown ),
-                      info->hdr_unknown .buffer, ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO *info, prs_struct *ps, int depth)
-{
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_group_info");
-       depth++;
-
-       smb_io_unihdr ("hdr_grp_name", &(info->hdr_grp_name), ps, depth);
-       smb_io_gid    ("gid",          &(info->gid),          ps, depth);
-       smb_io_unihdr ("hdr_grp_desc", &(info->hdr_grp_desc), ps, depth);
-       smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
-       ps->offset += 48;
-
-       smb_io_unistr2("uni_grp_name", &(info->uni_grp_name),
-                      info->hdr_grp_name.buffer, ps, depth);
-       smb_io_unistr2("uni_grp_desc", &(info->uni_grp_desc),
-                      info->hdr_grp_desc.buffer, ps, depth);
-       smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
-                      info->hdr_sec_desc.buffer, ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAM_ACCOUNT_INFO structure.
-********************************************************************/
-BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info, char *user_name,
-                          char *full_name, uint32 user_rid, uint32 group_rid,
-                          char *home_dir, char *dir_drive, char *logon_script,
-                          char *acct_desc, uint32 acb_info, char *profile)
-{
-       int len_user_name = strlen(user_name);
-       int len_full_name = strlen(full_name);
-       int len_home_dir = strlen(home_dir);
-       int len_dir_drive = strlen(dir_drive);
-       int len_logon_script = strlen(logon_script);
-       int len_acct_desc = strlen(acct_desc);
-       int len_profile = strlen(profile);
-
-       DEBUG(5,("make_sam_account_info\n"));
-
-        make_uni_hdr(&(info->hdr_acct_name   ), len_user_name   );
-        make_uni_hdr(&(info->hdr_full_name   ), len_full_name   );
-        make_uni_hdr(&(info->hdr_home_dir    ), len_home_dir    );
-        make_uni_hdr(&(info->hdr_dir_drive   ), len_dir_drive   );
-        make_uni_hdr(&(info->hdr_logon_script), len_logon_script);
-        make_uni_hdr(&(info->hdr_acct_desc   ), len_acct_desc   );
-        make_uni_hdr(&(info->hdr_profile     ), len_profile     );
-
-       /* not present */
-        make_uni_hdr(&(info->hdr_workstations), 0);
-        make_uni_hdr(&(info->hdr_comment), 0);
-        make_uni_hdr(&(info->hdr_parameters), 0);
-       make_bufhdr2(&(info->hdr_sec_desc), 0, 0, 0);
-
-       info->user_rid = user_rid;
-       info->group_rid = group_rid;
-
-       init_nt_time(&(info->logon_time));
-       init_nt_time(&(info->logoff_time));
-       init_nt_time(&(info->pwd_last_set_time));
-       init_nt_time(&(info->acct_expiry_time));
-
-       info->logon_divs = 0xA8;
-       info->ptr_logon_hrs = 0; /* Don't care right now */
-
-       info->bad_pwd_count = 0;
-       info->logon_count = 0;
-       info->acb_info = acb_info;
-       info->nt_pwd_present = 0;
-       info->lm_pwd_present = 0;
-       info->pwd_expired = 0;
-       info->country = 0;
-       info->codepage = 0;
-
-       info->unknown1 = 0x4EC;
-       info->unknown2 = 0;
-
-       make_unistr2(&(info->uni_acct_name), user_name, len_user_name+1);
-       make_unistr2(&(info->uni_full_name), full_name, len_full_name+1);
-       make_unistr2(&(info->uni_home_dir ), home_dir , len_home_dir +1);
-       make_unistr2(&(info->uni_dir_drive), dir_drive, len_dir_drive+1);
-       make_unistr2(&(info->uni_logon_script), logon_script, len_logon_script+1);
-       make_unistr2(&(info->uni_acct_desc), acct_desc, len_acct_desc+1);
-       make_unistr2(&(info->uni_profile  ), profile  , len_profile  +1);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD *pwd,
-                               prs_struct *ps, int depth)
-{
-       if (pwd == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
+       prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
        depth++;
 
-       prs_uint32("unk_0 ", ps, depth, &(pwd->unk_0 ));
-
-       smb_io_unihdr ("hdr_lm_pwd", &(pwd->hdr_lm_pwd), ps, depth);
-       prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16);
+       if(!prs_align(ps))
+               return False;
        
-       smb_io_unihdr ("hdr_nt_pwd", &(pwd->hdr_nt_pwd), ps, depth);
-       prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16);
-
-       smb_io_unihdr("", &(pwd->hdr_empty_lm), ps, depth);
-       smb_io_unihdr("", &(pwd->hdr_empty_nt), ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-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, int depth)
-{
-       BUFHDR2 hdr_priv_data;
-       uint32 i;
-
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_account_info");
-       depth++;
-
-       smb_io_unihdr("hdr_acct_name", &(info->hdr_acct_name), ps, depth);
-       smb_io_unihdr("hdr_full_name", &(info->hdr_full_name), ps, depth);
-
-       prs_uint32("user_rid ", ps, depth, &(info->user_rid ));
-       prs_uint32("group_rid", ps, depth, &(info->group_rid));
-
-       smb_io_unihdr("hdr_home_dir "   , &(info->hdr_home_dir ), ps, depth);
-       smb_io_unihdr("hdr_dir_drive"   , &(info->hdr_dir_drive), ps, depth);
-       smb_io_unihdr("hdr_logon_script", &(info->hdr_logon_script), ps, depth);
-       smb_io_unihdr("hdr_acct_desc"   , &(info->hdr_acct_desc), ps, depth);
-       smb_io_unihdr("hdr_workstations", &(info->hdr_workstations), ps, depth);
-
-       smb_io_time("logon_time" , &(info->logon_time ), ps, depth);
-       smb_io_time("logoff_time", &(info->logoff_time), ps, depth);
-
-       prs_uint32("logon_divs   ", ps, depth, &(info->logon_divs   ));
-       prs_uint32("ptr_logon_hrs", ps, depth, &(info->ptr_logon_hrs));
-
-       prs_uint16("bad_pwd_count", ps, depth, &(info->bad_pwd_count));
-       prs_uint16("logon_count"  , ps, depth, &(info->logon_count  ));
-       smb_io_time("pwd_last_set_time", &(info->pwd_last_set_time), ps, depth);
-       smb_io_time("acct_expiry_time" , &(info->acct_expiry_time ), ps, depth);
-
-       prs_uint32("acb_info", ps, depth, &(info->acb_info));
-       prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16);
-       prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16);
-       prs_uint8("lm_pwd_present", ps, depth, &(info->lm_pwd_present));
-       prs_uint8("nt_pwd_present", ps, depth, &(info->nt_pwd_present));
-       prs_uint8("pwd_expired"   , ps, depth, &(info->pwd_expired   ));
-
-       smb_io_unihdr("hdr_comment"   , &(info->hdr_comment   ), ps, depth);
-       smb_io_unihdr("hdr_parameters", &(info->hdr_parameters), ps, depth);
-       prs_uint16("country" , ps, depth, &(info->country ));
-       prs_uint16("codepage", ps, depth, &(info->codepage));
-
-       smb_io_bufhdr2("hdr_priv_data", &(hdr_priv_data), ps, depth);
-       smb_io_bufhdr2("hdr_sec_desc" , &(info->hdr_sec_desc) , ps, depth);
-       smb_io_unihdr ("hdr_profile"  , &(info->hdr_profile)  , ps, depth);
-
-       for (i = 0; i < 3; i++)
-       {
-               smb_io_unihdr("hdr_reserved", &(info->hdr_reserved[i]), ps, depth);
-       }
-
-       for (i = 0; i < 4; i++)
-       {
-               prs_uint32("dw_reserved", ps, depth, &(info->dw_reserved[i]));
-       }
-
-       smb_io_unistr2("uni_acct_name", &(info->uni_acct_name),
-                      info->hdr_acct_name.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_full_name", &(info->uni_full_name),
-                      info->hdr_full_name.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_home_dir ", &(info->uni_home_dir ),
-                      info->hdr_home_dir .buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_dir_drive", &(info->uni_dir_drive),
-                      info->hdr_dir_drive.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_logon_script", &(info->uni_logon_script),
-                      info->hdr_logon_script.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_acct_desc", &(info->uni_acct_desc),
-                      info->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_workstations", &(info->uni_workstations),
-                      info->hdr_workstations.buffer, ps, depth);
-       prs_align(ps);
-
-       prs_uint32("unknown1", ps, depth, &(info->unknown1));
-       prs_uint32("unknown2", ps, depth, &(info->unknown2));
-
-       smb_io_buffer4("buf_logon_hrs" , &(info->buf_logon_hrs ),
-                      info->ptr_logon_hrs, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_comment"   , &(info->uni_comment   ),
-                      info->hdr_comment.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_parameters", &(info->uni_parameters),
-                      info->hdr_parameters.buffer, ps, depth);
-       prs_align(ps);
-       if (hdr_priv_data.buffer != 0)
-       {
-               int old_offset;
-               uint32 len = 0x44;
-               prs_uint32("pwd_len", ps, depth, &len);
-               old_offset = ps->offset;
-               if (len == 0x44)
-               {
-                       if (ps->io)
-                       {
-                               /* reading */
-                               prs_hash1(ps, ps->offset, sess_key);
-                       }
-                       net_io_sam_passwd_info("pass", &(info->pass), ps, depth);
-                       if (!ps->io)
-                       {
-                               /* writing */
-                               prs_hash1(ps, old_offset, sess_key);
-                       }
-               }
-               ps->offset = old_offset + len;
-       }
-       smb_io_buffer4("buf_sec_desc"  , &(info->buf_sec_desc  ),
-                      info->hdr_sec_desc.buffer, ps, depth);
-       prs_align(ps);
-       smb_io_unistr2("uni_profile"   , &(info->uni_profile   ),
-                      info->hdr_profile.buffer, ps, depth);
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
-       fstring tmp;
-
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("ptr_rids   ", ps, depth, &(info->ptr_rids   ));
-       prs_uint32("ptr_attribs", ps, depth, &(info->ptr_attribs));
-       prs_uint32("num_members", ps, depth, &(info->num_members));
-       ps->offset += 16;
-
-       if (info->ptr_rids != 0)
-       {
-               prs_uint32("num_members2", ps, depth, &(info->num_members2));
-               if (info->num_members2 != info->num_members)
-               {
-                       /* RPC fault */
-                       return False;
-               }
-
-               SMB_ASSERT_ARRAY(info->rids, info->num_members2);
-
-               for (i = 0; i < info->num_members2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
-                       prs_uint32(tmp, ps, depth, &(info->rids[i]));
-               }
-       }
-
-       if (info->ptr_attribs != 0)
-       {
-               prs_uint32("num_members3", ps, depth, &(info->num_members3));
-               if (info->num_members3 != info->num_members)
-               {
-                       /* RPC fault */
-                       return False;
-               }
-
-               SMB_ASSERT_ARRAY(info->attribs, info->num_members3);
-
-               for (i = 0; i < info->num_members3; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
-                       prs_uint32(tmp, ps, depth, &(info->attribs[i]));
-               }
-       }
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO *info, prs_struct *ps, int depth)
-{
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_alias_info");
-       depth++;
-
-       smb_io_unihdr ("hdr_als_name", &(info->hdr_als_name), ps, depth);
-       prs_uint32("als_rid", ps, depth, &(info->als_rid));
-       smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
-       smb_io_unihdr ("hdr_als_desc", &(info->hdr_als_desc), ps, depth);
-       ps->offset += 40;
-
-       smb_io_unistr2("uni_als_name", &(info->uni_als_name),
-                      info->hdr_als_name.buffer, ps, depth);
-       smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
-                      info->hdr_sec_desc.buffer, ps, depth);
-       smb_io_unistr2("uni_als_desc", &(info->uni_als_desc),
-                      info->hdr_als_name.buffer, ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
-       fstring tmp;
-
-       if (info == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("num_members", ps, depth, &(info->num_members));
-       prs_uint32("ptr_members", ps, depth, &(info->ptr_members));
-       ps->offset += 16;
-
-       if (info->ptr_members != 0)
-       {
-               prs_uint32("num_sids", ps, depth, &(info->num_sids));
-               if (info->num_sids != info->num_members)
-               {
-                       /* RPC fault */
-                       return False;
-               }
-
-               SMB_ASSERT_ARRAY(info->ptr_sids, info->num_sids);
-
-               for (i = 0; i < info->num_sids; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
-                       prs_uint32(tmp, ps, depth, &(info->ptr_sids[i]));
-               }
-
-               SMB_ASSERT_ARRAY(info->sids, info->num_sids);
-
-               for (i = 0; i < info->num_sids; i++)
-               {
-                       if (info->ptr_sids[i] != 0)
-                       {
-                               slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]", i);
-                               smb_io_dom_sid2(tmp, &(info->sids[i]), ps, depth);
-                       }
-               }
-       }
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (delta == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
-       depth++;
-
-       switch (type)
-       {
-               case 1:
-               {
-                       net_io_sam_domain_info("", &(delta->domain_info),
-                                                  ps, depth);
-                       break;
-               }
-               case 2:
-               {
-                       net_io_sam_group_info("", &(delta->group_info), 
-                                                  ps, depth);
-                       break;
-               }
-               case 5:
-               {
-                       net_io_sam_account_info("", sess_key,
-                                               &(delta->account_info), 
-                                                  ps, depth);
-                       break;
-               }
-               case 8:
-               {
-                       net_io_sam_group_mem_info("", &(delta->grp_mem_info), 
-                                                  ps, depth);
-                       break;
-               }
-               case 9:
-               {
-                       net_io_sam_alias_info("", &(delta->alias_info), 
-                                                  ps, depth);
-                       break;
-               }
-               case 0xC:
-               {
-                       net_io_sam_alias_mem_info("", &(delta->als_mem_info), 
-                                                  ps, depth);
-                       break;
-               }
-               default:
-               {
-                       DEBUG(0, ("Replication error: Unknown delta type %x\n", type));
-                       break;
-               }
-       }
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
-
-       if (r_s == NULL) return False;
-
-       prs_debug(ps, depth, desc, "net_io_r_sam_sync");
-       depth++;
-
-       smb_io_cred("", &(r_s->srv_creds), ps, depth);
-       prs_uint32("sync_context", ps, depth, &(r_s->sync_context));
-
-       prs_uint32("ptr_deltas", ps, depth, &(r_s->ptr_deltas));
-       if (r_s->ptr_deltas != 0)
-       {
-               prs_uint32("num_deltas ", ps, depth, &(r_s->num_deltas ));
-               prs_uint32("ptr_deltas2", ps, depth, &(r_s->ptr_deltas2));
-               if (r_s->ptr_deltas2 != 0)
-               {
-                       prs_uint32("num_deltas2", ps, depth, &(r_s->num_deltas2));
-                       if (r_s->num_deltas2 != r_s->num_deltas)
-                       {
-                               /* RPC fault */
-                               return False;
-                       }
-
-                       for (i = 0; i < r_s->num_deltas2; i++)
-                       {
-                               net_io_sam_delta_hdr("", &r_s->hdr_deltas[i], ps, depth);
-                       }
-
-                       for (i = 0; i < r_s->num_deltas2; i++)
-                       {
-                               net_io_sam_delta_ctr("", sess_key,
-                                         &r_s->deltas[i],
-                                         r_s->hdr_deltas[i].type3, ps, depth);
-                       }
-               }
-       }
+       if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
+               return False;
+       if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
+               return False;
 
-       prs_align(ps);
-       prs_uint32("status", ps, depth, &(r_s->status));
+       if(!prs_uint32("status      ", ps, depth, &r_l->status))
+               return False;
 
        return True;
 }
index d9c07e388568cd67d2758c32c6e8481e6b5f7fa0..f5f4eb67b8d8933c1f9d1bcd2e0c90a0e32d1f46 100644 (file)
@@ -2,8 +2,9 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    Samba memory buffer functions
-   Copyright (C) Andrew Tridgell              1992-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell              1992-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+   Copyright (C) Jeremy Allison 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
@@ -33,523 +34,567 @@ extern int DEBUGLEVEL;
  ********************************************************************/
 void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
 {
-       DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
+       DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
 }
 
 /*******************************************************************
- debug a parse structure
+ Initialise a parse structure - malloc the data if requested.
  ********************************************************************/
-void prs_debug_out(prs_struct *ps, char *msg, int level)
+
+BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
 {
-       DEBUG(level,("%s ps: io %s align %d offset %d err %d data %p len %d\n",
-               msg, BOOLSTR(ps->io), ps->align, ps->offset, ps->error,
-               ps->data,
-               ps->data != NULL ? mem_buf_len(ps->data) : 0));
+       ZERO_STRUCTP(ps);
+       ps->io = io;
+       ps->bigendian_data = False;
+       ps->align = align;
+       ps->is_dynamic = False;
+       ps->data_offset = 0;
+       ps->buffer_size = 0;
+       ps->data_p = NULL;
+
+       if (size != 0) {
+               ps->buffer_size = size;
+               if((ps->data_p = (char *)malloc((size_t)size)) == NULL) {
+                       DEBUG(0,("prs_init: malloc fail for %u bytes.\n", (unsigned int)size));
+                       return False;
+               }
+               ps->is_dynamic = True; /* We own this memory. */
+       }
+
+       return True;
 }
 
 /*******************************************************************
- initialise a parse structure
+ Delete the memory in a parse structure - if we own it.
  ********************************************************************/
-void prs_init(prs_struct *ps, uint32 size,
-                               uint8 align, uint32 margin,
-                               BOOL io)
+
+void prs_mem_free(prs_struct *ps)
 {
-       ps->io = io;
-       ps->align = align;
-       ps->offset = 0;
-       ps->error = False;
+       if(ps->is_dynamic && (ps->data_p != NULL))
+               free(ps->data_p);
+       ps->is_dynamic = False;
+       ps->data_p = NULL;
+       ps->buffer_size = 0;
+       ps->data_offset = 0;
+}
 
-       ps->data = NULL;
-       mem_buf_init(&(ps->data), margin);
+/*******************************************************************
+ Hand some already allocated memory to a prs_struct.
+ ********************************************************************/
 
-       if (size != 0)
-       {
-               mem_alloc_data(ps->data, size);
-               ps->data->offset.start = 0;
-               ps->data->offset.end   = 0xffffffff;
-       }
+void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic)
+{
+       ps->is_dynamic = is_dynamic;
+       ps->data_p = buf;
+       ps->buffer_size = size;
 }
 
 /*******************************************************************
- copy a parse structure
+ Take some memory back from a prs_struct.
  ********************************************************************/
-BOOL prs_copy(prs_struct *ps, const prs_struct *from)
+
+char *prs_take_memory(prs_struct *ps, uint32 *psize)
 {
-       int len = mem_buf_len(from->data);
-       prs_init(ps, len, from->align, from->data->margin, from->io);
-       if (!mem_buf_copy(mem_data(&ps->data, 0), from->data, 0, len))
-       {
+       char *ret = ps->data_p;
+       if(psize)
+               *psize = ps->buffer_size;
+       ps->is_dynamic = False;
+       prs_mem_free(ps);
+       return ret;
+}
+
+/*******************************************************************
+ Attempt, if needed, to grow a data buffer.
+ Also depends on the data stream mode (io).
+ ********************************************************************/
+
+BOOL prs_grow(prs_struct *ps, uint32 extra_space)
+{
+       uint32 new_size;
+       char *new_data;
+
+       if(ps->data_offset + extra_space <= ps->buffer_size)
+               return True;
+
+       /*
+        * We cannot grow the buffer if we're not reading
+        * into the prs_struct, or if we don't own the memory.
+        */
+
+       if(UNMARSHALLING(ps) || !ps->is_dynamic) {
+               DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
+                               (unsigned int)extra_space));
                return False;
        }
-       ps->offset = len;
-       prs_link(NULL, ps, NULL);
+
+       /*
+        * Decide how much extra space we really need.
+        */
+
+       extra_space -= (ps->buffer_size - ps->data_offset);
+
+       if(ps->buffer_size == 0) {
+
+               /*
+                * Ensure we have at least a PDU's length, or extra_space, whichever
+                * is greater.
+                */
+
+               new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
+
+               if((new_data = malloc(new_size)) == NULL) {
+                       DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
+                       return False;
+               }
+               memset(new_data, '\0', new_size );
+       } else {
+
+               /*
+                * If the current buffer size is bigger than the space needed, just 
+                * double it, else add extra_space.
+                */
+
+               new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);
+
+               if((new_data = Realloc(ps->data_p, new_size)) == NULL) {
+                       DEBUG(0,("prs_grow: Realloc failure for size %u.\n",
+                               (unsigned int)new_size));
+                       return False;
+               }
+       }
+
+       ps->buffer_size = new_size;
+       ps->data_p = new_data;
+
        return True;
 }
 
 /*******************************************************************
- initialise a parse structure
+ Attempt to force a data buffer to grow by len bytes.
+ This is only used when appending more data onto a prs_struct
+ when reading an rpc reply, before unmarshalling it.
  ********************************************************************/
-void prs_mem_free(prs_struct *ps)
+
+BOOL prs_force_grow(prs_struct *ps, uint32 extra_space)
 {
-       mem_buf_free(&(ps->data));
+       uint32 new_size = ps->buffer_size + extra_space;
+       char *new_data;
+
+       if(!UNMARSHALLING(ps) || !ps->is_dynamic) {
+               DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
+                               (unsigned int)extra_space));
+               return False;
+       }
+
+       if((new_data = Realloc(ps->data_p, new_size)) == NULL) {
+               DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n",
+                       (unsigned int)new_size));
+               return False;
+       }
+
+       ps->buffer_size = new_size;
+       ps->data_p = new_data;
+
+       return True;
 }
 
 /*******************************************************************
- link one parsing structure to another
+ Get the data pointer (external interface).
  ********************************************************************/
-void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
-{
-       ps->data->offset.start = prev != NULL ? prev->data->offset.end : 0;
-       ps->data->offset.end   = ps->data->offset.start + ps->offset;
-       ps->data->next         = next != NULL ? next->data : NULL;
 
-       DEBUG(150,("prs_link: start %d end %d\n",
-               ps->data->offset.start,
-               ps->data->offset.end));
+char *prs_data_p(prs_struct *ps)
+{
+       return ps->data_p;
 }
 
 /*******************************************************************
- align a pointer to a multiple of align_offset bytes.  looks like it
- will work for offsets of 0, 2 and 4...
+ Get the current data size (external interface).
  ********************************************************************/
-void prs_align(prs_struct *ps)
+
+uint32 prs_data_size(prs_struct *ps)
 {
-       int mod;
-       if (ps->error) return;
-       mod = ps->offset & (ps->align-1);
-       if (ps->align != 0 && mod != 0)
-       {
-               ps->offset += ps->align - mod;
-       }
+       return ps->buffer_size;
 }
 
 /*******************************************************************
- attempt, if appropriate, to grow a data buffer.
-
- depends on the data stream mode (io)
+ Fetch the current offset (external interface).
  ********************************************************************/
-BOOL prs_grow(prs_struct *ps, uint32 new_size)
+
+uint32 prs_offset(prs_struct *ps)
 {
-       if (ps->error) return False;
-       return mem_grow_data(&(ps->data), ps->io, new_size, False);
+       return ps->data_offset;
 }
 
 /*******************************************************************
lengthens a buffer by len bytes and copies data into it.
Set the current offset (external interface).
  ********************************************************************/
-BOOL prs_append_data(prs_struct *ps, const char *data, int len)
+
+BOOL prs_set_offset(prs_struct *ps, uint32 offset)
 {
-       int prev_size = ps->data->data_used;
-       int new_size  = prev_size + len;
-       char *to;
+       if(offset <= ps->data_offset) {
+               ps->data_offset = offset;
+               return True;
+       }
 
-       mem_realloc_data(ps->data, new_size);
-       to = mem_data(&ps->data, prev_size);
-       if (to == NULL || ps->data->data_used != new_size)
-       {
+       if(!prs_grow(ps, offset - ps->data_offset))
                return False;
-       }
-       memcpy(to, data, len);
 
+       ps->data_offset = offset;
        return True;
 }
 
 /*******************************************************************
- stream a uint8
+ Append the data from one parse_struct into another.
  ********************************************************************/
-BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
+
+BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
 {
-       char *q;
-       if (ps->error) return False;
-       prs_grow(ps, ps->offset + 1);
-       q = mem_data(&(ps->data), ps->offset);
-       if (q == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint8 error", 5);
+       if(!prs_grow(dst, prs_offset(src)))
                return False;
-       }
-
-       DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
-       ps->offset += 1;
 
+       memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)prs_offset(src));
+       dst->data_offset += prs_offset(src);
 
        return True;
 }
 
 /*******************************************************************
- stream a uint16
+ Append the data from a buffer into a parse_struct.
  ********************************************************************/
-BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
+
+BOOL prs_append_data(prs_struct *dst, char *src, uint32 len)
 {
-       char *q;
-       if (ps->error) return False;
-       prs_grow(ps, ps->offset + 2);
-       q = mem_data(&(ps->data), ps->offset);
-       if (q == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint16 error", 5);
+       if(!prs_grow(dst, len))
                return False;
-       }
 
-       DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
-       ps->offset += 2;
+       memcpy(&dst->data_p[dst->data_offset], src, (size_t)len);
+       dst->data_offset += len;
 
        return True;
 }
 
 /*******************************************************************
hash a stream.
Set the data as big-endian (external interface).
  ********************************************************************/
-BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
+
+void prs_set_bigendian_data(prs_struct *ps)
 {
-       char *q;
-       if (ps->error) return False;
-       q = mem_data(&(ps->data), ps->offset);
+       ps->bigendian_data = True;
+}
+
+/*******************************************************************
+ Align a the data_len to a multiple of align bytes - filling with
+ zeros.
+ ********************************************************************/
+
+BOOL prs_align(prs_struct *ps)
+{
+       uint32 mod = ps->data_offset & (ps->align-1);
+
+       if (ps->align != 0 && mod != 0) {
+               uint32 extra_space = (ps->align - mod);
+               if(!prs_grow(ps, extra_space))
+                       return False;
+               memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
+               ps->data_offset += extra_space;
+       }
+
+       return True;
+}
+
+/*******************************************************************
+ Ensure we can read/write to a given offset.
+ ********************************************************************/
+
+char *prs_mem_get(prs_struct *ps, uint32 extra_size)
+{
+       if(UNMARSHALLING(ps)) {
+               /*
+                * If reading, ensure that we can read the requested size item.
+                */
+               if (ps->data_offset + extra_size > ps->buffer_size) {
+                       DEBUG(0,("prs_mem_get: reading data of size %u would overrun buffer.\n",
+                                       (unsigned int)extra_size ));
+                       return NULL;
+               }
+       } else {
+               /*
+                * Writing - grow the buffer if needed.
+                */
+               if(!prs_grow(ps, extra_size))
+                       return False;
+       }
+       return &ps->data_p[ps->data_offset];
+}
+
+/*******************************************************************
+ Stream a uint8.
+ ********************************************************************/
+
+BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
+{
+       char *q = prs_mem_get(ps, sizeof(uint8));
        if (q == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_hash1 error", 5);
                return False;
-       }
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("prs_hash1\n"));
-       dump_data(100, sess_key, 16);
-       dump_data(100, q, 68);
-#endif
-       SamOEMhash((uchar*)q, sess_key, 2);
-#ifdef DEBUG_PASSWORD
-       dump_data(100, q, 68);
-#endif
+       DBG_RW_CVAL(name, depth, ps->data_offset, ps->io, q, *data8)
+       ps->data_offset += sizeof(uint8);
 
        return True;
 }
 
 /*******************************************************************
- stream a uint32
+ Stream a uint16.
  ********************************************************************/
-BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
+
+BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
 {
-       char *q;
-       if (ps->error) return False;
-       prs_grow(ps, ps->offset + 4);
-       q = mem_data(&(ps->data), ps->offset);
+       char *q = prs_mem_get(ps, sizeof(uint16));
        if (q == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint32 error", 5);
                return False;
-       }
 
-       DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
-       ps->offset += 4;
+       DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16)
+       ps->data_offset += sizeof(uint16);
 
        return True;
 }
 
-
-/******************************************************************
- stream an array of uint8s.  length is number of uint8s
+/*******************************************************************
+ Stream a uint32.
  ********************************************************************/
-BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
+
+BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + len * sizeof(uint8);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL) 
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint8s error", 5);
+       char *q = prs_mem_get(ps, sizeof(uint32));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
-       ps->offset = end_offset;
+       DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32)
+       ps->data_offset += sizeof(uint32);
 
        return True;
 }
 
+
 /******************************************************************
- stream an array of uint16s.  length is number of uint16s
+ Stream an array of uint8s. Length is number of uint8s.
  ********************************************************************/
-BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
+
+BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + len * sizeof(uint16);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint16s error", 5);
+       char *q = prs_mem_get(ps, len * sizeof(uint8));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
-       ps->offset = end_offset;
+       DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, data8s, len)
+       ps->data_offset += (len * sizeof(uint8));
 
        return True;
 }
 
 /******************************************************************
- stream an array of uint32s.  length is number of uint32s
+ Stream an array of uint32s. Length is number of uint32s.
  ********************************************************************/
-BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
+
+BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + len * sizeof(uint32);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_uint32s error", 5);
+       char *q = prs_mem_get(ps, len * sizeof(uint32));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
-       ps->offset = end_offset;
+       DBG_RW_PIVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data32s, len)
+       ps->data_offset += (len * sizeof(uint32));
 
        return True;
 }
 
 /******************************************************************
stream a "not" unicode string, length/buffer specified separately,
- in byte chars
Stream a "not" unicode string, length/buffer specified separately,
+ in byte chars. String is in little-endian format.
  ********************************************************************/
-BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
+
+BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + str->buf_len * sizeof(uint8);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_buffer2 error", 5);
+       char *p = (char *)str->buffer;
+       char *q = prs_mem_get(ps, str->buf_len);
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
-       ps->offset = end_offset;
+       /* If we're using big-endian, reverse to get little-endian. */
+       if(ps->bigendian_data)
+               DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->buf_len/2)
+       else
+               DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->buf_len)
+       ps->data_offset += str->buf_len;
 
        return True;
 }
 
 /******************************************************************
stream a string, length/buffer specified separately,
Stream a string, length/buffer specified separately,
  in uint8 chars.
  ********************************************************************/
-BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
+
+BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + str->str_str_len * sizeof(uint8);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_string2 error", 5);
+       char *q = prs_mem_get(ps, str->str_str_len * sizeof(uint8));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
-       ps->offset = end_offset;
+       DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, str->buffer, str->str_max_len)
+       ps->data_offset += (str->str_str_len * sizeof(uint8));
 
        return True;
 }
 
 /******************************************************************
- stream a unicode string, length/buffer specified separately,
- in uint16 chars.
+ Stream a unicode string, length/buffer specified separately,
+ in uint16 chars. We use DBG_RW_PCVAL, not DBG_RW_PSVAL here
+ as the unicode string is already in little-endian format.
  ********************************************************************/
-BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
+
+BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_unistr2 error", 5);
+       char *p = (char *)str->buffer;
+       char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_str_len)
-       ps->offset = end_offset;
+       /* If we're using big-endian, reverse to get little-endian. */
+       if(ps->bigendian_data)
+               DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->uni_str_len)
+       else
+               DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->uni_str_len * 2)
+       ps->data_offset += (str->uni_str_len * sizeof(uint16));
 
        return True;
 }
 
 /******************************************************************
- stream a unicode string, length/buffer specified separately,
- in uint16 chars.
+ Stream a unicode string, length/buffer specified separately,
+ in uint16 chars. We use DBG_RW_PCVAL, not DBG_RW_PSVAL here
+ as the unicode string is already in little-endian format.
  ********************************************************************/
-BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
+
+BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
 {
-       char *q;
-       int end_offset;
-       char *e;
-       if (ps->error) return False;
-       end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
-       prs_grow(ps, end_offset);
-       q = mem_data(&(ps->data), ps->offset);
-       e = mem_data(&(ps->data), end_offset-1);
-
-       if (q == NULL || e == NULL)
-       {
-               ps->error = True;
-               prs_debug_out(ps, "_prs_unistr3 error", 5);
+       char *p = (char *)str->str.buffer;
+       char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
+       if (q == NULL)
                return False;
-       }
 
-       DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->str.buffer, str->uni_str_len)
-       ps->offset = end_offset;
+       /* If we're using big-endian, reverse to get little-endian. */
+       if(ps->bigendian_data)
+               DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->uni_str_len)
+       else
+               DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->uni_str_len * 2)
+       ps->data_offset += (str->uni_str_len * sizeof(uint16));
 
        return True;
 }
 
 /*******************************************************************
- stream a unicode  null-terminated string
+ Stream a unicode  null-terminated string. As the string is already
+ in little-endian format then do it as a stream of bytes.
  ********************************************************************/
-BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
+
+BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
 {
-       int i = -1;
+       int len = 0;
+       unsigned char *p = (unsigned char *)str->buffer;
        uint8 *start;
-       if (ps->error) return False;
-       start = (uint8*)mem_data(&(ps->data), ps->offset);
+       char *q;
+
+       for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) &&
+                          str->buffer[len] != 0; len++)
+               ;
 
-       do
+       q = prs_mem_get(ps, len*2);
+       if (q == NULL)
+               return False;
+
+       start = (uint8*)q;
+
+       len = 0;
+       do 
        {
-               char *q;
-               i++;
-               prs_grow(ps, ps->offset + i*2);
-               q = mem_data(&(ps->data), ps->offset + i*2);
-               if (q == NULL) 
-               {
-                       ps->error = True;
-                       prs_debug_out(ps, "_prs_unistr error", 5);
-                       return False;
+               if(ps->bigendian_data) {
+                       RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0)
+                       p += 2;
+                       q += 2;
+               } else {
+                       RW_CVAL(ps->io, q, *p, 0);
+                       p++;
+                       q++;
+                       RW_CVAL(ps->io, q, *p, 0);
+                       p++;
+                       q++;
                }
-               RW_SVAL(ps->io, q, str->buffer[i],0);
-       }
-       while ((((size_t)i) < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
-                    (str->buffer[i] != 0));
-
+               len++;
+       } while ((len < (sizeof(str->buffer) / sizeof(str->buffer[0]))) &&
+                    (str->buffer[len] != 0));
 
-       ps->offset += (i+1)*2;
+       ps->data_offset += len*2;
 
-       dump_data(5+depth, (char *)start, i * 2);
+       dump_data(5+depth, (char *)start, len * 2);
 
        return True;
 }
 
 /*******************************************************************
stream a null-terminated string.  len is strlen, and therefore does
Stream a null-terminated string.  len is strlen, and therefore does
  not include the null-termination character.
-
- len == 0 indicates variable length string
- (up to max size of pstring - 1024 chars).
-
  ********************************************************************/
-BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
+
+BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size)
 {
-       int i = -1; /* start off at zero after 1st i++ */
+       char *q;
        uint8 *start;
-       if (ps->error) return False;
-       start = (uint8*)mem_data(&(ps->data), ps->offset);
+       int i;
 
-       DEBUG(120,("_prs_string: string %s len %d max %d\n",
-                       str, len, max_buf_size));
+       len = MIN(len, (max_buf_size-1));
 
-       DEBUG(10,("%s%04x %s: ", tab_depth(depth), ps->offset, name != NULL ? name : ""));
+       q = prs_mem_get(ps, len+1);
+       if (q == NULL)
+               return False;
 
-       do
-       {
-               char *q;
-               i++;
-
-               prs_grow(ps, ps->offset + i);
-               q = mem_data(&(ps->data), ps->offset + i);
-               if (q == NULL)
-               {
-                       ps->error = True;
-                       prs_debug_out(ps, "_prs_string error", 5);
-                       return False;
-               }
+       start = (uint8*)q;
 
-               if (i < len || len == 0)
-               {
-                       RW_CVAL(ps->io, q, str[i], 0);
-               }
-               else
-               {
-                       uint8 dummy = 0;
-                       RW_CVAL(ps->io, q, dummy,0);
-               }
+       for(i = 0; i < len; i++) {
+               RW_CVAL(ps->io, q, str[i],0);
+               q++;
+       }
 
-       } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) );
+       /* The terminating null. */
+       str[i] = '\0';
 
-       DEBUG(120,("_prs_string: string %s len %d max %d\n",
-                       str, len, max_buf_size));
+       if (MARSHALLING(ps)) {
+               RW_CVAL(ps->io, q, str[i], 0);
+       }
 
-       ps->offset += i+1;
+       ps->data_offset += len+1;
 
-       dump_data(5+depth, (char *)start, i);
+       dump_data(5+depth, (char *)start, len);
 
        return True;
 }
 
 /*******************************************************************
- prs_uint16 wrapper.  call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading
+ prs_uint16 wrapper. Call this and it sets up a pointer to where the
+ uint16 should be stored, or gets the size if reading.
  ********************************************************************/
-BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
+
+BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
 {
-       if (ps->error) return False;
-       (*offset) = ps->offset;
-       if (ps->io)
-       {
+       (*offset) = ps->data_offset;
+       if (UNMARSHALLING(ps)) {
                /* reading. */
-               return _prs_uint16(name, ps, depth, data16);
-       }
-       else
-       {
-               ps->offset += sizeof(uint16);
+               return prs_uint16(name, ps, depth, data16);
+       } else {
+               char *q = prs_mem_get(ps, sizeof(uint16));
+               if(q ==NULL)
+                       return False;
+               ps->data_offset += sizeof(uint16);
        }
        return True;
 }
@@ -558,43 +603,42 @@ BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint
  prs_uint16 wrapper.  call this and it retrospectively stores the size.
  does nothing on reading, as that is already handled by ...._pre()
  ********************************************************************/
-BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+
+BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
                                uint32 ptr_uint16, uint32 start_offset)
 {
-       if (ps->error) return False;
-       if (!ps->io)
-       {
-               /* storing: go back and do a retrospective job.  i hate this */
-               uint16 data_size = ps->offset - start_offset;
-               uint32 old_offset = ps->offset;
-
-               ps->offset = ptr_uint16;
-               prs_uint16(name, ps, depth, &data_size);
-               ps->offset = old_offset;
-       }
-       else
-       {
-               ps->offset = start_offset + (*data16);
+       if (MARSHALLING(ps)) {
+               /* 
+                * Writing - temporarily move the offset pointer.
+                */
+               uint16 data_size = ps->data_offset - start_offset;
+               uint32 old_offset = ps->data_offset;
+
+               ps->data_offset = ptr_uint16;
+               if(!prs_uint16(name, ps, depth, &data_size)) {
+                       ps->data_offset = old_offset;
+                       return False;
+               }
+               ps->data_offset = old_offset;
+       } else {
+               ps->data_offset = start_offset + (uint32)(*data16);
        }
        return True;
 }
 
 /*******************************************************************
- prs_uint32 wrapper.  call this and it sets up a pointer to where the
- uint32 should be stored, or gets the size if reading
+ prs_uint32 wrapper. Call this and it sets up a pointer to where the
+ uint32 should be stored, or gets the size if reading.
  ********************************************************************/
-BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
+
+BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
 {
-       if (ps->error) return False;
-       (*offset) = ps->offset;
-       if (ps->io)
-       {
+       (*offset) = ps->data_offset;
+       if (UNMARSHALLING(ps)) {
                /* reading. */
-               return _prs_uint32(name, ps, depth, data32);
-       }
-       else
-       {
-               ps->offset += sizeof(uint32);
+               return prs_uint32(name, ps, depth, data32);
+       } else {
+               ps->data_offset += sizeof(uint32);
        }
        return True;
 }
@@ -603,18 +647,21 @@ BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint
  prs_uint32 wrapper.  call this and it retrospectively stores the size.
  does nothing on reading, as that is already handled by ...._pre()
  ********************************************************************/
-BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+
+BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
                                uint32 ptr_uint32, uint32 data_size)
 {
-       if (ps->error) return False;
-       if (!ps->io)
-       {
-               /* storing: go back and do a retrospective job.  i hate this */
-               uint32 old_offset = ps->offset;
-               ps->offset = ptr_uint32;
-               prs_uint32(name, ps, depth, &data_size);
-               ps->offset = old_offset;
+       if (MARSHALLING(ps)) {
+               /* 
+                * Writing - temporarily move the offset pointer.
+                */
+               uint32 old_offset = ps->data_offset;
+               ps->data_offset = ptr_uint32;
+               if(!prs_uint32(name, ps, depth, &data_size)) {
+                       ps->data_offset = old_offset;
+                       return False;
+               }
+               ps->data_offset = old_offset;
        }
        return True;
 }
-
index 9f446cc86a58c712596c321b431a66dcfbf03efc..23262279a488b615b89fce64fd354bb9ae3d0acb 100644 (file)
@@ -2,9 +2,9 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
  *  
  *  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
@@ -28,95 +28,43 @@ extern int DEBUGLEVEL;
 
 
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-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->level = level;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-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;
-
-       prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
-       depth++;
-
-       prs_align(ps);
-       
-       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    ));
-       }
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-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;
-
-       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));
-
-       return True;
-}
-
-
-/*******************************************************************
-creates a structure.
-********************************************************************/
-BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *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->level = level;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       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    ));
+       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+               return False;
+
+       if (r_q->ptr != 0) {
+               if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
+                       return False;
+               if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
+                       return False;
+               if(!prs_uint32("level    ", ps, depth, &r_q->level))
+                       return False;
        }
 
        return True;
@@ -126,64 +74,75 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
-{
-       memcpy(&(q_u->pol), pol, sizeof(q_u->pol));
 
-       return True;
+void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
+{
+       memcpy(&q_u->pol, pol, sizeof(q_u->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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
@@ -191,167 +150,197 @@ 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)
-       {
+       if (ptr != 0) {
                uint32 hdr_offset;
                uint32 old_offset;
-               smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset);
-               old_offset = ps->offset;
-               if (ptr3 != NULL)
-               {
-                       prs_uint32("ptr3", ps, depth, ptr3);
+               if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset))
+                       return False;
+
+               old_offset = prs_offset(ps);
+
+               if (ptr3 != NULL) {
+                       if(!prs_uint32("ptr3", ps, depth, ptr3))
+                               return False;
                }
-               if (ptr3 == NULL || *ptr3 != 0)
-               {
-                       sec_io_desc_buf("data   ", data   , ps, depth);
+
+               if (ptr3 == NULL || *ptr3 != 0) {
+                       if(!sec_io_desc_buf("data   ", &data, ps, depth)) /* JRA - this line is probably wrong... */
+                               return False;
                }
-               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);
-               prs_align(ps);
+
+               if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
+                                  data->max_len, data->len))
+                               return False;
+               if(!prs_set_offset(ps, old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
+                       return False;
+
+               if(prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits 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)
+
+void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+                               char *name, char *class, SEC_ACCESS *sam_access,
+                               SEC_DESC_BUF *sec_buf)
 {
-       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  = name  != NULL ? strlen(name ) + 1: 0;
+       int len_class = class != NULL ? strlen(class) + 1: 0;
 
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+       memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
 
-       make_uni_hdr(&(q_c->hdr_name), len_name);
-       make_unistr2(&(q_c->uni_name), key_name, len_name);
+       init_uni_hdr(&q_c->hdr_name, len_name);
+       init_unistr2(&q_c->uni_name, name, len_name);
 
-       make_uni_hdr(&(q_c->hdr_class), len_class);
-       make_unistr2(&(q_c->uni_class), key_class, len_class);
+       init_uni_hdr(&q_c->hdr_class, len_class);
+       init_unistr2(&q_c->uni_class, class, len_class);
 
        q_c->reserved = 0x00000000;
-       memcpy(&(q_c->sam_access), sam_access, sizeof(q_c->sam_access));
+       memcpy(&q_c->sam_access, sam_access, sizeof(q_c->sam_access));
 
        q_c->ptr1 = 1;
        q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
 
        q_c->data = sec_buf;
        q_c->ptr2 = 1;
-       make_buf_hdr(&(q_c->hdr_sec), sec_len, sec_len);
+       init_buf_hdr(&q_c->hdr_sec, sec_buf->len, sec_buf->len);
        q_c->ptr3 = 1;
-       make_sec_desc_buf(q_c->data, sec_len, sec);
-
        q_c->unknown_2 = 0x00000000;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pnt_pol), 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);
-       prs_align(ps);
-
-       prs_uint32("reserved", ps, depth, &(r_q->reserved));
-       sec_io_access("sam_access", &r_q->sam_access, ps, depth);
-
-       prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
-       if (r_q->ptr1 != 0)
-       {
-               prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
+       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+               return False;
+
+       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("reserved", ps, depth, &r_q->reserved))
+               return False;
+       if(!sec_io_access("sam_access", &r_q->sam_access, ps, depth))
+               return False;
+
+       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+               return False;
+
+       if (r_q->ptr1 != 0) {
+               if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+                       return False;
        }
 
-       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);
+       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+               return False;
+       if(!reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth))
+               return False;
 
-       prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
+       if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_r->key_pol), ps, depth);
-       prs_uint32("unknown", ps, depth, &(r_r->unknown));
+       if(!smb_io_pol_hnd("", &r_r->key_pol, ps, depth))
+               return False;
+       if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+
+void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
                                char *name)
 {
        int len_name  = name  != NULL ? strlen(name ) + 1: 0;
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
-
-       make_uni_hdr(&(q_c->hdr_name), len_name);
-       make_unistr2(&(q_c->uni_name), name, len_name);
+       memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
 
-       return True;
+       init_uni_hdr(&q_c->hdr_name, len_name);
+       init_unistr2(&q_c->uni_name, name, len_name);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+               return False;
 
-       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);
+       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
 
        return True;
 }
@@ -360,112 +349,127 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+
+void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
                                char *name)
 {
        int len_name  = name  != NULL ? strlen(name ) + 1: 0;
        ZERO_STRUCTP(q_c);
 
-       memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+       memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
 
-       make_uni_hdr(&(q_c->hdr_name), len_name);
-       make_unistr2(&(q_c->uni_name), name, len_name);
-
-       return True;
+       init_uni_hdr(&q_c->hdr_name, len_name);
+       init_unistr2(&q_c->uni_name, name, len_name);
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+               return False;
 
-       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);
+       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
+
+void init_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->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;
+       memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
+       init_uni_hdr(&q_o->hdr_class, max_class_len);
        q_o->uni_class.uni_max_len = max_class_len;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       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);
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
+       if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(prs_align(ps))
+               return False;
 
        return True;
 }
@@ -474,168 +478,198 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       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("mak_subkeysize", ps, depth, &(r_r->max_subkeysize));
-       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      ));
-       smb_io_time("mod_time     ", &(r_r->mod_time), ps, depth);
+       if(!smb_io_unihdr ("", &r_r->hdr_class, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_r->uni_class, r_r->hdr_class.buffer, ps, depth))
+               return False;
+
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_subkeys   ", ps, depth, &r_r->num_subkeys))
+               return False;
+       if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen))
+               return False;
+       if(!prs_uint32("mak_subkeysize", ps, depth, &r_r->max_subkeysize))
+               return False;
+       if(!prs_uint32("num_values    ", ps, depth, &r_r->num_values))
+               return False;
+       if(!prs_uint32("max_valnamelen", ps, depth, &r_r->max_valnamelen))
+               return False;
+       if(!prs_uint32("max_valbufsize", ps, depth, &r_r->max_valbufsize))
+               return False;
+       if(!prs_uint32("sec_desc      ", ps, depth, &r_r->sec_desc))
+               return False;
+       if(!smb_io_time("mod_time     ", &r_r->mod_time, ps, depth))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
-{
-       memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
 
-       return True;
+void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
+{
+       memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("unknown", ps, depth, &(r_r->unknown));
-       prs_uint32("status" , ps, depth, &(r_r->status ));
+       if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+               return False;
+       if(!prs_uint32("status" , ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
+
+void init_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->level = level;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       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    ));
+       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+               return False;
+       if (r_q->ptr != 0) {
+               if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
+                       return False;
+               if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
+                       return False;
+               if(!prs_uint32("level    ", ps, depth, &r_q->level))
+                       return False;
        }
 
        return True;
 }
 
-
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes an REG_Q_CLOSE structure.
+ Inits an REG_Q_CLOSE structure.
 ********************************************************************/
-BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
-{
-       if (q_c == NULL || hnd == NULL) return False;
 
-       DEBUG(5,("make_reg_q_close\n"));
-
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+void init_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
+{
+       DEBUG(5,("init_reg_q_close\n"));
 
-       return True;
+       memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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");
+       prs_debug(ps, depth, desc, "reg_io_q_unknown_1");
        depth++;
 
-       prs_align(ps);
+       if(prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
 
        return True;
 }
@@ -643,19 +677,25 @@ 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)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "reg_io_r_close");
+       prs_debug(ps, depth, desc, "reg_io_r_unknown_1");
        depth++;
 
-       prs_align(ps);
+       if(prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("", &(r_u->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
@@ -663,41 +703,43 @@ 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)
-{
-       if (q_i == NULL) return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf)
+{
+       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
 
-       q_i->sec_info = sec_info;
+       q_i->sec_info = DACL_SECURITY_INFORMATION;
 
        q_i->ptr = 1;
-       make_buf_hdr(&(q_i->hdr_sec), buf_len, buf_len);
-       make_sec_desc_buf(q_i->data, buf_len, sec_desc);
-
-       return True;
+       init_buf_hdr(&q_i->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
+       q_i->data = sec_desc_buf;
 }
 
 /*******************************************************************
 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth); 
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
 
-       prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
-       prs_uint32("ptr    ", ps, depth, &(r_q->ptr    ));
+       if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+               return False;
+       if(!prs_uint32("ptr    ", ps, depth, &r_q->ptr))
+               return False;
 
-       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+       if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+               return False;
 
        return True;
 }
@@ -705,16 +747,20 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
@@ -723,46 +769,47 @@ 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)
-{
-       if (q_i == NULL) return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, 
+                               uint32 sec_buf_size, SEC_DESC_BUF *psdb)
+{
+       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
 
-       q_i->sec_info = sec_info;
+       q_i->sec_info = OWNER_SECURITY_INFORMATION |
+                       GROUP_SECURITY_INFORMATION |
+                       DACL_SECURITY_INFORMATION;
 
-       q_i->ptr = sec_buf != NULL ? 1 : 0;
-       q_i->data = sec_buf;
+       q_i->ptr = psdb != NULL ? 1 : 0;
+       q_i->data = psdb;
 
-       if (sec_buf != NULL)
-       {
-               make_buf_hdr(&(q_i->hdr_sec), buf_len, 0);
-               make_sec_desc_buf(q_i->data, buf_len, NULL);
-       }
-
-       return True;
+       init_buf_hdr(&q_i->hdr_sec, sec_buf_size, 0);
 }
 
 /*******************************************************************
 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pol), ps, depth); 
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
 
-       prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
-       prs_uint32("ptr     ", ps, depth, &(r_q->ptr     ));
+       if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+               return False;
+       if(!prs_uint32("ptr     ", ps, depth, &r_q->ptr))
+               return False;
 
-       reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+       if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+               return False;
 
        return True;
 }
@@ -771,196 +818,217 @@ 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, 
+ void init_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;
-
        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);
+       init_buf_hdr(&r_i->hdr_sec, buf_len, buf_len);
+       init_sec_desc_buf(r_i->data, buf_len, 1);
 
        r_i->status = status; /* 0x0000 0000 or 0x0000 007a */
-
-       return True;
 }
 #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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("ptr      ", ps, depth, &(r_q->ptr      ));
-
-       if (r_q->ptr != 0)
-       {
-               smb_io_hdrbuf("", &(r_q->hdr_sec), ps, depth);
-               sec_io_desc_buf("", r_q->data, ps, depth);
-
-               prs_align(ps);
+       if(!prs_uint32("ptr      ", ps, depth, &r_q->ptr))
+               return False;
+
+       if (r_q->ptr != 0) {
+               if(!smb_io_hdrbuf("", &r_q->hdr_sec, ps, depth))
+                       return False;
+               if(!sec_io_desc_buf("", &r_q->data, ps, depth))
+                       return False;
+               if(prs_align(ps))
+                       return False;
        }
 
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-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;
-
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
-
-       make_uni_hdr(&(q_i->hdr_val), len_type);
-       make_unistr2(&(q_i->uni_val), val_name, len_type);
+void init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type,
+                               time_t unix_time, uint8 major, uint8 minor)
+{
+       int len_type  = strlen(product_type);
 
-       q_i->ptr_type = 1;
-       q_i->type = 0x77872314;
+       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
 
-       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;
+       init_uni_hdr(&q_i->hdr_type, len_type);
+       init_unistr2(&q_i->uni_type, product_type, len_type);
 
-       q_i->ptr_max_len = 1;
-       q_i->buf_max_len = 0x104;
+       q_i->ptr1 = 1;
+       unix_to_nt_time(&q_i->time, unix_time);
+       q_i->major_version1 = major;
+       q_i->minor_version1 = minor;
+       memset(q_i->pad1, 0, sizeof(q_i->pad1));
 
-       q_i->ptr_len = 1;
-       q_i->buf_len = 0x0;
+       q_i->ptr2 = 1;
+       q_i->major_version2 = major;
+       q_i->minor_version2 = minor;
+       memset(q_i->pad2, 0, sizeof(q_i->pad2));
 
-       return True;
+       q_i->ptr3 = 1;
+       q_i->unknown = 0x00000000;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       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);
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
+       if(!smb_io_unihdr ("", &r_q->hdr_type, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_type, r_q->hdr_type.buffer, ps, depth))
+               return False;
+
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
-       if (r_q->ptr_type != 0)
-       {
-               prs_uint32("type", ps, depth, &(r_q->type));
+       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+               return False;
+
+       if (r_q->ptr1 != 0) {
+               if(!smb_io_time("", &r_q->time, ps, depth))
+                       return False;
+               if(!prs_uint8 ("major_version1", ps, depth, &r_q->major_version1))
+                       return False;
+               if(!prs_uint8 ("minor_version1", ps, depth, &r_q->minor_version1))
+                       return False;
+               if(!prs_uint8s(False, "pad1", ps, depth, r_q->pad1, sizeof(r_q->pad1)))
+                       return False;
        }
 
-       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);
-       prs_align(ps);
+       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+               return False;
 
-       prs_uint32("ptr_max_len", ps, depth, &(r_q->ptr_max_len));
-       if (r_q->ptr_max_len != 0)
-       {
-               prs_uint32("buf_max_len", ps, depth, &(r_q->buf_max_len));
+       if (r_q->ptr2 != 0) {
+               if(!prs_uint8 ("major_version2", ps, depth, &r_q->major_version2))
+                       return False;
+               if(!prs_uint8 ("minor_version2", ps, depth, &r_q->minor_version2))
+                       return False;
+               if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
+                       return False;
        }
 
-       prs_uint32("ptr_len", ps, depth, &(r_q->ptr_len));
-       if (r_q->ptr_len != 0)
-       {
-               prs_uint32("buf_len", ps, depth, &(r_q->buf_len));
+       if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
+               return False;
+
+       if (r_q->ptr3 != 0) {
+               if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
+                       return False;
        }
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_r_info(REG_R_INFO *r_r,
-                               uint32 *type, BUFFER2 *buf,
+
+void init_reg_r_info(REG_R_INFO *r_r,
+                               uint32 level, char *os_type,
+                               uint32 unknown_0, uint32 unknown_1,
                                uint32 status)
 {
-       if (r_r == NULL) return False;
+       uint8 buf[512];
+       int len = dos_struni2((char *)buf, os_type, sizeof(buf));
 
-       r_r->ptr_type = type != NULL ? 1 : 0;
-       r_r->type = type;
+       r_r->ptr1 = 1;
+       r_r->level = level;
 
-       r_r->ptr_uni_type = buf != NULL ? 1 : 0;
-       r_r->uni_type = buf;
+       r_r->ptr_type = 1;
+       init_buffer2(&r_r->uni_type, buf, len*2);
 
-       if (buf != NULL)
-       {
-               r_r->ptr_max_len = 1;
-               r_r->buf_max_len = r_r->uni_type->buf_max_len;
+       r_r->ptr2 = 1;
+       r_r->unknown_0 = unknown_0;
 
-               r_r->ptr_len = 1;
-               r_r->buf_len = r_r->uni_type->buf_len;
-       }
-       else
-       {
-               r_r->ptr_max_len = 0;
-               r_r->ptr_len = 0;
-       }
-               
-       r_r->status = status;
+       r_r->ptr3 = 1;
+       r_r->unknown_1 = unknown_1;
 
-       return True;
+       r_r->status = status;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type));
-       if (r_r->ptr_type != 0)
-       {
-               prs_uint32("type", ps, depth, r_r->type);
-       }
+       if(!prs_uint32("ptr1", ps, depth, &r_r->ptr1))
+               return False;
+
+       if (r_r->ptr1 != 0) {
+               if(!prs_uint32("level", ps, depth, &r_r->level))
+                       return False;
+               if(!prs_uint32("ptr_type", ps, depth, &r_r->ptr_type))
+                       return False;
+
+               if(!smb_io_buffer2("uni_type", &r_r->uni_type, r_r->ptr_type, ps, depth))
+                       return False;
+               if(prs_align(ps))
+                       return False;
+
+               if(!prs_uint32("ptr2", ps, depth, &r_r->ptr2))
+                       return False;
+
+               if (r_r->ptr2 != 0) {
+                       if(!prs_uint32("unknown_0", ps, depth, &r_r->unknown_0))
+                               return False;
+               }
 
-       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);
-       prs_align(ps);
+               if(!prs_uint32("ptr3", ps, depth, &r_r->ptr3))
+                       return False;
 
-       prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len));
-       if (r_r->ptr_max_len != 0)
-       {
-               prs_uint32("buf_max_len", ps, depth, &(r_r->buf_max_len));
-       }
+               if (r_r->ptr3 != 0) {
+                       if(!prs_uint32("unknown_1", ps, depth, &r_r->unknown_1))
+                               return False;
+               }
 
-       prs_uint32("ptr_len", ps, depth, &(r_r->ptr_len));
-       if (r_r->ptr_len != 0)
-       {
-               prs_uint32("buf_len", ps, depth, &(r_r->buf_len));
        }
-
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
@@ -968,20 +1036,17 @@ 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,
+
+void init_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;
-
        ZERO_STRUCTP(q_i);
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       memcpy(&q_i->pol, pol, sizeof(q_i->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;
+       init_uni_hdr(&q_i->hdr_name, max_val_len);
        q_i->uni_name.uni_max_len = max_val_len;
        
        q_i->ptr_type = 1;
@@ -995,49 +1060,61 @@ BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
 
        q_i->ptr2 = 1;
        q_i->len_value2 = 0;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
+       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+               return False;
        
-       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);
-       prs_align(ps);
-
-       prs_uint32("ptr_type", ps, depth, &(q_q->ptr_type));
-
-       if (q_q->ptr_type != 0)
-       {
-               prs_uint32("type", ps, depth, &(q_q->type));
+       if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
+               return False;
+       if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_type", ps, depth, &q_q->ptr_type))
+               return False;
+
+       if (q_q->ptr_type != 0) {
+               if(!prs_uint32("type", ps, depth, &q_q->type))
+                       return False;
        }
 
-       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);
-       prs_align(ps);
-
-       prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
-       if (q_q->ptr1 != 0)
-       {
-               prs_uint32("len_value1", ps, depth, &(q_q->len_value1));
+       if(!prs_uint32("ptr_value", ps, depth, &q_q->ptr_value))
+               return False;
+       if(!smb_io_buffer2("buf_value", &q_q->buf_value, q_q->ptr_value, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+               return False;
+       if (q_q->ptr1 != 0) {
+               if(!prs_uint32("len_value1", ps, depth, &q_q->len_value1))
+                       return False;
        }
-       prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
-       if (q_q->ptr2 != 0)
-       {
-               prs_uint32("len_value2", ps, depth, &(q_q->len_value2));
+       if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+               return False;
+       if (q_q->ptr2 != 0) {
+               if(!prs_uint32("len_value2", ps, depth, &q_q->len_value2))
+                       return False;
        }
 
        return True;
@@ -1046,43 +1123,56 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       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));
-
-       if (r_q->ptr_type != 0)
-       {
-               prs_uint32("type", ps, depth, &(r_q->type));
+       if(!smb_io_unihdr ("hdr_name", &r_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("uni_name", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_type", ps, depth, &r_q->ptr_type))
+               return False;
+
+       if (r_q->ptr_type != 0) {
+               if(!prs_uint32("type", ps, depth, &r_q->type))
+                       return False;
        }
 
-       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);
-       prs_align(ps);
-
-       prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
-       if (r_q->ptr1 != 0)
-       {
-               prs_uint32("len_value1", ps, depth, &(r_q->len_value1));
+       if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
+               return False;
+       if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+               return False;
+       if (r_q->ptr1 != 0) {
+               if(!prs_uint32("len_value1", ps, depth, &r_q->len_value1))
+                       return False;
        }
 
-       prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
-       if (r_q->ptr2 != 0)
-       {
-               prs_uint32("len_value2", ps, depth, &(r_q->len_value2));
+       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+               return False;
+       if (r_q->ptr2 != 0) {
+               if(!prs_uint32("len_value2", ps, depth, &r_q->len_value2))
+                       return False;
        }
 
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
@@ -1090,48 +1180,55 @@ 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,
+
+void init_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;
-
        ZERO_STRUCTP(q_i);
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
 
-       make_uni_hdr(&q_i->hdr_name, val_len);
-       make_unistr2(&(q_i->uni_name), val_name, val_len);
+       init_uni_hdr(&q_i->hdr_name, val_len);
+       init_unistr2(&q_i->uni_name, val_name, val_len);
        
        q_i->type      = type;
        q_i->buf_value = val;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
+       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+               return False;
        
-       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));
-       smb_io_buffer3("buf_value", q_q->buf_value, ps, depth);
-       prs_align(ps);
+       if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
+
+       if(!prs_uint32("type", ps, depth, &q_q->type))
+               return False;
+       if(!smb_io_buffer3("buf_value", q_q->buf_value, ps, depth))
+               return False;
+       if(prs_align(ps))
+               return False;
 
        return True;
 }
@@ -1139,16 +1236,20 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
@@ -1156,11 +1257,10 @@ 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)
-{
-       if (q_i == NULL) return False;
 
-       memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+{
+       memcpy(&q_i->pol, pol, sizeof(q_i->pol));
 
        q_i->key_index = key_idx;
        q_i->key_name_len = 0;
@@ -1174,49 +1274,58 @@ 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 ? */
-
-       return True;
+       unix_to_nt_time(&q_i->time, 0);            /* current time? */
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(q_q->pol), ps, depth); 
+       if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+               return False;
        
-       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));
-
-       prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
-
-       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));
+       if(!prs_uint32("key_index", ps, depth, &q_q->key_index))
+               return False;
+       if(!prs_uint16("key_name_len", ps, depth, &q_q->key_name_len))
+               return False;
+       if(!prs_uint16("unknown_1", ps, depth, &q_q->unknown_1))
+               return False;
+
+       if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+               return False;
+
+       if (q_q->ptr1 != 0) {
+               if(!prs_uint32("unknown_2", ps, depth, &q_q->unknown_2))
+                       return False;
+               if(!prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1)))
+                       return False;
        }
 
-       prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
+       if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+               return False;
 
-       if (q_q->ptr2 != 0)
-       {
-               prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2));
+       if (q_q->ptr2 != 0) {
+               if(!prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2)))
+                       return False;
        }
 
-       prs_uint32("ptr3", ps, depth, &(q_q->ptr3));
+       if(!prs_uint32("ptr3", ps, depth, &q_q->ptr3))
+               return False;
 
-       if (q_q->ptr3 != 0)
-       {
-               smb_io_time("", &(q_q->time), ps, depth);
+       if (q_q->ptr3 != 0) {
+               if(!smb_io_time("", &q_q->time, ps, depth))
+                       return False;
        }
 
        return True;
@@ -1225,193 +1334,141 @@ 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)
 {
-       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);
+       if(prs_align(ps))
+               return False;
        
-       prs_uint16("key_name_len", ps, depth, &(r_q->key_name_len));
-       prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
-
-       prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
-
-       if (r_q->ptr1 != 0)
-       {
-               prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
-               prs_uint32("unknown_3", ps, depth, &(r_q->unknown_3));
-               smb_io_unistr3("key_name", &(r_q->key_name), ps, depth);
-               prs_align(ps);
+       if(!prs_uint16("key_name_len", ps, depth, &r_q->key_name_len))
+               return False;
+       if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
+               return False;
+
+       if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+               return False;
+
+       if (r_q->ptr1 != 0) {
+               if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+                       return False;
+               if(!prs_uint32("unknown_3", ps, depth, &r_q->unknown_3))
+                       return False;
+               if(!smb_io_unistr3("key_name", &r_q->key_name, ps, depth))
+                       return False;
+               if(prs_align(ps))
+                       return False;
        }
 
-       prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
+       if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+               return False;
 
-       if (r_q->ptr2 != 0)
-       {
-               prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2));
+       if (r_q->ptr2 != 0) {
+               if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
+                       return False;
        }
 
-       prs_uint32("ptr3", ps, depth, &(r_q->ptr3));
+       if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
+               return False;
 
-       if (r_q->ptr3 != 0)
-       {
-               smb_io_time("", &(r_q->time), ps, depth);
+       if (r_q->ptr3 != 0) {
+               if(!smb_io_time("", &r_q->time, ps, depth))
+                       return False;
        }
 
-       prs_uint32("status", ps, depth, &(r_q->status));
+       if(!prs_uint32("status", ps, depth, &r_q->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
 makes a structure.
 ********************************************************************/
-BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+
+void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
                                char *key_name, uint32 unk)
 {
        int len_name = strlen(key_name)+1;
 
-       if (r_q == NULL) return False;
-
-       memcpy(&(r_q->pol), pol, sizeof(r_q->pol));
+       memcpy(&r_q->pol, pol, sizeof(r_q->pol));
 
-       make_uni_hdr(&(r_q->hdr_name), len_name);
-       make_unistr2(&(r_q->uni_name), key_name, len_name);
+       init_uni_hdr(&r_q->hdr_name, len_name);
+       init_unistr2(&r_q->uni_name, key_name, len_name);
 
        r_q->unknown_0 = 0x00000000;
        r_q->unknown_1 = unk;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_q->pol), 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);
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
+       if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+               return False;
+
+       if(prs_align(ps))
+               return False;
        
-       prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
-       prs_uint32("unknown_1", ps, depth, &(r_q->unknown_1));
+       if(!prs_uint32("unknown_0", ps, depth, &r_q->unknown_0))
+               return False;
+       if(!prs_uint32("unknown_1", ps, depth, &r_q->unknown_1))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-creates a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+
+void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
                                POLICY_HND *pol, uint32 status)
 {
-       if (r_r == NULL) return False;
-
-       memcpy(&(r_r->pol), pol, sizeof(r_r->pol));
+       memcpy(&r_r->pol, pol, sizeof(r_r->pol));
        r_r->status = status;
-
-       return True;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
+
 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);
+       if(prs_align(ps))
+               return False;
        
-       smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+       if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_r->status));
+       if(!prs_uint32("status", ps, depth, &r_r->status))
+               return False;
 
        return True;
 }
-
-/*******************************************************************
-makes a structure.
-********************************************************************/
-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;
-
-       ZERO_STRUCTP(q_i);
-
-       q_i->ptr_0 = 1;
-       q_i->ptr_1 = 1;
-       q_i->ptr_2 = 1;
-
-       make_uni_hdr(&q_i->hdr_msg, len);
-       make_unistr2(&(q_i->uni_msg), msg, len);
-       
-       q_i->timeout = timeout;
-       q_i->flags   = flags;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL reg_io_q_shutdown(char *desc,  REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth)
-{
-       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);
-       prs_align(ps);
-
-       prs_uint32("timeout", ps, depth, &(q_q->timeout));
-       prs_uint16("flags  ", ps, depth, &(q_q->flags  ));
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL reg_io_r_shutdown(char *desc,  REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth)
-{
-       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 ac6ea8ea7e078bbbc80367ba1381d8cddd1644bd..d4ea84628ad72df7934c72cc96b735bb30faafdb 100644 (file)
@@ -3,9 +3,10 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Jeremy Allison                    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
@@ -32,501 +33,476 @@ extern int DEBUGLEVEL;
 interface/version dce/rpc pipe identification
 ********************************************************************/
 
-#define TRANS_SYNT_V2             \
-{                                 \
-       {                             \
-               0x04, 0x5d, 0x88, 0x8a,   \
-               0xeb, 0x1c, 0xc9, 0x11,   \
-               0x9f, 0xe8, 0x08, 0x00,   \
-               0x2b, 0x10, 0x48, 0x60    \
-       }, 0x02                       \
-}                                 \
-
-#define SYNT_SVCCTL_V2          \
-{                                 \
-       {                             \
-               0x81, 0xbb, 0x7a, 0x36,   \
-               0x44, 0x98, 0xf1, 0x35,   \
-               0xad, 0x32, 0x98, 0xf0,   \
-               0x38, 0x00, 0x10, 0x03    \
-       }, 0x02                       \
-}                                 \
-
-#define SYNT_BROWSER_V0          \
-{                                 \
-       {                             \
-               0x98, 0xd0, 0xff, 0x6b,   \
-               0x12, 0xa1, 0x10, 0x36,   \
-               0x98, 0x33, 0x01, 0x28,   \
-               0x92, 0x02, 0x01, 0x62    \
-       }, 0x00                       \
-}                                 \
-
-#define SYNT_NETLOGON_V2          \
-{                                 \
-       {                             \
-               0x04, 0x5d, 0x88, 0x8a,   \
-               0xeb, 0x1c, 0xc9, 0x11,   \
-               0x9f, 0xe8, 0x08, 0x00,   \
-               0x2b, 0x10, 0x48, 0x60    \
-       }, 0x02                       \
-}                                 \
-
-#define SYNT_WKSSVC_V1            \
-{                                 \
-       {                             \
-               0x98, 0xd0, 0xff, 0x6b,   \
-               0x12, 0xa1, 0x10, 0x36,   \
-               0x98, 0x33, 0x46, 0xc3,   \
-               0xf8, 0x7e, 0x34, 0x5a    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_SRVSVC_V3            \
-{                                 \
-       {                             \
-               0xc8, 0x4f, 0x32, 0x4b,   \
-               0x70, 0x16, 0xd3, 0x01,   \
-               0x12, 0x78, 0x5a, 0x47,   \
-               0xbf, 0x6e, 0xe1, 0x88    \
-       }, 0x03                       \
-}                                 \
-
-#define SYNT_LSARPC_V0            \
-{                                 \
-       {                             \
-               0x78, 0x57, 0x34, 0x12,   \
-               0x34, 0x12, 0xcd, 0xab,   \
-               0xef, 0x00, 0x01, 0x23,   \
-               0x45, 0x67, 0x89, 0xab    \
-       }, 0x00                       \
-}                                 \
-
-#define SYNT_SAMR_V1              \
-{                                 \
-       {                             \
-               0x78, 0x57, 0x34, 0x12,   \
-               0x34, 0x12, 0xcd, 0xab,   \
-               0xef, 0x00, 0x01, 0x23,   \
-               0x45, 0x67, 0x89, 0xac    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_NETLOGON_V1          \
-{                                 \
-       {                             \
-               0x78, 0x56, 0x34, 0x12,   \
-               0x34, 0x12, 0xcd, 0xab,   \
-               0xef, 0x00, 0x01, 0x23,   \
-               0x45, 0x67, 0xcf, 0xfb    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_WINREG_V1            \
-{                                 \
-       {                             \
-               0x01, 0xd0, 0x8c, 0x33,   \
-               0x44, 0x22, 0xf1, 0x31,   \
-               0xaa, 0xaa, 0x90, 0x00,   \
-               0x38, 0x00, 0x10, 0x03    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_ATSVC_V1            \
-{                                 \
-       {                             \
-               0x82, 0x06, 0xf7, 0x1f,   \
-               0x51, 0x0a, 0xe8, 0x30,   \
-               0x07, 0x6d, 0x74, 0x0b,   \
-               0xe8, 0xce, 0xe9, 0x8b    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_SPOOLSS_V1           \
-{                                 \
-       {                             \
-               0x78, 0x56, 0x34, 0x12,   \
-               0x34, 0x12, 0xcd, 0xab,   \
-               0xef, 0x00, 0x01, 0x23,   \
-               0x45, 0x67, 0x89, 0xab    \
-       }, 0x01                       \
-}                                 \
-
-#define SYNT_NONE_V0              \
-{                                 \
-       {                             \
-               0x00, 0x00, 0x00, 0x00,   \
-               0x00, 0x00, 0x00, 0x00,   \
-               0x00, 0x00, 0x00, 0x00,   \
-               0x00, 0x00, 0x00, 0x00    \
-       }, 0x00                       \
-}                                 \
-
-#define SYNT_EVENTLOG_V0            \
-{                                 \
-       {                             \
-               0xdc, 0x3f, 0x27, 0x82,   \
-               0x2a, 0xe3, 0xc3, 0x18,   \
-               0x3f, 0x78, 0x82, 0x79,   \
-               0x29, 0xdc, 0x23, 0xea    \
-       }, 0x00                       \
-}
-                                 \
+#define TRANS_SYNT_V2                       \
+{                                           \
+       {                                   \
+               0x8a885d04, 0x1ceb, 0x11c9, \
+               { 0x9f, 0xe8, 0x08, 0x00,   \
+               0x2b, 0x10, 0x48, 0x60 }    \
+       }, 0x02                             \
+}
+
+#define SYNT_NETLOGON_V2                    \
+{                                           \
+       {                                   \
+               0x8a885d04, 0x1ceb, 0x11c9, \
+               { 0x9f, 0xe8, 0x08, 0x00,   \
+               0x2b, 0x10, 0x48, 0x60 }    \
+       }, 0x02                             \
+}
+
+#define SYNT_WKSSVC_V1                      \
+{                                           \
+       {                                   \
+               0x6bffd098, 0xa112, 0x3610, \
+               { 0x98, 0x33, 0x46, 0xc3,   \
+               0xf8, 0x7e, 0x34, 0x5a }    \
+       }, 0x01                             \
+}
+
+#define SYNT_SRVSVC_V3                      \
+{                                           \
+       {                                   \
+               0x4b324fc8, 0x1670, 0x01d3, \
+               { 0x12, 0x78, 0x5a, 0x47,   \
+               0xbf, 0x6e, 0xe1, 0x88 }    \
+       }, 0x03                             \
+}
+
+#define SYNT_LSARPC_V0                      \
+{                                           \
+       {                                   \
+               0x12345778, 0x1234, 0xabcd, \
+               { 0xef, 0x00, 0x01, 0x23,   \
+               0x45, 0x67, 0x89, 0xab }    \
+       }, 0x00                             \
+}
+
+#define SYNT_SAMR_V1                        \
+{                                           \
+       {                                   \
+               0x12345778, 0x1234, 0xabcd, \
+               { 0xef, 0x00, 0x01, 0x23,   \
+               0x45, 0x67, 0x89, 0xac }    \
+       }, 0x01                             \
+}
+
+#define SYNT_NETLOGON_V1                    \
+{                                           \
+       {                                   \
+               0x12345678, 0x1234, 0xabcd, \
+               { 0xef, 0x00, 0x01, 0x23,   \
+               0x45, 0x67, 0xcf, 0xfb }    \
+       }, 0x01                             \
+}
+
+#define SYNT_WINREG_V1                      \
+{                                           \
+       {                                   \
+               0x338cd001, 0x2244, 0x31f1, \
+               { 0xaa, 0xaa, 0x90, 0x00,   \
+               0x38, 0x00, 0x10, 0x03 }    \
+       }, 0x01                             \
+}
+
+#define SYNT_NONE_V0                        \
+{                                           \
+       {                                   \
+               0x0, 0x0, 0x0,              \
+               { 0x00, 0x00, 0x00, 0x00,   \
+               0x00, 0x00, 0x00, 0x00 }    \
+       }, 0x00                             \
+}
+
+/* pipe string names */
+#define PIPE_SRVSVC   "\\PIPE\\srvsvc"
+#define PIPE_SAMR     "\\PIPE\\samr"
+#define PIPE_WINREG   "\\PIPE\\winreg"
+#define PIPE_WKSSVC   "\\PIPE\\wkssvc"
+#define PIPE_NETLOGON "\\PIPE\\NETLOGON"
+#define PIPE_NTLSA    "\\PIPE\\ntlsa"
+#define PIPE_NTSVCS   "\\PIPE\\ntsvcs"
+#define PIPE_LSASS    "\\PIPE\\lsass"
+#define PIPE_LSARPC   "\\PIPE\\lsarpc"
+
 struct pipe_id_info pipe_names [] =
 {
        /* client pipe , abstract syntax , server pipe   , transfer syntax */
        { PIPE_LSARPC  , SYNT_LSARPC_V0  , PIPE_LSASS    , TRANS_SYNT_V2 },
-       { PIPE_BROWSER , SYNT_BROWSER_V0 , PIPE_NTSVCS   , TRANS_SYNT_V2 },
        { PIPE_SAMR    , SYNT_SAMR_V1    , PIPE_LSASS    , TRANS_SYNT_V2 },
        { PIPE_NETLOGON, SYNT_NETLOGON_V1, PIPE_LSASS    , TRANS_SYNT_V2 },
        { PIPE_SRVSVC  , SYNT_SRVSVC_V3  , PIPE_NTSVCS   , TRANS_SYNT_V2 },
-       { PIPE_SVCCTL  , SYNT_SVCCTL_V2  , PIPE_NTSVCS   , TRANS_SYNT_V2 },
        { PIPE_WKSSVC  , SYNT_WKSSVC_V1  , PIPE_NTSVCS   , TRANS_SYNT_V2 },
        { PIPE_WINREG  , SYNT_WINREG_V1  , PIPE_WINREG   , TRANS_SYNT_V2 },
-       { PIPE_ATSVC   , SYNT_ATSVC_V1   , PIPE_ATSVC    , TRANS_SYNT_V2 },
-       { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS  , TRANS_SYNT_V2 },
-       { PIPE_EVENTLOG, SYNT_EVENTLOG_V0, PIPE_EVENTLOG , TRANS_SYNT_V2 },
        { NULL         , SYNT_NONE_V0    , NULL          , SYNT_NONE_V0  }
 };
 
 /*******************************************************************
-creates an RPC_HDR structure.
+ Inits an RPC_HDR structure.
 ********************************************************************/
-BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+
+void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
                                uint32 call_id, int data_len, int auth_len)
 {
-       if (hdr == NULL) return False;
-
        hdr->major        = 5;               /* RPC version 5 */
        hdr->minor        = 0;               /* minor version 0 */
        hdr->pkt_type     = pkt_type;        /* RPC packet type */
        hdr->flags        = flags;           /* dce/rpc flags */
-       hdr->pack_type    = 0x10;            /* packed data representation */
+       hdr->pack_type[0] = 0x10;            /* little-endian data representation */
+       hdr->pack_type[1] = 0;               /* packed data representation */
+       hdr->pack_type[2] = 0;               /* packed data representation */
+       hdr->pack_type[3] = 0;               /* packed data representation */
        hdr->frag_len     = data_len;        /* fragment length, fill in later */
        hdr->auth_len     = auth_len;        /* authentication length */
        hdr->call_id      = call_id;         /* call identifier - match incoming RPC */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR structure.
+ Reads or writes an RPC_HDR structure.
 ********************************************************************/
+
 BOOL smb_io_rpc_hdr(char *desc,  RPC_HDR *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr");
        depth++;
 
-       prs_uint8 ("major     ", ps, depth, &(rpc->major));
-       prs_uint8 ("minor     ", ps, depth, &(rpc->minor));
-       prs_uint8 ("pkt_type  ", ps, depth, &(rpc->pkt_type));
-       prs_uint8 ("flags     ", ps, depth, &(rpc->flags));
-       prs_uint32("pack_type ", ps, depth, &(rpc->pack_type));
-       prs_uint16("frag_len  ", ps, depth, &(rpc->frag_len));
-       prs_uint16("auth_len  ", ps, depth, &(rpc->auth_len));
-       prs_uint32("call_id   ", ps, depth, &(rpc->call_id));
-
-       return True;
-}
+       if(!prs_uint8 ("major     ", ps, depth, &rpc->major))
+               return False;
 
-/*******************************************************************
-reads or writes an RPC_HDR_FAULT structure.
-********************************************************************/
-BOOL smb_io_rpc_hdr_fault(char *desc,  RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
-{
-       if (rpc == NULL) return False;
+       if(!prs_uint8 ("minor     ", ps, depth, &rpc->minor))
+               return False;
+       if(!prs_uint8 ("pkt_type  ", ps, depth, &rpc->pkt_type))
+               return False;
+       if(!prs_uint8 ("flags     ", ps, depth, &rpc->flags))
+               return False;
+       if(!prs_uint8("pack_type0", ps, depth, &rpc->pack_type[0]))
+               return False;
+       if(!prs_uint8("pack_type1", ps, depth, &rpc->pack_type[1]))
+               return False;
+       if(!prs_uint8("pack_type2", ps, depth, &rpc->pack_type[2]))
+               return False;
+       if(!prs_uint8("pack_type3", ps, depth, &rpc->pack_type[3]))
+               return False;
 
-       prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
-       depth++;
+       /*
+        * If reading and pack_type[0] == 0 then the data is in big-endian
+        * format. Set the flag in the prs_struct to specify reverse-endainness.
+        */
 
-       prs_uint32("status  ", ps, depth, &(rpc->status  ));
-       prs_uint32("reserved", ps, depth, &(rpc->reserved));
+       if (ps->io && rpc->pack_type[0] == 0) {
+               DEBUG(10,("smb_io_rpc_hdr: PDU data format is big-endian. Setting flag.\n"));
+               prs_set_bigendian_data(ps);
+       }
 
+       if(!prs_uint16("frag_len  ", ps, depth, &rpc->frag_len))
+               return False;
+       if(!prs_uint16("auth_len  ", ps, depth, &rpc->auth_len))
+               return False;
+       if(!prs_uint32("call_id   ", ps, depth, &rpc->call_id))
+               return False;
        return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_IFACE structure.
+ Reads or writes an RPC_IFACE structure.
 ********************************************************************/
-static BOOL smb_io_rpc_iface(char *desc,  RPC_IFACE *ifc, prs_struct *ps, int depth)
+
+static BOOL smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
 {
-       if (ifc == NULL) return False;
+       if (ifc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_iface");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32 ("data   ", ps, depth, &ifc->uuid.time_low))
+               return False;
+       if(!prs_uint16 ("data   ", ps, depth, &ifc->uuid.time_mid))
+               return False;
+       if(!prs_uint16 ("data   ", ps, depth, &ifc->uuid.time_hi_and_version))
+               return False;
 
-       prs_uint8s (False, "data   ", ps, depth, ifc->data, sizeof(ifc->data));
-       prs_uint32 (       "version", ps, depth, &(ifc->version));
+       if(!prs_uint8s (False, "data   ", ps, depth, ifc->uuid.remaining, sizeof(ifc->uuid.remaining)))
+               return False;
+       if(!prs_uint32 (       "version", ps, depth, &(ifc->version)))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates an RPC_ADDR_STR structure.
-
-The name can be null (RPC Alter-Context)
+ Inits an RPC_ADDR_STR structure.
 ********************************************************************/
-static BOOL make_rpc_addr_str(RPC_ADDR_STR *str, const char *name)
-{
-       if (str == NULL ) return False;
-       if (name == NULL)
-       {
-               str->len = 1;
-               fstrcpy(str->str, "");
-       }
-       else
-       {
-               str->len = strlen(name) + 1;
-               fstrcpy(str->str, name);
-       }
 
-       return True;
+static void init_rpc_addr_str(RPC_ADDR_STR *str, char *name)
+{
+       str->len = strlen(name) + 1;
+       fstrcpy(str->str, name);
 }
 
 /*******************************************************************
-reads or writes an RPC_ADDR_STR structure.
+ Reads or writes an RPC_ADDR_STR structure.
 ********************************************************************/
+
 static BOOL smb_io_rpc_addr_str(char *desc,  RPC_ADDR_STR *str, prs_struct *ps, int depth)
 {
-       if (str == NULL) return False;
+       if (str == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_addr_str");
        depth++;
-       prs_align(ps);
-
-       prs_uint16 (      "len", ps, depth, &(str->len));
-       prs_uint8s (True, "str", ps, depth, (uchar*)str->str, str->len);
+       if(!prs_align(ps))
+               return False;
 
+       if(!prs_uint16 (      "len", ps, depth, &str->len))
+               return False;
+       if(!prs_uint8s (True, "str", ps, depth, (uchar*)str->str, MIN(str->len, sizeof(str->str)) ))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates an RPC_HDR_BBA structure.
+ Inits an RPC_HDR_BBA structure.
 ********************************************************************/
-static BOOL make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
-{
-       if (bba == NULL) return False;
 
+static void init_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
+{
        bba->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
        bba->max_rsize = max_rsize; /* max receive fragment size (0x1630) */   
        bba->assoc_gid = assoc_gid; /* associated group id (0x0) */ 
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_BBA structure.
+ Reads or writes an RPC_HDR_BBA structure.
 ********************************************************************/
+
 static BOOL smb_io_rpc_hdr_bba(char *desc,  RPC_HDR_BBA *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba");
        depth++;
 
-       prs_uint16("max_tsize", ps, depth, &(rpc->max_tsize));
-       prs_uint16("max_rsize", ps, depth, &(rpc->max_rsize));
-       prs_uint32("assoc_gid", ps, depth, &(rpc->assoc_gid));
-
+       if(!prs_uint16("max_tsize", ps, depth, &rpc->max_tsize))
+               return False;
+       if(!prs_uint16("max_rsize", ps, depth, &rpc->max_rsize))
+               return False;
+       if(!prs_uint32("assoc_gid", ps, depth, &rpc->assoc_gid))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates an RPC_HDR_RB structure.
+ Inits an RPC_HDR_RB structure.
 ********************************************************************/
-BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc, 
+
+void init_rpc_hdr_rb(RPC_HDR_RB *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
                                uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
                                RPC_IFACE *abstract, RPC_IFACE *transfer)
 {
-       if (rpc == NULL) return False;
-
-       make_rpc_hdr_bba(&(rpc->bba), max_tsize, max_rsize, assoc_gid);
+       init_rpc_hdr_bba(&rpc->bba, max_tsize, max_rsize, assoc_gid);
 
        rpc->num_elements = num_elements ; /* the number of elements (0x1) */
        rpc->context_id   = context_id   ; /* presentation context identifier (0x0) */
        rpc->num_syntaxes = num_syntaxes ; /* the number of syntaxes (has always been 1?)(0x1) */
 
        /* num and vers. of interface client is using */
-       memcpy(&(rpc->abstract), abstract, sizeof(rpc->abstract));
+       rpc->abstract = *abstract;
 
        /* num and vers. of interface to use for replies */
-       memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
-
-       return True;
+       rpc->transfer = *transfer;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_RB structure.
+ Reads or writes an RPC_HDR_RB structure.
 ********************************************************************/
-BOOL smb_io_rpc_hdr_rb(char *desc,  RPC_HDR_RB *rpc, prs_struct *ps, int depth)
+
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rb");
        depth++;
 
-       smb_io_rpc_hdr_bba("", &(rpc->bba), ps, depth);
+       if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
+               return False;
 
-       prs_uint32("num_elements", ps, depth, &(rpc->num_elements));
-       prs_uint16("context_id  ", ps, depth, &(rpc->context_id  ));
-       prs_uint8 ("num_syntaxes", ps, depth, &(rpc->num_syntaxes));
+       if(!prs_uint32("num_elements", ps, depth, &rpc->num_elements))
+               return False;
+       if(!prs_uint16("context_id  ", ps, depth, &rpc->context_id ))
+               return False;
+       if(!prs_uint8 ("num_syntaxes", ps, depth, &rpc->num_syntaxes))
+               return False;
 
-       smb_io_rpc_iface("", &(rpc->abstract), ps, depth);
-       smb_io_rpc_iface("", &(rpc->transfer), ps, depth);
+       if(!smb_io_rpc_iface("", &rpc->abstract, ps, depth))
+               return False;
+       if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates an RPC_RESULTS structure.
-
-lkclXXXX only one reason at the moment!
+ Inits an RPC_RESULTS structure.
 
+ lkclXXXX only one reason at the moment!
 ********************************************************************/
-static BOOL make_rpc_results(RPC_RESULTS *res, 
+
+static void init_rpc_results(RPC_RESULTS *res, 
                                uint8 num_results, uint16 result, uint16 reason)
 {
-       if (res == NULL) return False;
-
        res->num_results = num_results; /* the number of results (0x01) */
        res->result      = result     ;  /* result (0x00 = accept) */
        res->reason      = reason     ;  /* reason (0x00 = no reason specified) */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_RESULTS structure.
-
-lkclXXXX only one reason at the moment!
+ Reads or writes an RPC_RESULTS structure.
 
+ lkclXXXX only one reason at the moment!
 ********************************************************************/
-static BOOL smb_io_rpc_results(char *desc,  RPC_RESULTS *res, prs_struct *ps, int depth)
+
+static BOOL smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
 {
-       if (res == NULL) return False;
+       if (res == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_results");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint8 ("num_results", ps, depth, &(res->num_results));
+       if(!prs_uint8 ("num_results", ps, depth, &res->num_results))    
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint16("result     ", ps, depth, &(res->result     ));
-       prs_uint16("reason     ", ps, depth, &(res->reason     ));
-
+       if(!prs_uint16("result     ", ps, depth, &res->result))
+               return False;
+       if(!prs_uint16("reason     ", ps, depth, &res->reason))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates an RPC_HDR_BA structure.
+ Init an RPC_HDR_BA structure.
 
-lkclXXXX only one reason at the moment!
-jfm: nope two ! The pipe_addr can be NULL !
+ lkclXXXX only one reason at the moment!
 
 ********************************************************************/
-BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc, 
+
+void init_rpc_hdr_ba(RPC_HDR_BA *rpc, 
                                uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
-                               const char *pipe_addr,
+                               char *pipe_addr,
                                uint8 num_results, uint16 result, uint16 reason,
                                RPC_IFACE *transfer)
 {
-       if (rpc == NULL || transfer == NULL) return False;
-
-       make_rpc_hdr_bba (&(rpc->bba ), max_tsize, max_rsize, assoc_gid);
-       make_rpc_addr_str(&(rpc->addr), pipe_addr);
-       make_rpc_results (&(rpc->res ), num_results, result, reason);
+       init_rpc_hdr_bba (&rpc->bba, max_tsize, max_rsize, assoc_gid);
+       init_rpc_addr_str(&rpc->addr, pipe_addr);
+       init_rpc_results (&rpc->res, num_results, result, reason);
 
        /* the transfer syntax from the request */
-       memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
-
-       return True;
+       memcpy(&rpc->transfer, transfer, sizeof(rpc->transfer));
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_BA structure.
+ Reads or writes an RPC_HDR_BA structure.
 ********************************************************************/
-BOOL smb_io_rpc_hdr_ba(char *desc,  RPC_HDR_BA *rpc, prs_struct *ps, int depth)
+
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_ba");
        depth++;
 
-       smb_io_rpc_hdr_bba ("", &(rpc->bba)     , ps, depth);
-       smb_io_rpc_addr_str("", &(rpc->addr)    , ps, depth);
-       smb_io_rpc_results ("", &(rpc->res)     , ps, depth);
-       smb_io_rpc_iface   ("", &(rpc->transfer), ps, depth);
-
+       if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
+               return False;
+       if(!smb_io_rpc_addr_str("", &rpc->addr, ps, depth))
+               return False;
+       if(!smb_io_rpc_results("", &rpc->res, ps, depth))
+               return False;
+       if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates an RPC_HDR_REQ structure.
+ Init an RPC_HDR_REQ structure.
 ********************************************************************/
-BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
-{
-       if (hdr == NULL) return False;
 
+void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
+{
        hdr->alloc_hint   = alloc_hint; /* allocation hint */
        hdr->context_id   = 0;         /* presentation context identifier */
        hdr->opnum        = opnum;     /* opnum */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_REQ structure.
+ Reads or writes an RPC_HDR_REQ structure.
 ********************************************************************/
-BOOL smb_io_rpc_hdr_req(char *desc,  RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
+
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_req");
        depth++;
 
-       prs_uint32("alloc_hint", ps, depth, &(rpc->alloc_hint));
-       prs_uint16("context_id", ps, depth, &(rpc->context_id));
-       prs_uint16("opnum     ", ps, depth, &(rpc->opnum));
-
+       if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
+               return False;
+       if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
+               return False;
+       if(!prs_uint16("opnum     ", ps, depth, &rpc->opnum))
+               return False;
        return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_RESP structure.
+ Reads or writes an RPC_HDR_RESP structure.
 ********************************************************************/
-BOOL smb_io_rpc_hdr_resp(char *desc,  RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
+
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
 {
-       if (rpc == NULL) return False;
+       if (rpc == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_resp");
        depth++;
 
-       prs_uint32("alloc_hint", ps, depth, &(rpc->alloc_hint));
-       prs_uint16("context_id", ps, depth, &(rpc->context_id));
-       prs_uint8 ("cancel_ct ", ps, depth, &(rpc->cancel_count));
-       prs_uint8 ("reserved  ", ps, depth, &(rpc->reserved));
-
+       if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
+               return False;
+       if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
+               return False;
+       if(!prs_uint8 ("cancel_ct ", ps, depth, &rpc->cancel_count))
+               return False;
+       if(!prs_uint8 ("reserved  ", ps, depth, &rpc->reserved))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates an RPC_HDR_AUTHA structure.
+ Init an RPC_HDR_AUTHA structure.
 ********************************************************************/
-BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+
+void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
                                uint16 max_tsize, uint16 max_rsize,
                                uint8 auth_type, uint8 auth_level,
                                uint8 stub_type_len)
 {
-       if (rai == NULL) return False;
-
        rai->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
        rai->max_rsize = max_rsize; /* max receive fragment size (0x1630) */   
 
@@ -536,194 +512,228 @@ BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
        rai->padding       = 0; /* padding 0x00 */
 
        rai->unknown       = 0x0014a0c0; /* non-zero pointer to something */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_AUTHA structure.
+ Reads or writes an RPC_HDR_AUTHA structure.
 ********************************************************************/
+
 BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth)
 {
-       if (rai == NULL) return False;
+       if (rai == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_autha");
        depth++;
 
-       prs_uint16("max_tsize    ", ps, depth, &(rai->max_tsize));
-       prs_uint16("max_rsize    ", ps, depth, &(rai->max_rsize));
+       if(!prs_uint16("max_tsize    ", ps, depth, &rai->max_tsize))
+               return False;
+       if(!prs_uint16("max_rsize    ", ps, depth, &rai->max_rsize))
+               return False;
 
-       prs_uint8 ("auth_type    ", ps, depth, &(rai->auth_type    )); /* 0x0a nt lm ssp */
-       prs_uint8 ("auth_level   ", ps, depth, &(rai->auth_level   ));/* 0x06 */
-       prs_uint8 ("stub_type_len", ps, depth, &(rai->stub_type_len));
-       prs_uint8 ("padding      ", ps, depth, &(rai->padding      ));
+       if(!prs_uint8 ("auth_type    ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
+               return False;
+       if(!prs_uint8 ("auth_level   ", ps, depth, &rai->auth_level)) /* 0x06 */
+               return False;
+       if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
+               return False;
+       if(!prs_uint8 ("padding      ", ps, depth, &rai->padding))
+               return False;
 
-       prs_uint32("unknown      ", ps, depth, &(rai->unknown      )); /* 0x0014a0c0 */
+       if(!prs_uint32("unknown      ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-checks an RPC_HDR_AUTH structure.
+ Checks an RPC_HDR_AUTH structure.
 ********************************************************************/
+
 BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai)
 {
-       return ((rai->auth_type == 0x0a || rai->auth_type == 0x44) &&
-                rai->auth_level == 0x06);
-
-       return True;
+       return (rai->auth_type == NTLMSSP_AUTH_TYPE && rai->auth_level == NTLMSSP_AUTH_LEVEL);
 }
 
 /*******************************************************************
-creates an RPC_HDR_AUTH structure.
+ Inits an RPC_HDR_AUTH structure.
 ********************************************************************/
-BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+
+void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
                                uint8 auth_type, uint8 auth_level,
                                uint8 stub_type_len,
                                uint32 ptr)
 {
-       if (rai == NULL) return False;
-
        rai->auth_type     = auth_type; /* nt lm ssp 0x0a */
        rai->auth_level    = auth_level; /* 0x06 */
        rai->stub_type_len = stub_type_len; /* 0x00 */
        rai->padding       = 0; /* padding 0x00 */
 
        rai->unknown       = ptr; /* non-zero pointer to something */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_HDR_AUTH structure.
+ Reads or writes an RPC_HDR_AUTH structure.
 ********************************************************************/
+
 BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth)
 {
-       if (rai == NULL) return False;
+       if (rai == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_hdr_auth");
        depth++;
 
-       prs_uint8 ("auth_type    ", ps, depth, &(rai->auth_type    )); /* 0x0a nt lm ssp */
-       prs_uint8 ("auth_level   ", ps, depth, &(rai->auth_level   ));/* 0x06 */
-       prs_uint8 ("stub_type_len", ps, depth, &(rai->stub_type_len));
-       prs_uint8 ("padding      ", ps, depth, &(rai->padding      ));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint8 ("auth_type    ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
+               return False;
+       if(!prs_uint8 ("auth_level   ", ps, depth, &rai->auth_level)) /* 0x06 */
+               return False;
+       if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
+               return False;
+       if(!prs_uint8 ("padding      ", ps, depth, &rai->padding))
+               return False;
 
-       prs_uint32("unknown      ", ps, depth, &(rai->unknown      )); /* 0x0014a0c0 */
+       if(!prs_uint32("unknown      ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-checks an RPC_AUTH_NTLMSSP_VERIFIER structure.
+ Checks an RPC_AUTH_VERIFIER structure.
 ********************************************************************/
-BOOL rpc_auth_ntlmssp_verifier_chk(RPC_AUTH_NTLMSSP_VERIFIER *rav,
+
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
                                char *signature, uint32 msg_type)
 {
        return (strequal(rav->signature, signature) && rav->msg_type == msg_type);
-
-       return True;
 }
 
 /*******************************************************************
-creates an RPC_AUTH_NTLMSSP_VERIFIER structure.
+ Inits an RPC_AUTH_VERIFIER structure.
 ********************************************************************/
-BOOL make_rpc_auth_ntlmssp_verifier(RPC_AUTH_NTLMSSP_VERIFIER *rav,
+
+void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
                                char *signature, uint32 msg_type)
 {
-       if (rav == NULL) return False;
-
        fstrcpy(rav->signature, signature); /* "NTLMSSP" */
        rav->msg_type = msg_type; /* NTLMSSP_MESSAGE_TYPE */
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_AUTH_NTLMSSP_VERIFIER structure.
+ Reads or writes an RPC_AUTH_VERIFIER structure.
 ********************************************************************/
-BOOL smb_io_rpc_auth_ntlmssp_verifier(char *desc, RPC_AUTH_NTLMSSP_VERIFIER *rav, prs_struct *ps, int depth)
+
+BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
 {
-       if (rav == NULL) return False;
+       if (rav == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
        depth++;
 
-       prs_string("signature", ps, depth, rav->signature, 0, sizeof(rav->signature)); /* "NTLMSSP" */
-       prs_uint32("msg_type ", ps, depth, &(rav->msg_type  )); /* NTLMSSP_MESSAGE_TYPE */
+       /* "NTLMSSP" */
+       if(!prs_string("signature", ps, depth, rav->signature, strlen("NTLMSSP"),
+                       sizeof(rav->signature)))
+               return False;
+       if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type)) /* NTLMSSP_MESSAGE_TYPE */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates an RPC_AUTH_NTLMSSP_NEG structure.
+ Inits an RPC_AUTH_NTLMSSP_NEG structure.
 ********************************************************************/
-BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+
+void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
                                uint32 neg_flgs,
                                fstring myname, fstring domain)
 {
        int len_myname = strlen(myname);
        int len_domain = strlen(domain);
 
-       if (neg == NULL) return False;
-
        neg->neg_flgs = neg_flgs ; /* 0x00b2b3 */
 
-       make_str_hdr(&neg->hdr_domain, len_domain, len_domain, 0x20 + len_myname); 
-       make_str_hdr(&neg->hdr_myname, len_myname, len_myname, 0x20); 
+       init_str_hdr(&neg->hdr_domain, len_domain, len_domain, 0x20 + len_myname); 
+       init_str_hdr(&neg->hdr_myname, len_myname, len_myname, 0x20); 
 
        fstrcpy(neg->myname, myname);
        fstrcpy(neg->domain, domain);
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
-
-*** lkclXXXX HACK ALERT! ***
+ Reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
 
+ *** lkclXXXX HACK ALERT! ***
 ********************************************************************/
+
 BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_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_ntlmssp_neg");
        depth++;
 
-       prs_uint32("neg_flgs ", ps, depth, &(neg->neg_flgs));
+       if(!prs_uint32("neg_flgs ", ps, depth, &neg->neg_flgs))
+               return False;
 
-       if (ps->io)
-       {
+       if (ps->io) {
                uint32 old_offset;
+               uint32 old_neg_flags = neg->neg_flgs;
 
                /* reading */
 
                ZERO_STRUCTP(neg);
 
-               smb_io_strhdr("hdr_domain", &(neg->hdr_domain), ps, depth); 
-               smb_io_strhdr("hdr_myname", &(neg->hdr_myname), ps, depth); 
+               neg->neg_flgs = old_neg_flags;
+
+               if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
+                       return False;
+
+               old_offset = prs_offset(ps);
 
-               old_offset = ps->offset;
+               /* lkclXXXX HACK! */
+               if(!prs_set_offset(ps, neg->hdr_myname.buffer + 0x50))
+                       return False;
 
-               ps->offset = neg->hdr_myname  .buffer + 0x50; /* lkclXXXX HACK! */
-               prs_uint8s(True , "myname", ps, depth, (uint8*)neg->myname  , MIN(neg->hdr_myname  .str_str_len, sizeof(neg->myname  ))); 
-               old_offset += neg->hdr_myname  .str_str_len;
+               if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname, 
+                               MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
+                       return False;
+
+               old_offset += neg->hdr_myname.str_str_len;
+
+               /* lkclXXXX HACK! */
+               if(!prs_set_offset(ps, neg->hdr_domain.buffer + 0x50))
+                       return False;
+
+               if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain, 
+                       MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain  ))))
+                       return False;
 
-               ps->offset = neg->hdr_domain  .buffer + 0x50; /* lkclXXXX HACK! */
-               prs_uint8s(True , "domain", ps, depth, (uint8*)neg->domain  , MIN(neg->hdr_domain  .str_str_len, sizeof(neg->domain  ))); 
                old_offset += neg->hdr_domain  .str_str_len;
 
-               ps->offset = old_offset;
-       }
-       else
-       {
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
+       } else {
                /* writing */
-               smb_io_strhdr("hdr_domain", &(neg->hdr_domain), ps, depth); 
-               smb_io_strhdr("hdr_myname", &(neg->hdr_myname), ps, depth); 
-
-               prs_uint8s(True , "myname", ps, depth, (uint8*)neg->myname  , MIN(neg->hdr_myname  .str_str_len, sizeof(neg->myname  ))); 
-               prs_uint8s(True , "domain", ps, depth, (uint8*)neg->domain  , MIN(neg->hdr_domain  .str_str_len, sizeof(neg->domain  ))); 
+               if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
+                       return False;
+
+               if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname, 
+                                       MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
+                       return False;
+               if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain, 
+                                       MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain  ))))
+                       return False;
        }
 
        return True;
@@ -732,76 +742,72 @@ BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_stru
 /*******************************************************************
 creates an RPC_AUTH_NTLMSSP_CHAL structure.
 ********************************************************************/
-BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+
+void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
                                uint32 neg_flags,
                                uint8 challenge[8])
 {
-       if (chl == NULL) return False;
-
        chl->unknown_1 = 0x0; 
        chl->unknown_2 = 0x00000028;
        chl->neg_flags = neg_flags; /* 0x0082b1 */
 
        memcpy(chl->challenge, challenge, sizeof(chl->challenge)); 
-       bzero (chl->reserved ,            sizeof(chl->reserved)); 
-
-       return True;
+       memset((char *)chl->reserved , '\0', sizeof(chl->reserved)); 
 }
 
 /*******************************************************************
-reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
+ Reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
 ********************************************************************/
+
 BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth)
 {
-       if (chl == NULL) return False;
+       if (chl == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chal");
        depth++;
 
-       prs_uint32("unknown_1", ps, depth, &(chl->unknown_1)); /* 0x0000 0000 */
-       prs_uint32("unknown_2", ps, depth, &(chl->unknown_2)); /* 0x0000 b2b3 */
-       prs_uint32("neg_flags", ps, depth, &(chl->neg_flags)); /* 0x0000 82b1 */
+       if(!prs_uint32("unknown_1", ps, depth, &chl->unknown_1)) /* 0x0000 0000 */
+               return False;
+       if(!prs_uint32("unknown_2", ps, depth, &chl->unknown_2)) /* 0x0000 b2b3 */
+               return False;
+       if(!prs_uint32("neg_flags", ps, depth, &chl->neg_flags)) /* 0x0000 82b1 */
+               return False;
 
-       prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge));
-       prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved ));
+       if(!prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge)))
+               return False;
+       if(!prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved )))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-creates an RPC_AUTH_NTLMSSP_RESP structure.
-
-*** lkclXXXX FUDGE!  HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
-*** lkclXXXX the actual offset is at the start of the auth verifier    ***
+ Inits an RPC_AUTH_NTLMSSP_RESP structure.
 
+ *** lkclXXXX FUDGE!  HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+ *** lkclXXXX the actual offset is at the start of the auth verifier    ***
 ********************************************************************/
-BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
-                               uchar lm_resp[24],
-                               uchar *nt_resp, size_t nt_len,
+
+void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+                               uchar lm_resp[24], uchar nt_resp[24],
                                char *domain, char *user, char *wks,
                                uint32 neg_flags)
 {
        uint32 offset;
        int dom_len = strlen(domain);
-       int wks_len = strlen(wks   );
-       int usr_len = strlen(user  );
-       int lm_len  = nt_len != 0 ? (lm_resp != NULL ? 24 : 0) : 1;
+       int wks_len = strlen(wks);
+       int usr_len = strlen(user);
+       int lm_len  = (lm_resp != NULL) ? 24 : 0;
+       int nt_len  = (nt_resp != NULL) ? 24 : 0;
 
        DEBUG(5,("make_rpc_auth_ntlmssp_resp\n"));
 
-       if (rsp == NULL) return False;
-
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("lm_resp\n"));
-       if (lm_resp != NULL)
-       {
-               dump_data(100, lm_resp, lm_len);
-       }
+       dump_data(100, (char *)lm_resp, 24);
        DEBUG(100,("nt_resp\n"));
-       if (nt_resp != NULL)
-       {
-               dump_data(100, nt_resp, nt_len);
-       }
+       dump_data(100, (char *)nt_resp, 24);
 #endif
 
        DEBUG(6,("dom: %s user: %s wks: %s neg_flgs: 0x%x\n",
@@ -816,153 +822,190 @@ BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
                usr_len *= 2;
        }
 
-       make_str_hdr(&rsp->hdr_domain , dom_len, dom_len, offset);
+       init_str_hdr(&rsp->hdr_domain, dom_len, dom_len, offset);
        offset += dom_len;
 
-       make_str_hdr(&rsp->hdr_usr    , usr_len, usr_len, offset);
+       init_str_hdr(&rsp->hdr_usr, usr_len, usr_len, offset);
        offset += usr_len;
 
-       make_str_hdr(&rsp->hdr_wks    , wks_len, wks_len, offset);
+       init_str_hdr(&rsp->hdr_wks, wks_len, wks_len, offset);
        offset += wks_len;
 
-       make_str_hdr(&rsp->hdr_lm_resp, lm_len , lm_len , offset);
+       init_str_hdr(&rsp->hdr_lm_resp, lm_len, lm_len, offset);
        offset += lm_len;
 
-       make_str_hdr(&rsp->hdr_nt_resp, nt_len , nt_len , offset);
+       init_str_hdr(&rsp->hdr_nt_resp, nt_len, nt_len, offset);
        offset += nt_len;
 
-       make_str_hdr(&rsp->hdr_sess_key, 0, 0, offset);
+       init_str_hdr(&rsp->hdr_sess_key, 0, 0, offset);
 
        rsp->neg_flags = neg_flags;
 
-       if (lm_resp != NULL && lm_len != 1)
-       {
-               memcpy(rsp->lm_resp, lm_resp, lm_len);
-       }
-       else
-       {
-               rsp->lm_resp[0] = 0;
-       }
-       if (nt_resp != NULL)
-       {
-               memcpy(rsp->nt_resp, nt_resp, nt_len);
-       }
-       else
-       {
-               rsp->nt_resp[0] = 0;
-       }
+       memcpy(rsp->lm_resp, lm_resp, 24);
+       memcpy(rsp->nt_resp, nt_resp, 24);
 
-       if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
-       {
-               ascii_to_unibuf(rsp->domain, domain, sizeof(rsp->domain)-2);
-               ascii_to_unibuf(rsp->user  , user  , sizeof(rsp->user  )-2);
-               ascii_to_unibuf(rsp->wks   , wks   , sizeof(rsp->wks   )-2);
-       }
-       else
-       {
+       if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
+               dos_struni2(rsp->domain, domain, sizeof(rsp->domain));
+               dos_struni2(rsp->user, user, sizeof(rsp->user));
+               dos_struni2(rsp->wks, wks, sizeof(rsp->wks));
+       } else {
                fstrcpy(rsp->domain, domain);
-               fstrcpy(rsp->user  , user  );
-               fstrcpy(rsp->wks   , wks   );
+               fstrcpy(rsp->user, user);
+               fstrcpy(rsp->wks, wks);
        }
        rsp->sess_key[0] = 0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
-
-*** lkclXXXX FUDGE!  HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
-*** lkclXXXX the actual offset is at the start of the auth verifier    ***
+ Reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
 
+ *** lkclXXXX FUDGE!  HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+ *** lkclXXXX the actual offset is at the start of the auth verifier    ***
 ********************************************************************/
+
 BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_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_ntlmssp_resp");
        depth++;
 
-       if (ps->io)
-       {
+       if (ps->io) {
                uint32 old_offset;
 
                /* reading */
 
                ZERO_STRUCTP(rsp);
 
-               smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp , ps, depth); 
-               smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp , ps, depth); 
-               smb_io_strhdr("hdr_domain  ", &rsp->hdr_domain  , ps, depth); 
-               smb_io_strhdr("hdr_user    ", &rsp->hdr_usr     , ps, depth); 
-               smb_io_strhdr("hdr_wks     ", &rsp->hdr_wks     , ps, depth); 
-               smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth); 
+               if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_domain  ", &rsp->hdr_domain, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_user    ", &rsp->hdr_usr, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_wks     ", &rsp->hdr_wks, ps, depth)) 
+                       return False;
+               if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
+                       return False;
+
+               if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
+                       return False;
+
+               old_offset = prs_offset(ps);
 
-               prs_uint32("neg_flags", ps, depth, &(rsp->neg_flags)); /* 0x0000 82b1 */
+               if(!prs_set_offset(ps, rsp->hdr_domain.buffer + 0x1c))
+                       return False;
 
-               old_offset = ps->offset;
+               if(!prs_uint8s(True , "domain  ", ps, depth, (uint8*)rsp->domain,
+                               MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
+                       return False;
 
-               ps->offset = rsp->hdr_domain  .buffer + 0x1c;
-               prs_uint8s(True , "domain  ", ps, depth, (uint8*)rsp->domain  , MIN(rsp->hdr_domain  .str_str_len, sizeof(rsp->domain  ))); 
-               old_offset += rsp->hdr_domain  .str_str_len;
+               old_offset += rsp->hdr_domain.str_str_len;
 
-               ps->offset = rsp->hdr_usr     .buffer + 0x1c;
-               prs_uint8s(True , "user    ", ps, depth, (uint8*)rsp->user    , MIN(rsp->hdr_usr     .str_str_len, sizeof(rsp->user    ))); 
-               old_offset += rsp->hdr_usr     .str_str_len;
+               if(!prs_set_offset(ps, rsp->hdr_usr.buffer + 0x1c))
+                       return False;
 
-               ps->offset = rsp->hdr_wks     .buffer + 0x1c;
-               prs_uint8s(True , "wks     ", ps, depth, (uint8*)rsp->wks     , MIN(rsp->hdr_wks     .str_str_len, sizeof(rsp->wks     ))); 
-               old_offset += rsp->hdr_wks     .str_str_len;
+               if(!prs_uint8s(True , "user    ", ps, depth, (uint8*)rsp->user,
+                               MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
+                       return False;
 
-               ps->offset = rsp->hdr_lm_resp .buffer + 0x1c;
-               prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp , MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp ))); 
-               old_offset += rsp->hdr_lm_resp .str_str_len;
+               old_offset += rsp->hdr_usr.str_str_len;
 
-               ps->offset = rsp->hdr_nt_resp .buffer + 0x1c;
-               prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp , MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp ))); 
-               old_offset += rsp->hdr_nt_resp .str_str_len;
+               if(!prs_set_offset(ps, rsp->hdr_wks.buffer + 0x1c))
+                       return False;
+
+               if(!prs_uint8s(True, "wks     ", ps, depth, (uint8*)rsp->wks,
+                               MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
+                       return False;
+
+               old_offset += rsp->hdr_wks.str_str_len;
+
+               if(!prs_set_offset(ps, rsp->hdr_lm_resp.buffer + 0x1c))
+                       return False;
+
+               if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
+                               MIN(rsp->hdr_lm_resp.str_str_len, sizeof(rsp->lm_resp ))))
+                       return False;
+
+               old_offset += rsp->hdr_lm_resp.str_str_len;
+
+               if(!prs_set_offset(ps, rsp->hdr_nt_resp.buffer + 0x1c))
+                       return False;
+
+               if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
+                               MIN(rsp->hdr_nt_resp.str_str_len, sizeof(rsp->nt_resp ))))
+                       return False;
+
+               old_offset += rsp->hdr_nt_resp.str_str_len;
+
+               if (rsp->hdr_sess_key.str_str_len != 0) {
+
+                       if(!prs_set_offset(ps, rsp->hdr_sess_key.buffer + 0x1c))
+                               return False;
 
-               if (rsp->hdr_sess_key.str_str_len != 0)
-               {
-                       ps->offset = rsp->hdr_sess_key.buffer + 0x1c;
                        old_offset += rsp->hdr_sess_key.str_str_len;
-                       prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key, MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))); 
+
+                       if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
+                                       MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
+                               return False;
                }
 
-               ps->offset = old_offset;
-       }
-       else
-       {
+               if(!prs_set_offset(ps, old_offset))
+                       return False;
+       } else {
                /* writing */
-               smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp , ps, depth); 
-               smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp , ps, depth); 
-               smb_io_strhdr("hdr_domain  ", &rsp->hdr_domain  , ps, depth); 
-               smb_io_strhdr("hdr_user    ", &rsp->hdr_usr     , ps, depth); 
-               smb_io_strhdr("hdr_wks     ", &rsp->hdr_wks     , ps, depth); 
-               smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth); 
-
-               prs_uint32("neg_flags", ps, depth, &(rsp->neg_flags)); /* 0x0000 82b1 */
-
-               prs_uint8s(True , "domain  ", ps, depth, (uint8*)rsp->domain  , MIN(rsp->hdr_domain  .str_str_len, sizeof(rsp->domain  ))); 
-               prs_uint8s(True , "user    ", ps, depth, (uint8*)rsp->user    , MIN(rsp->hdr_usr     .str_str_len, sizeof(rsp->user    ))); 
-               prs_uint8s(True , "wks     ", ps, depth, (uint8*)rsp->wks     , MIN(rsp->hdr_wks     .str_str_len, sizeof(rsp->wks     ))); 
-               prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp , MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp ))); 
-               prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp , MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp ))); 
-               prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key, MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))); 
+               if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_domain  ", &rsp->hdr_domain, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_user    ", &rsp->hdr_usr, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_wks     ", &rsp->hdr_wks, ps, depth))
+                       return False;
+               if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
+                       return False;
+
+               if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
+                       return False;
+
+               if(!prs_uint8s(True , "domain  ", ps, depth, (uint8*)rsp->domain,
+                               MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
+                       return False;
+
+               if(!prs_uint8s(True , "user    ", ps, depth, (uint8*)rsp->user,
+                               MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
+                       return False;
+
+               if(!prs_uint8s(True , "wks     ", ps, depth, (uint8*)rsp->wks,
+                               MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
+                       return False;
+               if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
+                               MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp))))
+                       return False;
+               if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
+                               MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp ))))
+                       return False;
+               if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
+                               MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-checks an RPC_AUTH_NTLMSSP_CHK structure.
+ Checks an RPC_AUTH_NTLMSSP_CHK structure.
 ********************************************************************/
+
 BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num)
 {
        if (chk == NULL)
-       {
                return False;
-       }
 
        if (chk->crc32 != crc32 ||
            chk->ver   != NTLMSSP_SIGN_VERSION ||
@@ -975,41 +1018,44 @@ BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_nu
                return False;
        }
        return True;
-
-       return True;
 }
 
 /*******************************************************************
-creates an RPC_AUTH_NTLMSSP_CHK structure.
+ Inits an RPC_AUTH_NTLMSSP_CHK structure.
 ********************************************************************/
-BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+
+void init_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
                                uint32 ver, uint32 crc32, uint32 seq_num)
 {
-       if (chk == NULL) return False;
-
-       chk->ver      = ver     ;
+       chk->ver      = ver;
        chk->reserved = 0x0;
-       chk->crc32    = crc32   ;
-       chk->seq_num  = seq_num ;
-
-       return True;
+       chk->crc32    = crc32;
+       chk->seq_num  = seq_num;
 }
 
 /*******************************************************************
-reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
+ Reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
 ********************************************************************/
+
 BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_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_ntlmssp_chk");
        depth++;
 
-       prs_uint32("ver     ", ps, depth, &(chk->ver     )); 
-       prs_uint32("reserved", ps, depth, &(chk->reserved)); 
-       prs_uint32("crc32   ", ps, depth, &(chk->crc32   )); 
-       prs_uint32("seq_num ", ps, depth, &(chk->seq_num )); 
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ver     ", ps, depth, &chk->ver))
+               return False;
+       if(!prs_uint32("reserved", ps, depth, &chk->reserved))
+               return False;
+       if(!prs_uint32("crc32   ", ps, depth, &chk->crc32))
+               return False;
+       if(!prs_uint32("seq_num ", ps, depth, &chk->seq_num))
+               return False;
 
        return True;
 }
-
index cedfbdebd3b5c542be73ec2c45415fb1397b479d..effe329376e958d36691c0bde7bde7d083cc6a3b 100644 (file)
@@ -2,9 +2,9 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
  *  
  *  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
@@ -28,444 +28,314 @@ extern int DEBUGLEVEL;
 
 
 /*******************************************************************
-makes a SAMR_Q_CLOSE_HND structure.
+ Inits a SAMR_Q_CLOSE_HND structure.
 ********************************************************************/
-BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
-{
-       if (q_c == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_close_hnd\n"));
 
-       memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
+{
+       DEBUG(5,("init_samr_q_close_hnd\n"));
 
-       return True;
+       memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_q_close_hnd(char *desc,  SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_close_hnd");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_r_close_hnd(char *desc,  SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_close_hnd");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       int len_name = strlen(dom_name);
-
-       if (q_u == NULL) return False;
+       if(!prs_align(ps))
+               return False;
 
-       DEBUG(5,("make_samr_q_lookup_domain\n"));
+       if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       memcpy(&(q_u->connect_pol), pol, sizeof(*pol));
-
-       make_uni_hdr(&(q_u->hdr_domain), len_name);
-       make_unistr2(&(q_u->uni_domain), dom_name, len_name);
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_lookup_domain");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth);
-       prs_align(ps);
-
-       smb_io_unihdr("hdr_domain", &(q_u->hdr_domain), ps, depth);
-       smb_io_unistr2("uni_domain", &(q_u->uni_domain),
-                      q_u->hdr_domain.buffer, ps, depth);
-       prs_align(ps);
-
-       return True;
-}
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_lookup_domain");
-       depth++;
-
-       prs_align(ps);
 
-       prs_uint32("ptr", ps, depth, &(r_u->ptr_sid));
-
-       if (r_u->ptr_sid != 0)
-       {
-               smb_io_dom_sid2("sid", &(r_u->dom_sid), ps, depth);
-               prs_align(ps);
-       }
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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)
+void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+                               POLICY_HND *connect_pol, uint32 rid,
+                               DOM_SID *sid)
 {
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("samr_make_samr_q_open_domain\n"));
+       DEBUG(5,("samr_init_q_open_domain\n"));
 
        memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
-       q_u->flags = flags;
-       make_dom_sid2(&(q_u->dom_sid), sid);
-
-       return True;
+       q_u->rid = rid;
+       init_dom_sid2(&q_u->dom_sid, sid);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_open_domain(char *desc,  SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_open_domain");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("connect_pol", &q_u->connect_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("flags", ps, depth, &(q_u->flags));
+       if(!prs_uint32("rid", ps, depth, &q_u->rid))
+               return False;
 
-       smb_io_dom_sid2("sid", &(q_u->dom_sid), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_dom_sid2("sid", &q_u->dom_sid, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_open_domain(char *desc,  SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_open_domain");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("domain_pol", &(r_u->domain_pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("domain_pol", &r_u->domain_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol)
-{
-       if (q_u == NULL) return False;
 
-       DEBUG(5,("samr_make_samr_q_unknown_2c\n"));
+void init_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol)
+{
+       DEBUG(5,("samr_init_q_unknown_2c\n"));
 
        memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
-
-       return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_q_unknown_2c(char *desc,  SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_unknown_2c");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status)
-{
-       if (q_u == NULL) return False;
 
-       DEBUG(5,("samr_make_r_unknown_2c\n"));
+void init_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status)
+{
+       DEBUG(5,("samr_init_r_unknown_2c\n"));
 
-       q_u->unknown_0 = 0x00150000;
+       q_u->unknown_0 = 0x00160000;
        q_u->unknown_1 = 0x00000000;
        q_u->status    = status;
-
-       return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_r_unknown_2c(char *desc,  SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_unknown_2c");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
-       prs_uint32("unknown_1", ps, depth, &(r_u->unknown_1));
-       prs_uint32("status   ", ps, depth, &(r_u->status   ));
+       if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
+               return False;
+       if(!prs_uint32("unknown_1", ps, depth, &r_u->unknown_1))
+               return False;
+       if(!prs_uint32("status   ", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_Q_UNKNOWN_3 structure.
 ********************************************************************/
-BOOL make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+
+void init_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
                                POLICY_HND *user_pol, uint16 switch_value)
 {
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("samr_make_samr_q_unknown_3\n"));
+       DEBUG(5,("samr_init_q_unknown_3\n"));
 
        memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
        q_u->switch_value = switch_value;
-
-       return True;
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_q_unknown_3(char *desc,  SAMR_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, "samr_io_q_unknown_3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
+               return False;
 
-       prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_Q_QUERY_DOMAIN_INFO structure.
 ********************************************************************/
-BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+
+void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
                                POLICY_HND *domain_pol, uint16 switch_value)
 {
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("samr_make_samr_q_query_dom_info\n"));
+       DEBUG(5,("init_samr_q_query_dom_info\n"));
 
        memcpy(&q_u->domain_pol, domain_pol, sizeof(q_u->domain_pol));
        q_u->switch_value = switch_value;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_query_dom_info");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a structure.
-********************************************************************/
-BOOL make_unk_info3(SAM_UNK_INFO_3 *u_3)
-{
-       if (u_3 == NULL) return False;
-
-       u_3->unknown_0 = 0x00000000;
-       u_3->unknown_1 = 0x80000000;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 *u_3, prs_struct *ps, int depth)
-{
-       if (u_3 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_unk_info3");
-       depth++;
-
-       prs_uint32("unknown_0", ps, depth, &u_3->unknown_0); /* 0x0000 0000 */
-       prs_uint32("unknown_1", ps, depth, &u_3->unknown_1); /* 0x8000 0000 */
-
-       prs_align(ps);
-
-
-       return True;
-}
-
-/*******************************************************************
-makes a structure.
-********************************************************************/
-BOOL make_unk_info6(SAM_UNK_INFO_6 *u_6)
-{
-       if (u_6 == NULL) return False;
-
-       u_6->unknown_0 = 0x00000000;
-       u_6->ptr_0 = 1;
-       memset(u_6->padding, 0, sizeof(u_6->padding)); /* 12 bytes zeros */
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 *u_6, prs_struct *ps, int depth)
-{
-       if (u_6 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_unk_info6");
-       depth++;
-
-       prs_uint32("unknown_0", ps, depth, &u_6->unknown_0); /* 0x0000 0000 */
-       prs_uint32("ptr_0", ps, depth, &u_6->ptr_0);     /* pointer to unknown structure */
-       prs_uint8s(False, "padding", ps, depth, u_6->padding, sizeof(u_6->padding)); /* 12 bytes zeros */
-
-       prs_align(ps);
-
+       if(!prs_align(ps))
+               return False;
 
-       return True;
-}
+       if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-/*******************************************************************
-makes a structure.
-********************************************************************/
-BOOL make_unk_info7(SAM_UNK_INFO_7 *u_7)
-{
-       if (u_7 == NULL) return False;
+       if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       u_7->unknown_0 = 0x0003;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a structure.
 ********************************************************************/
-BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth)
-{
-       if (u_7 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_unk_info7");
-       depth++;
 
-       prs_uint16("unknown_0", ps, depth, &u_7->unknown_0); /* 0x0003 */
-       prs_align(ps);
-
-
-       return True;
-}
-
-/*******************************************************************
-makes a structure.
-********************************************************************/
-BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
+void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
 {
        int len_domain = strlen(domain);
        int len_server = strlen(server);
 
-       if (u_2 == NULL) return False;
-
        u_2->unknown_0 = 0x00000000;
        u_2->unknown_1 = 0x80000000;
        u_2->unknown_2 = 0x00000000;
 
        u_2->ptr_0 = 1;
-       make_uni_hdr(&(u_2->hdr_domain), len_domain);
-       make_uni_hdr(&(u_2->hdr_server), len_server);
+       init_uni_hdr(&u_2->hdr_domain, len_domain);
+       init_uni_hdr(&u_2->hdr_server, len_server);
 
        u_2->seq_num = 0x10000000;
        u_2->unknown_3 = 0x00000000;
@@ -473,221 +343,177 @@ BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
        u_2->unknown_4  = 0x00000001;
        u_2->unknown_5  = 0x00000003;
        u_2->unknown_6  = 0x00000001;
-       u_2->num_domain_usrs  = MAX_SAM_ENTRIES;
-       u_2->num_domain_grps = MAX_SAM_ENTRIES;
-       u_2->num_local_grps = MAX_SAM_ENTRIES;
+       u_2->num_domain_usrs  = 0x00000008;
+       u_2->num_domain_grps = 0x00000003;
+       u_2->num_local_grps = 0x00000003;
 
        memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
 
-       make_unistr2(&u_2->uni_domain, domain, len_domain);
-       make_unistr2(&u_2->uni_server, server, len_server);
-
-       return True;
+       init_unistr2(&u_2->uni_domain, domain, len_domain);
+       init_unistr2(&u_2->uni_server, server, len_server);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth)
 {
-       if (u_2 == NULL) return False;
+       if (u_2 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_unk_info2");
        depth++;
 
-       prs_uint32("unknown_0", ps, depth, &u_2->unknown_0); /* 0x0000 0000 */
-       prs_uint32("unknown_1", ps, depth, &u_2->unknown_1); /* 0x8000 0000 */
-       prs_uint32("unknown_2", ps, depth, &u_2->unknown_2); /* 0x0000 0000 */
+       if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
+               return False;
+       if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
+               return False;
+       if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2)) /* 0x0000 0000 */
+               return False;
 
-       prs_uint32("ptr_0", ps, depth, &u_2->ptr_0);     /* pointer to unknown structure */
-       smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth); /* domain name unicode header */
-       smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth); /* server name unicode header */
+       if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0))     /* pointer to unknown structure */
+               return False;
+       if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth)) /* domain name unicode header */
+               return False;
+       if(!smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth)) /* server name unicode header */
+               return False;
 
        /* put all the data in here, at the moment, including what the above
           pointer is referring to
         */
 
-       prs_uint32("seq_num ", ps, depth, &u_2->seq_num ); /* 0x0000 0099 or 0x1000 0000 */
-       prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 ); /* 0x0000 0000 */
+       if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num )) /* 0x0000 0099 or 0x1000 0000 */
+               return False;
+       if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 )) /* 0x0000 0000 */
+               return False;
        
-       prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 ); /* 0x0000 0001 */
-       prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 ); /* 0x0000 0003 */
-       prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 ); /* 0x0000 0001 */
-       prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs ); /* 0x0000 0008 */
-       prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps); /* 0x0000 0003 */
-       prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps); /* 0x0000 0003 */
-
-       prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding)); /* 12 bytes zeros */
-
-       smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth); /* domain name unicode string */
-       prs_align(ps);
-       smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth); /* server name unicode string */
-
-       prs_align(ps);
-
+       if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 )) /* 0x0000 0001 */
+               return False;
+       if(!prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 )) /* 0x0000 0003 */
+               return False;
+       if(!prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 )) /* 0x0000 0001 */
+               return False;
+       if(!prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs )) /* 0x0000 0008 */
+               return False;
+       if(!prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps)) /* 0x0000 0003 */
+               return False;
+       if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps)) /* 0x0000 0003 */
+               return False;
 
-       return True;
-}
+       if(!prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding))) /* 12 bytes zeros */
+               return False;
 
-/*******************************************************************
-makes a structure.
-********************************************************************/
-BOOL make_unk_info1(SAM_UNK_INFO_1 *u_1)
-{
-       if (u_1 == NULL) return False;
+       if(!smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth)) /* domain name unicode string */
+               return False;
+       if(!smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth)) /* server name unicode string */
+               return False;
 
-       memset(u_1->padding, 0, sizeof(u_1->padding)); /* 12 bytes zeros */
-       u_1->unknown_1 = 0x80000000;
-       u_1->unknown_2 = 0x00000000;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_R_QUERY_DOMAIN_INFO structure.
 ********************************************************************/
-BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth)
-{
-       if (u_1 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_unk_info1");
-       depth++;
-
-       prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)); /* 12 bytes zeros */
-
-       prs_uint32("unknown_1", ps, depth, &u_1->unknown_1); /* 0x8000 0000 */
-       prs_uint32("unknown_2", ps, depth, &u_1->unknown_2); /* 0x0000 0000 */
-
-       prs_align(ps);
-
-       return True;
-}
 
-/*******************************************************************
-makes a SAMR_R_QUERY_DOMAIN_INFO structure.
-********************************************************************/
-BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u, 
+void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u, 
                                uint16 switch_value, SAM_UNK_CTR *ctr,
                                uint32 status)
 {
-       if (r_u == NULL || ctr == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_dom_info\n"));
+       DEBUG(5,("init_samr_r_query_dom_info\n"));
 
        r_u->ptr_0 = 0;
        r_u->switch_value = 0;
        r_u->status = status; /* return status */
 
-       if (status == 0)
-       {
+       if (status == 0) {
                r_u->switch_value = switch_value;
                r_u->ptr_0 = 1;
                r_u->ctr = ctr;
        }
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_query_dom_info");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("ptr_0       ", ps, depth, &(r_u->ptr_0));
+       if(!prs_align(ps))
+               return False;
 
-       if (r_u->ptr_0 != 0 && r_u->ctr != NULL)
-       {
-               prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
-               prs_align(ps);
+       if(!prs_uint32("ptr_0       ", ps, depth, &r_u->ptr_0))
+               return False;
+       if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-               switch (r_u->switch_value)
-               {
-                       case 0x07:
-                       {
-                               sam_io_unk_info7("unk_inf7", &r_u->ctr->info.inf7, ps, depth);
-                               break;
-                       }
-                       case 0x06:
-                       {
-                               sam_io_unk_info6("unk_inf6", &r_u->ctr->info.inf6, ps, depth);
-                               break;
-                       }
-                       case 0x03:
-                       {
-                               sam_io_unk_info3("unk_inf3", &r_u->ctr->info.inf3, ps, depth);
-                               break;
-                       }
-                       case 0x02:
-                       {
-                               sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth);
-                               break;
-                       }
-                       case 0x01:
-                       {
-                               sam_io_unk_info1("unk_inf1", &r_u->ctr->info.inf1, ps, depth);
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
-                                         r_u->switch_value));
-                               r_u->status = 0xC0000000|NT_STATUS_INVALID_INFO_CLASS;
+       if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
+               switch (r_u->switch_value) {
+               case 0x02:
+                       if(!sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth))
                                return False;
-                       }
+                       break;
+               default:
+                       DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
+                                 r_u->switch_value));
+                       return False;
                }
        }
 
-       prs_uint32("status      ", ps, depth, &(r_u->status));
-
        return True;
 }
 
 
 /*******************************************************************
- makes a DOM_SID3 structure.
-
- calculate length by adding up the size of the components.
+ Inits a DOM_SID3 structure.
+ Calculate length by adding up the size of the components.
  ********************************************************************/
-BOOL make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
-{
-       if (sid3 == NULL) return False;
 
-    sid3->sid = *sid;
+void init_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
+{
+       sid3->sid = *sid;
        sid3->len = 2 + 8 + sid3->sid.num_auths * 4;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_SID3 structure.
+ Reads or writes a SAM_SID3 structure.
 
-this one's odd, because the length (in bytes) is specified at the beginning.
-the length _includes_ the length of the length, too :-)
+ this one's odd, because the length (in bytes) is specified at the beginning.
+ the length _includes_ the length of the length, too :-)
 
 ********************************************************************/
+
 static BOOL sam_io_dom_sid3(char *desc,  DOM_SID3 *sid3, prs_struct *ps, int depth)
 {
-       if (sid3 == NULL) return False;
+       if (sid3 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_dom_sid3");
        depth++;
 
-       prs_uint16("len", ps, depth, &(sid3->len));
-       prs_align(ps);
-       smb_io_dom_sid("", &(sid3->sid), ps, depth); 
+       if(!prs_uint16("len", ps, depth, &sid3->len))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!smb_io_dom_sid("", &sid3->sid, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_UNKNOWN3 structure.
+ Inits a SAMR_R_UNKNOWN3 structure.
 
 unknown_2   : 0x0001
 unknown_3   : 0x8004
@@ -698,7 +524,8 @@ unknown_6   : 0x0002
 unknown_7   : 0x5800 or 0x0070
 
 ********************************************************************/
-static BOOL make_sam_sid_stuff(SAM_SID_STUFF *stf,
+
+static void init_sam_sid_stuff(SAM_SID_STUFF *stf,
                                uint16 unknown_2, uint16 unknown_3,
                                uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
                                int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS])
@@ -706,7 +533,7 @@ static BOOL make_sam_sid_stuff(SAM_SID_STUFF *stf,
        stf->unknown_2 = unknown_2;
        stf->unknown_3 = unknown_3;
 
-       bzero(stf->padding1, sizeof(stf->padding1));
+       memset((char *)stf->padding1, '\0', sizeof(stf->padding1));
 
        stf->unknown_4 = unknown_4;
        stf->unknown_5 = unknown_4;
@@ -719,77 +546,81 @@ static BOOL make_sam_sid_stuff(SAM_SID_STUFF *stf,
        stf->padding2  = 0x0000;
 
        memcpy(stf->sid, sid3, sizeof(DOM_SID3) * num_sid3s);
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_SID_STUFF structure.
+ Reads or writes a SAM_SID_STUFF structure.
 ********************************************************************/
+
 static BOOL sam_io_sid_stuff(char *desc,  SAM_SID_STUFF *stf, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (stf == NULL) return False;
+       if (stf == NULL)
+               return False;
 
-       DEBUG(5,("make_sam_sid_stuff\n"));
+       DEBUG(5,("init_sam_sid_stuff\n"));
 
-       prs_uint16("unknown_2", ps, depth, &(stf->unknown_2));
-       prs_uint16("unknown_3", ps, depth, &(stf->unknown_3));
+       if(!prs_uint16("unknown_2", ps, depth, &stf->unknown_2))
+               return False;
+       if(!prs_uint16("unknown_3", ps, depth, &stf->unknown_3))
+               return False;
 
-       prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1)); 
+       if(!prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1)))
+               return False;
        
-       prs_uint32("unknown_4", ps, depth, &(stf->unknown_4));
-       prs_uint32("unknown_5", ps, depth, &(stf->unknown_5));
-       prs_uint16("unknown_6", ps, depth, &(stf->unknown_6));
-       prs_uint16("unknown_7", ps, depth, &(stf->unknown_7));
-
-       prs_uint32("num_sids ", ps, depth, &(stf->num_sids ));
-       prs_uint16("padding2 ", ps, depth, &(stf->padding2 ));
+       if(!prs_uint32("unknown_4", ps, depth, &stf->unknown_4))
+               return False;
+       if(!prs_uint32("unknown_5", ps, depth, &stf->unknown_5))
+               return False;
+       if(!prs_uint16("unknown_6", ps, depth, &stf->unknown_6))
+               return False;
+       if(!prs_uint16("unknown_7", ps, depth, &stf->unknown_7))
+               return False;
+
+       if(!prs_uint32("num_sids ", ps, depth, &stf->num_sids ))
+               return False;
+       if(!prs_uint16("padding2 ", ps, depth, &stf->padding2 ))
+               return False;
 
        SMB_ASSERT_ARRAY(stf->sid, stf->num_sids);
 
-       for (i = 0; i < stf->num_sids; i++)
-       {
-               sam_io_dom_sid3("", &(stf->sid[i]), ps, depth); 
+       for (i = 0; i < stf->num_sids; i++) {
+               if(!sam_io_dom_sid3("", &(stf->sid[i]), ps, depth))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a SAMR_R_UNKNOWN3 structure.
+ Inits or writes a SAMR_R_UNKNOWN3 structure.
 ********************************************************************/
-BOOL make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
+
+void init_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
                                uint16 unknown_2, uint16 unknown_3,
                                uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
                                int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
                                uint32 status)
 {
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("samr_make_r_unknown_3\n"));
+       DEBUG(5,("samr_init_r_unknown_3\n"));
 
        r_u->ptr_0 = 0;
        r_u->ptr_1 = 0;
 
-       if (status == 0x0)
-       {
+       if (status == 0x0) {
                r_u->ptr_0 = 1;
                r_u->ptr_1 = 1;
-               make_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
+               init_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
                       unknown_4, unknown_6, unknown_7,
                       num_sid3s, sid3);
        }
 
        r_u->status = status;
-
-       return True;
 }
 
-
 /*******************************************************************
-reads or writes a SAMR_R_UNKNOWN_3 structure.
+ Reads or writes a SAMR_R_UNKNOWN_3 structure.
 
 this one's odd, because the daft buggers use a different mechanism
 for writing out the array of sids. they put the number of sids in
@@ -800,4493 +631,2108 @@ is put at the beginning of the data stream.
 wierd.  
 
 ********************************************************************/
+
 BOOL samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth)
 {
        int ptr_len0=0;
        int ptr_len1=0;
        int ptr_sid_stuff = 0;
 
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_unknown_3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_0         ", ps, depth, &(r_u->ptr_0         ));
+       if(!prs_uint32("ptr_0         ", ps, depth, &r_u->ptr_0))
+               return False;
 
-       if (ps->io) 
-       {
+       if (ps->io) {
                /* reading.  do the length later */
-               prs_uint32("sid_stuff_len0", ps, depth, &(r_u->sid_stuff_len0));
-       }
-       else
-       {
+               if(!prs_uint32("sid_stuff_len0", ps, depth, &r_u->sid_stuff_len0))
+                       return False;
+       } else {
                /* storing */
-               ptr_len0 = ps->offset; ps->offset += 4;
+               ptr_len0 = prs_offset(ps);
+               if(!prs_set_offset(ps, ptr_len0 + 4))
+                       return False;
        }
 
-       if (r_u->ptr_0 != 0)
-       {
-               prs_uint32("ptr_1         ", ps, depth, &(r_u->ptr_1         ));
-               if (ps->io)
-               {
+       if (r_u->ptr_0 != 0) {
+               if(!prs_uint32("ptr_1         ", ps, depth, &r_u->ptr_1))
+                       return False;
+               if (ps->io) {
                        /* reading.  do the length later */
-                       prs_uint32("sid_stuff_len1", ps, depth, &(r_u->sid_stuff_len1));
-               }
-               else
-               {
+                       if(!prs_uint32("sid_stuff_len1", ps, depth, &r_u->sid_stuff_len1))
+                               return False;
+               } else {
                        /* storing */
-                       ptr_len1 = ps->offset; ps->offset += 4;
+                       ptr_len1 = prs_offset(ps);
+                       if(!prs_set_offset(ps, ptr_len1 + 4))
+                               return False;
                }
 
-               if (r_u->ptr_1 != 0)
-               {
-                       ptr_sid_stuff = ps->offset;
-                       sam_io_sid_stuff("", &(r_u->sid_stuff), ps, depth); 
+               if (r_u->ptr_1 != 0) {
+                       ptr_sid_stuff = prs_offset(ps);
+                       if(!sam_io_sid_stuff("", &r_u->sid_stuff, ps, depth))
+                               return False;
                }
        }
 
-       if (!(ps->io)) /* storing not reading.  do the length, now. */
-       {
-               if (ptr_sid_stuff != 0)
-               {
-                       uint32 sid_stuff_len = ps->offset - ptr_sid_stuff;
-                       int old_len = ps->offset;
+       if (!(ps->io)) {
+               /* storing not reading.  do the length, now. */
 
-                       ps->offset = ptr_len0;
-                       prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len); 
+               if (ptr_sid_stuff != 0) {
+                       int old_len = prs_offset(ps);
+                       uint32 sid_stuff_len = old_len - ptr_sid_stuff;
 
-                       ps->offset = ptr_len1;
-                       prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len);
+                       if(!prs_set_offset(ps, ptr_len0))
+                               return False;
+                       if(!prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len))
+                               return False;
+
+                       if(!prs_set_offset(ps, ptr_len1))
+                               return False;
+                       if(!prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len))
+                               return False;
 
-                       ps->offset = old_len;
+                       if(!prs_set_offset(ps, old_len))
+                               return False;
                }
        }
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_STR1 structure.
+ 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)
+
+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)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_str1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("unistr2", &(sam->uni_acct_name), acct_buf, ps, depth); /* account name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("unistr2", &(sam->uni_full_name), name_buf, ps, depth); /* full name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("unistr2", &(sam->uni_acct_desc), desc_buf, ps, depth); /* account desc unicode string */
-       prs_align(ps);
+       if(!smb_io_unistr2("unistr2", &sam->uni_acct_name, acct_buf, ps, depth)) /* account name unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &sam->uni_full_name, name_buf, ps, depth)) /* full name unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &sam->uni_acct_desc, desc_buf, ps, depth)) /* account description unicode string */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAM_ENTRY1 structure.
+ Inits a SAM_ENTRY1 structure.
 ********************************************************************/
-static BOOL make_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx, 
+
+static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx, 
                                uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
                                uint32 rid_user, uint16 acb_info)
 {
-       if (sam == NULL) return False;
-
-       DEBUG(5,("make_sam_entry1\n"));
+       DEBUG(5,("init_sam_entry1\n"));
 
        sam->user_idx = user_idx;
        sam->rid_user = rid_user;
        sam->acb_info = acb_info;
        sam->pad      = 0;
 
-       make_uni_hdr(&(sam->hdr_acct_name), len_sam_name);
-       make_uni_hdr(&(sam->hdr_user_name), len_sam_full);
-       make_uni_hdr(&(sam->hdr_user_desc), len_sam_desc);
-
-       return True;
+       init_uni_hdr(&sam->hdr_acct_name, len_sam_name);
+       init_uni_hdr(&sam->hdr_user_name, len_sam_full);
+       init_uni_hdr(&sam->hdr_user_desc, len_sam_desc);
 }
 
 /*******************************************************************
-reads or writes a SAM_ENTRY1 structure.
+ Reads or writes a SAM_ENTRY1 structure.
 ********************************************************************/
+
 static BOOL sam_io_sam_entry1(char *desc,  SAM_ENTRY1 *sam, prs_struct *ps, int depth)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_entry1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+       if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
+               return False;
 
-       prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
-       prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
-       prs_uint16("pad      ", ps, depth, &(sam->pad      ));
+       if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
+               return False;
+       if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
+               return False;
+       if(!prs_uint16("pad      ", ps, depth, &sam->pad))
+               return False;
 
-       smb_io_unihdr("unihdr", &(sam->hdr_acct_name), ps, depth); /* account name unicode string header */
-       smb_io_unihdr("unihdr", &(sam->hdr_user_name), ps, depth); /* account name unicode string header */
-       smb_io_unihdr("unihdr", &(sam->hdr_user_desc), ps, depth); /* account name unicode string header */
+       if(!smb_io_unihdr("unihdr", &sam->hdr_acct_name, ps, depth)) /* account name unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &sam->hdr_user_name, ps, depth)) /* account name unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &sam->hdr_user_desc, ps, depth)) /* account name unicode string header */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_STR2 structure.
+ 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)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_str2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("unistr2", &(sam->uni_srv_name), acct_buf, ps, depth); /* account name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("unistr2", &(sam->uni_srv_desc), desc_buf, ps, depth); /* account desc unicode string */
-       prs_align(ps);
+       if(!smb_io_unistr2("unistr2", &sam->uni_srv_name, acct_buf, ps, depth)) /* account name unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &sam->uni_srv_desc, desc_buf, ps, depth)) /* account description unicode string */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAM_ENTRY2 structure.
+ Inits a SAM_ENTRY2 structure.
 ********************************************************************/
-static BOOL make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx, 
+
+static void init_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx, 
                                uint32 len_sam_name, uint32 len_sam_desc,
                                uint32 rid_user, uint16 acb_info)
 {
-       if (sam == NULL) return False;
-
-       DEBUG(5,("make_sam_entry2\n"));
+       DEBUG(5,("init_sam_entry2\n"));
 
        sam->user_idx = user_idx;
        sam->rid_user = rid_user;
        sam->acb_info = acb_info;
        sam->pad      = 0;
 
-       make_uni_hdr(&(sam->hdr_srv_name), len_sam_name);
-       make_uni_hdr(&(sam->hdr_srv_desc), len_sam_desc);
-
-       return True;
+       init_uni_hdr(&sam->hdr_srv_name, len_sam_name);
+       init_uni_hdr(&sam->hdr_srv_desc, len_sam_desc);
 }
 
 /*******************************************************************
-reads or writes a SAM_ENTRY2 structure.
+ Reads or writes a SAM_ENTRY2 structure.
 ********************************************************************/
+
 static BOOL sam_io_sam_entry2(char *desc,  SAM_ENTRY2 *sam, prs_struct *ps, int depth)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_entry2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+       if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
+               return False;
 
-       prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
-       prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
-       prs_uint16("pad      ", ps, depth, &(sam->pad      ));
+       if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
+               return False;
+       if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
+               return False;
+       if(!prs_uint16("pad      ", ps, depth, &sam->pad))
+               return False;
 
-       smb_io_unihdr("unihdr", &(sam->hdr_srv_name), ps, depth); /* account name unicode string header */
-       smb_io_unihdr("unihdr", &(sam->hdr_srv_desc), ps, depth); /* account name unicode string header */
+       if(!smb_io_unihdr("unihdr", &sam->hdr_srv_name, ps, depth)) /* account name unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &sam->hdr_srv_desc, ps, depth)) /* account name unicode string header */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_STR3 structure.
+ 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)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_str3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("unistr2", &(sam->uni_grp_name), acct_buf, ps, depth); /* account name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("unistr2", &(sam->uni_grp_desc), desc_buf, ps, depth); /* account desc unicode string */
-       prs_align(ps);
+       if(!smb_io_unistr2("unistr2", &sam->uni_grp_name, acct_buf, ps, depth)) /* account name unicode string */
+               return False;
+       if(!smb_io_unistr2("unistr2", &sam->uni_grp_desc, desc_buf, ps, depth)) /* account description unicode string */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAM_ENTRY3 structure.
+ Inits a SAM_ENTRY3 structure.
 ********************************************************************/
-static BOOL make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx, 
+
+static void init_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx, 
                                uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
 {
-       if (sam == NULL) return False;
-
-       DEBUG(5,("make_sam_entry3\n"));
+       DEBUG(5,("init_sam_entry3\n"));
 
        sam->grp_idx = grp_idx;
        sam->rid_grp = rid_grp;
        sam->attr    = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
 
-       make_uni_hdr(&(sam->hdr_grp_name), len_grp_name);
-       make_uni_hdr(&(sam->hdr_grp_desc), len_grp_desc);
-
-       return True;
+       init_uni_hdr(&sam->hdr_grp_name, len_grp_name);
+       init_uni_hdr(&sam->hdr_grp_desc, len_grp_desc);
 }
 
 /*******************************************************************
-reads or writes a SAM_ENTRY3 structure.
+ Reads or writes a SAM_ENTRY3 structure.
 ********************************************************************/
+
 static BOOL sam_io_sam_entry3(char *desc,  SAM_ENTRY3 *sam, prs_struct *ps, int depth)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_entry3");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
-
-       prs_uint32("rid_grp", ps, depth, &(sam->rid_grp));
-       prs_uint32("attr   ", ps, depth, &(sam->attr   ));
-
-       smb_io_unihdr("unihdr", &(sam->hdr_grp_name), ps, depth); /* account name unicode string header */
-       smb_io_unihdr("unihdr", &(sam->hdr_grp_desc), ps, depth); /* account name unicode string header */
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAM_ENTRY4 structure.
-********************************************************************/
-static BOOL make_sam_entry4(SAM_ENTRY4 *sam, uint32 user_idx, 
-                               uint32 len_acct_name)
-{
-       if (sam == NULL) return False;
-
-       DEBUG(5,("make_sam_entry4\n"));
-
-       sam->user_idx = user_idx;
-       make_str_hdr(&(sam->hdr_acct_name), len_acct_name, len_acct_name,
-                    len_acct_name != 0);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a SAM_ENTRY4 structure.
-********************************************************************/
-static BOOL sam_io_sam_entry4(char *desc, SAM_ENTRY4 *sam, prs_struct *ps, int depth)
-{
-       if (sam == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_sam_entry4");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("user_idx", ps, depth, &(sam->user_idx));
-       smb_io_strhdr("strhdr", &(sam->hdr_acct_name), ps, depth);
-
-       return True;
-}
+       if(!prs_align(ps))
+               return False;
 
-/*******************************************************************
-makes a SAM_ENTRY5 structure.
-********************************************************************/
-static BOOL make_sam_entry5(SAM_ENTRY5 *sam, uint32 grp_idx, 
-                               uint32 len_grp_name)
-{
-       if (sam == NULL) return False;
+       if(!prs_uint32("grp_idx", ps, depth, &sam->grp_idx))
+               return False;
 
-       DEBUG(5,("make_sam_entry5\n"));
+       if(!prs_uint32("rid_grp", ps, depth, &sam->rid_grp))
+               return False;
+       if(!prs_uint32("attr   ", ps, depth, &sam->attr))
+               return False;
 
-       sam->grp_idx = grp_idx;
-       make_str_hdr(&(sam->hdr_grp_name), len_grp_name, len_grp_name,
-                    len_grp_name != 0);
+       if(!smb_io_unihdr("unihdr", &sam->hdr_grp_name, ps, depth)) /* account name unicode string header */
+               return False;
+       if(!smb_io_unihdr("unihdr", &sam->hdr_grp_desc, ps, depth)) /* account name unicode string header */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a SAM_ENTRY5 structure.
+ Inits a SAM_ENTRY structure.
 ********************************************************************/
-static BOOL sam_io_sam_entry5(char *desc, SAM_ENTRY5 *sam, prs_struct *ps, int depth)
-{
-       if (sam == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_sam_entry5");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
-       smb_io_strhdr("strhdr", &(sam->hdr_grp_name), ps, depth);
-
-       return True;
-}
 
-/*******************************************************************
-makes a SAM_ENTRY structure.
-********************************************************************/
-static BOOL make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
+static void init_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
 {
-       if (sam == NULL) return False;
-
-       DEBUG(10,("make_sam_entry: %d %d\n", len_sam_name, rid));
+       DEBUG(5,("init_sam_entry\n"));
 
        sam->rid = rid;
-       make_uni_hdr(&(sam->hdr_name), len_sam_name);
-
-       return True;
+       init_uni_hdr(&sam->hdr_name, len_sam_name);
 }
 
 /*******************************************************************
-reads or writes a SAM_ENTRY structure.
+ Reads or writes a SAM_ENTRY structure.
 ********************************************************************/
+
 static BOOL sam_io_sam_entry(char *desc,  SAM_ENTRY *sam, prs_struct *ps, int depth)
 {
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sam_io_sam_entry");
        depth++;
 
-       prs_align(ps);
-       prs_uint32("rid", ps, depth, &(sam->rid ));
-       smb_io_unihdr("unihdr", &(sam->hdr_name), ps, depth); /* account name unicode string header */
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("rid", ps, depth, &sam->rid))
+               return False;
+       if(!smb_io_unihdr("unihdr", &sam->hdr_name, ps, depth)) /* account name unicode string header */
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAMR_Q_ENUM_DOM_USERS structure.
+ Inits a SAMR_Q_ENUM_DOM_USERS structure.
 ********************************************************************/
-BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
-                               uint32 start_idx, 
+
+void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+                               uint16 req_num_entries, uint16 unk_0,
                                uint16 acb_mask, uint16 unk_1, uint32 size)
 {
-       if (q_e == NULL || pol == NULL) return False;
+       DEBUG(5,("init_q_enum_dom_users\n"));
 
-       DEBUG(5,("make_samr_q_enum_dom_users\n"));
+       memcpy(&q_e->pol, pol, sizeof(*pol));
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-
-       q_e->start_idx = start_idx; /* zero indicates lots */
+       q_e->req_num_entries = req_num_entries; /* zero indicates lots */
+       q_e->unknown_0 = unk_0; /* this gets returned in the response */
        q_e->acb_mask  = acb_mask;
        q_e->unknown_1 = unk_1;
        q_e->max_size = size;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
 {
-       if (q_e == NULL) return False;
+       if (q_e == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
-       prs_uint16("acb_mask ", ps, depth, &(q_e->acb_mask ));
-       prs_uint16("unknown_1", ps, depth, &(q_e->unknown_1));
+       if(!prs_uint16("req_num_entries", ps, depth, &q_e->req_num_entries))
+               return False;
+       if(!prs_uint16("unknown_0      ", ps, depth, &q_e->unknown_0))
+               return False;
 
-       prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+       if(!prs_uint16("acb_mask       ", ps, depth, &q_e->acb_mask))
+               return False;
+       if(!prs_uint16("unknown_1      ", ps, depth, &q_e->unknown_1))
+               return False;
 
-       prs_align(ps);
+       if(!prs_uint32("max_size       ", ps, depth, &q_e->max_size))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAMR_R_ENUM_DOM_USERS structure.
+ Inits a SAMR_R_ENUM_DOM_USERS structure.
 ********************************************************************/
-BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
-               uint32 next_idx,
+
+void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+               uint16 total_num_entries, uint16 unk_0,
                uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
 {
-       uint32 i;
+       int i;
 
-       if (r_u == NULL) return False;
+       DEBUG(5,("init_samr_r_enum_dom_users\n"));
 
-       DEBUG(5,("make_samr_r_enum_dom_users\n"));
+       if (num_sam_entries >= MAX_SAM_ENTRIES) {
+               num_sam_entries = MAX_SAM_ENTRIES;
+               DEBUG(5,("limiting number of entries to %d\n",
+                        num_sam_entries));
+       }
 
-       r_u->next_idx = next_idx;
-       r_u->sam = NULL;
-       r_u->uni_acct_name = NULL;
+       r_u->total_num_entries = total_num_entries;
+       r_u->unknown_0         = unk_0;
 
-       if (num_sam_entries != 0)
-       {
+       if (total_num_entries > 0) {
                r_u->ptr_entries1 = 1;
                r_u->ptr_entries2 = 1;
                r_u->num_entries2 = num_sam_entries;
                r_u->num_entries3 = num_sam_entries;
 
-               r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-               r_u->uni_acct_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_acct_name[0]));
+               SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
+               SMB_ASSERT_ARRAY(r_u->uni_acct_name, num_sam_entries);
 
-               if (r_u->sam == NULL || r_u->uni_acct_name == NULL)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
-                       return False;
-               }
-
-               for (i = 0; i < num_sam_entries; i++)
-               {
-                       make_sam_entry(&(r_u->sam[i]),
+               for (i = 0; i < num_sam_entries; i++) {
+                       init_sam_entry(&(r_u->sam[i]),
                                       pass[i].uni_user_name.uni_str_len,
                                       pass[i].user_rid);
 
-                       copy_unistr2(&(r_u->uni_acct_name[i]), &(pass[i].uni_user_name));
+                       copy_unistr2(&r_u->uni_acct_name[i], &(pass[i].uni_user_name));
                }
 
                r_u->num_entries4 = num_sam_entries;
-       }
-       else
-       {
+       } else {
                r_u->ptr_entries1 = 0;
                r_u->num_entries2 = num_sam_entries;
                r_u->ptr_entries2 = 1;
        }
 
        r_u->status = status;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
+
+BOOL samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx    ));
-       prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
+       if(!prs_uint16("total_num_entries", ps, depth, &r_u->total_num_entries))
+               return False;
+       if(!prs_uint16("unknown_0        ", ps, depth, &r_u->unknown_0))
+               return False;
+       if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
+               return False;
 
-       if (r_u->ptr_entries1 != 0)
-       {
-               prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
-               prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
-               prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+       if (r_u->total_num_entries != 0 && r_u->ptr_entries1 != 0) {
+               if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
+                       return False;
+               if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
+                       return False;
+               if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
+                       return False;
 
-               if (ps->io)
-               {
-                       r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-                       r_u->uni_acct_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_acct_name[0]));
-               }
+               SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries2);
 
-               if ((r_u->sam == NULL || r_u->uni_acct_name == NULL) && r_u->num_entries2 != 0)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_USERS\n"));
-                       r_u->num_entries4 = 0;
-                       r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
-                       return False;
+               for (i = 0; i < r_u->num_entries2; i++) {
+                       if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
+                               return False;
                }
 
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
-               }
+               SMB_ASSERT_ARRAY(r_u->uni_acct_name, r_u->num_entries2);
 
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       smb_io_unistr2("", &(r_u->uni_acct_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
-                       prs_align(ps);
+               for (i = 0; i < r_u->num_entries2; i++) {
+                       if(!smb_io_unistr2("", &r_u->uni_acct_name[i],
+                                       r_u->sam[i].hdr_name.buffer, ps, depth))
+                               return False;
                }
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
 
+               if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
+                       return False;
        }
 
-       prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_QUERY_DISPINFO structure.
+ Inits a SAMR_Q_ENUM_DOM_ALIASES structure.
 ********************************************************************/
-BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
-                               uint16 switch_level, uint32 start_idx,
-                               uint32 max_entries)
-{
-       if (q_e == NULL || pol == NULL) return False;
 
-       DEBUG(5,("make_samr_q_query_dispinfo\n"));
-
-       memcpy(&(q_e->domain_pol), pol, sizeof(*pol));
-
-       q_e->switch_level = switch_level;
+void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size)
+{
+       DEBUG(5,("init_q_enum_dom_aliases\n"));
 
-       q_e->start_idx = start_idx;
-       q_e->max_entries = max_entries;
-       q_e->max_size = 0xffff; /* Not especially useful */
+       memcpy(&q_e->pol, pol, sizeof(*pol));
 
-       return True;
+       q_e->unknown_0 = 0;
+       q_e->max_size = size;
 }
 
+
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
+
+BOOL samr_io_q_enum_dom_aliases(char *desc,  SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
 {
-       if (q_e == NULL) return False;
+       if (q_e == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
+       prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("domain_pol", &(q_e->domain_pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
-       prs_align(ps);
+       if(!prs_uint32("unknown_0", ps, depth, &q_e->unknown_0))
+               return False;
+       if(!prs_uint32("max_size ", ps, depth, &q_e->max_size ))
+               return False;
 
-       prs_uint32("start_idx   ", ps, depth, &(q_e->start_idx   ));
-       prs_uint32("max_entries ", ps, depth, &(q_e->max_entries ));
-       prs_uint32("max_size    ", ps, depth, &(q_e->max_size    ));
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAM_DISPINFO_1 structure.
+ Inits a SAMR_R_ENUM_DOM_ALIASES structure.
 ********************************************************************/
-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])
-{
-       uint32 len_sam_name, len_sam_full, len_sam_desc;
-       uint32 max_entries, max_data_size;
-       uint32 dsize = 0;
-       uint32 i;
-
-       if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
-
-       DEBUG(5,("make_sam_dispinfo_1\n"));
-
-       max_entries = *num_entries;
-       max_data_size = *data_size;
 
-       for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
-       {
-               len_sam_name = pass[i].uni_user_name.uni_str_len;
-               len_sam_full = pass[i].uni_full_name.uni_str_len;
-               len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
-
-               make_sam_entry1(&(sam->sam[i]), start_idx + i + 1,
-                               len_sam_name, len_sam_full, len_sam_desc,
-                               pass[i].user_rid, pass[i].acb_info);
+void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+               uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
+               uint32 status)
+{
+       int i;
 
-               copy_unistr2(&(sam->str[i].uni_acct_name), &(pass[i].uni_user_name));
-               copy_unistr2(&(sam->str[i].uni_full_name), &(pass[i].uni_full_name));
-               copy_unistr2(&(sam->str[i].uni_acct_desc), &(pass[i].uni_acct_desc));
+       DEBUG(5,("init_samr_r_enum_dom_aliases\n"));
 
-               dsize += sizeof(SAM_ENTRY1);
-               dsize += len_sam_name + len_sam_full + len_sam_desc;
+       if (num_sam_entries >= MAX_SAM_ENTRIES) {
+               num_sam_entries = MAX_SAM_ENTRIES;
+               DEBUG(5,("limiting number of entries to %d\n", 
+                        num_sam_entries));
        }
 
-       *num_entries = i;
-        *data_size = dsize;
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
+       r_u->num_entries  = num_sam_entries;
 
-       if (sam == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1");
-       depth++;
+       if (num_sam_entries > 0) {
+               r_u->ptr_entries  = 1;
+               r_u->num_entries2 = num_sam_entries;
+               r_u->ptr_entries2 = 1;
+               r_u->num_entries3 = num_sam_entries;
 
-       prs_align(ps);
+               SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+               for (i = 0; i < num_sam_entries; i++) {
+                       init_sam_entry(&r_u->sam[i],
+                                      grps[i].uni_user_name.uni_str_len,
+                                      grps[i].user_rid);
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_entry1("", &(sam->sam[i]), ps, depth);
-       }
+                       copy_unistr2(&r_u->uni_grp_name[i], &(grps[i].uni_user_name));
+               }
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_str1 ("", &(sam->str[i]),
-                                sam->sam[i].hdr_acct_name.buffer,
-                                sam->sam[i].hdr_user_name.buffer,
-                                sam->sam[i].hdr_user_desc.buffer,
-                                ps, depth);
+               r_u->num_entries4 = num_sam_entries;
+       } else {
+               r_u->ptr_entries = 0;
        }
 
-       return True;
+       r_u->status = status;
 }
 
-
 /*******************************************************************
-makes a SAM_DISPINFO_2 structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
-{
-       uint32 len_sam_name, len_sam_desc;
-       uint32 max_entries, max_data_size;
-       uint32 dsize = 0;
-       uint32 i;
-
-       if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
 
-       DEBUG(5,("make_sam_dispinfo_2\n"));
-
-       max_entries = *num_entries;
-       max_data_size = *data_size;
-
-       for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
-       {
-               len_sam_name = pass[i].uni_user_name.uni_str_len;
-               len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
-
-               make_sam_entry2(&(sam->sam[i]), start_idx + i + 1,
-                               len_sam_name, len_sam_desc,
-                               pass[i].user_rid, pass[i].acb_info);
+BOOL samr_io_r_enum_dom_aliases(char *desc,  SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
+{
+       int i;
 
-               copy_unistr2(&(sam->str[i].uni_srv_name), &(pass[i].uni_user_name));
-               copy_unistr2(&(sam->str[i].uni_srv_desc), &(pass[i].uni_acct_desc));
+       if (r_u == NULL)
+               return False;
 
-               dsize += sizeof(SAM_ENTRY2);
-               dsize += len_sam_name + len_sam_desc;
-       }
+       prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
+       depth++;
 
-       *num_entries = i;
-        *data_size = dsize;
+       if(!prs_align(ps))
+               return False;
 
-       return True;
-}
+       if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
+               return False;
+       if(!prs_uint32("ptr_entries", ps, depth, &r_u->ptr_entries))
+               return False;
 
-/*******************************************************************
-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)
-{
-       uint32 i;
+       if (r_u->num_entries != 0 && r_u->ptr_entries != 0) {
+               if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
+                       return False;
+               if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
+                       return False;
+               if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
+                       return False;
 
-       if (sam == NULL) return False;
+               SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
 
-       prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_2");
-       depth++;
+               for (i = 0; i < r_u->num_entries; i++) {
+                       if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
+                               return False;
+               }
 
-       prs_align(ps);
+               for (i = 0; i < r_u->num_entries; i++) {
+                       if(!smb_io_unistr2("", &r_u->uni_grp_name[i], r_u->sam[i].hdr_name.buffer, ps, depth))
+                               return False;
+               }
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+               if(!prs_align(ps))
+                       return False;
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_entry2("", &(sam->sam[i]), ps, depth);
+               if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
+                       return False;
        }
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_str2 ("", &(sam->str[i]),
-                                sam->sam[i].hdr_srv_name.buffer,
-                                sam->sam[i].hdr_srv_desc.buffer,
-                                ps, depth);
-       }
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAM_DISPINFO_3 structure.
+ Inits a SAMR_Q_QUERY_DISPINFO structure.
 ********************************************************************/
-BOOL make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        DOMAIN_GRP *grp)
-{
-       uint32 len_sam_name, len_sam_desc;
-       uint32 max_entries, max_data_size;
-       uint32 dsize = 0;
-       uint32 i;
-
-       if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
 
-       DEBUG(5,("make_sam_dispinfo_3\n"));
-
-       max_entries = *num_entries;
-       max_data_size = *data_size;
-
-       for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
-       {
-               len_sam_name = strlen(grp[i].name);
-               len_sam_desc = strlen(grp[i].comment);
-
-               make_sam_entry3(&(sam->sam[i]), start_idx + i + 1,
-                               len_sam_name, len_sam_desc,
-                               grp[i].rid);
-
-               make_unistr2(&(sam->str[i].uni_grp_name), grp[i].name   , len_sam_name);
-               make_unistr2(&(sam->str[i].uni_grp_desc), grp[i].comment, len_sam_desc);
+void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+                               uint16 switch_level, uint32 start_idx, uint32 size)
+{
+       DEBUG(5,("init_q_query_dispinfo\n"));
 
-               dsize += sizeof(SAM_ENTRY3);
-               dsize += (len_sam_name + len_sam_desc) * 2;
-       }
+       memcpy(&q_e->pol, pol, sizeof(*pol));
 
-       *num_entries = i;
-        *data_size = dsize;
+       q_e->switch_level = switch_level;
 
-       return True;
+       q_e->unknown_0 = 0;
+       q_e->start_idx = start_idx;
+       q_e->unknown_1 = 0x000007d0;
+       q_e->max_size  = size;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
-{
-       uint32 i;
 
-       if (sam == NULL) return False;
+BOOL samr_io_q_query_dispinfo(char *desc,  SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
+{
+       if (q_e == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_3");
+       prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_entry3("", &(sam->sam[i]), ps, depth);
-       }
+       if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
+               return False;
+       if(!prs_uint16("unknown_0   ", ps, depth, &q_e->unknown_0))
+               return False;
+       if(!prs_uint32("start_idx   ", ps, depth, &q_e->start_idx))
+               return False;
+       if(!prs_uint32("unknown_1   ", ps, depth, &q_e->unknown_1))
+               return False;
+       if(!prs_uint32("max_size    ", ps, depth, &q_e->max_size))
+               return False;
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_str3 ("", &(sam->str[i]),
-                                sam->sam[i].hdr_grp_name.buffer,
-                                sam->sam[i].hdr_grp_desc.buffer,
-                                ps, depth);
-       }
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAM_DISPINFO_4 structure.
+ Inits a SAM_INFO_2 structure.
 ********************************************************************/
-BOOL make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
-{
-       fstring sam_name;
-       uint32 len_sam_name;
-       uint32 max_entries, max_data_size;
-       uint32 dsize = 0;
-       uint32 i;
 
-       if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+void init_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+       int i;
+       int entries_added;
 
-       DEBUG(5,("make_sam_dispinfo_4\n"));
+       DEBUG(5,("init_sam_info_2\n"));
 
-       max_entries = *num_entries;
-       max_data_size = *data_size;
+       if (num_sam_entries >= MAX_SAM_ENTRIES) {
+               num_sam_entries = MAX_SAM_ENTRIES;
+               DEBUG(5,("limiting number of entries to %d\n", 
+                        num_sam_entries));
+       }
 
-       for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
-       {
-               len_sam_name = pass[i].uni_user_name.uni_str_len;
+       for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
+               if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) {
+                       init_sam_entry2(&sam->sam[entries_added],
+                                       start_idx + entries_added + 1,
+                                       pass[i].uni_user_name.uni_str_len,
+                                       pass[i].uni_acct_desc.uni_str_len,
+                                       pass[i].user_rid,
+                                       pass[i].acb_info);
 
-               make_sam_entry4(&(sam->sam[i]), start_idx + i + 1,
-                               len_sam_name);
+                       copy_unistr2(&sam->str[entries_added].uni_srv_name, &pass[i].uni_user_name);
+                       copy_unistr2(&sam->str[entries_added].uni_srv_desc, &pass[i].uni_acct_desc);
 
-               unistr2_to_ascii(sam_name, &(pass[i].uni_user_name), sizeof(sam_name));
-               make_string2(&(sam->str[i].acct_name), sam_name, len_sam_name);
+                       entries_added++;
+               }
 
-               dsize += sizeof(SAM_ENTRY4);
-               dsize += len_sam_name;
+               sam->num_entries   = entries_added;
+               sam->ptr_entries   = 1;
+               sam->num_entries2  = entries_added;
        }
-
-       *num_entries = i;
-        *data_size = dsize;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
+
+static BOOL sam_io_sam_info_2(char *desc,  SAM_INFO_2 *sam, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_4");
+       prs_debug(ps, depth, desc, "sam_io_sam_info_2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_entries  ", ps, depth, &sam->num_entries))
+               return False;
+       if(!prs_uint32("ptr_entries  ", ps, depth, &sam->ptr_entries))
+               return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
+               return False;
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_entry4("", &(sam->sam[i]), ps, depth);
+       SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+
+       for (i = 0; i < sam->num_entries; i++) {
+               if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth))
+                       return False;
        }
 
-       for (i = 0; i < num_entries; i++)
-       {
-               smb_io_string2("acct_name", &(sam->str[i].acct_name),
-                              sam->sam[i].hdr_acct_name.buffer, ps, depth);
+       for (i = 0; i < sam->num_entries; i++) {
+               if(!sam_io_sam_str2 ("", &sam->str[i],
+                                sam->sam[i].hdr_srv_name.buffer,
+                                sam->sam[i].hdr_srv_desc.buffer,
+                                ps, depth))
+                       return False;
        }
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAM_DISPINFO_5 structure.
+ Inits a SAM_INFO_1 structure.
 ********************************************************************/
-BOOL make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries,
-                        uint32 *data_size, uint32 start_idx,
-                        DOMAIN_GRP *grp)
-{
-       uint32 len_sam_name;
-       uint32 max_entries, max_data_size;
-       uint32 dsize = 0;
-       uint32 i;
-
-       if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
 
-       DEBUG(5,("make_sam_dispinfo_5\n"));
+void init_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+       int i;
+       int entries_added;
 
-       max_entries = *num_entries;
-       max_data_size = *data_size;
+       DEBUG(5,("init_sam_info_1\n"));
 
-       for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
-       {
-               len_sam_name = strlen(grp[i].name);
+       if (num_sam_entries >= MAX_SAM_ENTRIES) {
+               num_sam_entries = MAX_SAM_ENTRIES;
+               DEBUG(5,("limiting number of entries to %d\n", 
+                        num_sam_entries));
+       }
 
-               make_sam_entry5(&(sam->sam[i]), start_idx + i + 1,
-                               len_sam_name);
+       for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
+               if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) {
+                       init_sam_entry1(&sam->sam[entries_added],
+                                               start_idx + entries_added + 1,
+                                               pass[i].uni_user_name.uni_str_len,
+                                               pass[i].uni_full_name.uni_str_len, 
+                                               pass[i].uni_acct_desc.uni_str_len,
+                                               pass[i].user_rid,
+                                               pass[i].acb_info);
 
-               make_string2(&(sam->str[i].grp_name), grp[i].name,
-                            len_sam_name);
+                       copy_unistr2(&sam->str[entries_added].uni_acct_name, &pass[i].uni_user_name);
+                       copy_unistr2(&sam->str[entries_added].uni_full_name, &pass[i].uni_full_name);
+                       copy_unistr2(&sam->str[entries_added].uni_acct_desc, &pass[i].uni_acct_desc);
 
-               dsize += sizeof(SAM_ENTRY5);
-               dsize += len_sam_name;
+                       entries_added++;
+               }
        }
 
-       *num_entries = i;
-        *data_size = dsize;
-
-       return True;
+       sam->num_entries   = entries_added;
+       sam->ptr_entries   = 1;
+       sam->num_entries2  = entries_added;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
+
+static BOOL sam_io_sam_info_1(char *desc,  SAM_INFO_1 *sam, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
 
-       if (sam == NULL) return False;
+       if (sam == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_5");
+       prs_debug(ps, depth, desc, "sam_io_sam_info_1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_entries  ", ps, depth, &sam->num_entries))
+               return False;
+       if(!prs_uint32("ptr_entries  ", ps, depth, &sam->ptr_entries))
+               return False;
 
-       SMB_ASSERT_ARRAY(sam->sam, num_entries);
+       if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
+               return False;
 
-       for (i = 0; i < num_entries; i++)
-       {
-               sam_io_sam_entry5("", &(sam->sam[i]), ps, depth);
+       SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+
+       for (i = 0; i < sam->num_entries; i++) {
+               if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth))
+                       return False;
        }
 
-       for (i = 0; i < num_entries; i++)
-       {
-               smb_io_string2("grp_name", &(sam->str[i].grp_name),
-                              sam->sam[i].hdr_grp_name.buffer, ps, depth);
+       for (i = 0; i < sam->num_entries; i++) {
+               if(!sam_io_sam_str1 ("", &sam->str[i],
+                                                        sam->sam[i].hdr_acct_name.buffer,
+                                                        sam->sam[i].hdr_user_name.buffer,
+                                                        sam->sam[i].hdr_user_desc.buffer,
+                                                        ps, depth))
+               return False;
        }
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_R_QUERY_DISPINFO structure.
+ Inits a SAMR_R_QUERY_DISPINFO structure.
 ********************************************************************/
-BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
-                               uint32 num_entries, uint32 data_size,
-                               uint16 switch_level, SAM_DISPINFO_CTR *ctr,
-                               uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_samr_r_query_dispinfo: level %d\n", switch_level));
+void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+               uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status)
+{
+       DEBUG(5,("init_samr_r_query_dispinfo\n"));
 
-       r_u->total_size = 0; /* not calculated */
-       r_u->data_size = data_size;
+       if (status == 0x0) {
+               r_u->unknown_0 = 0x0000001;
+               r_u->unknown_1 = 0x0000001;
+       } else {
+               r_u->unknown_0 = 0x0;
+               r_u->unknown_1 = 0x0;
+       }
 
        r_u->switch_level = switch_level;
-       r_u->num_entries = num_entries;
-       r_u->ptr_entries = 1;
-       r_u->num_entries2 = num_entries;
        r_u->ctr = ctr;
-
        r_u->status = status;
-
-       return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_r_query_dispinfo(char *desc,  SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("total_size  ", ps, depth, &(r_u->total_size  ));
-       prs_uint32("data_size   ", ps, depth, &(r_u->data_size   ));
-       prs_uint16("switch_level", ps, depth, &(r_u->switch_level));
-       prs_align(ps);
+       if(!prs_uint32("unknown_0    ", ps, depth, &r_u->unknown_0))
+               return False;
+       if(!prs_uint32("unknown_1    ", ps, depth, &r_u->unknown_1))
+               return False;
+       if(!prs_uint16("switch_level ", ps, depth, &r_u->switch_level))
+               return False;
 
-       prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
-       prs_uint32("ptr_entries ", ps, depth, &(r_u->ptr_entries ));
-       prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+       if(!prs_align(ps))
+               return False;
 
-       switch (r_u->switch_level)
-       {
-               case 0x1:
-               {
-                       sam_io_sam_dispinfo_1("users", r_u->ctr->sam.info1, r_u->num_entries, ps, depth);
-                       break;
-               }
-               case 0x2:
-               {
-                       sam_io_sam_dispinfo_2("servers", r_u->ctr->sam.info2, r_u->num_entries, ps, depth);
-                       break;
-               }
-               case 0x3:
-               {
-                       sam_io_sam_dispinfo_3("groups", r_u->ctr->sam.info3, r_u->num_entries, ps, depth);
-                       break;
-               }
-               case 0x4:
-               {
-                       sam_io_sam_dispinfo_4("user list", r_u->ctr->sam.info4,r_u->num_entries, ps, depth);
-                       break;
-               }
-               case 0x5:
-               {
-                       sam_io_sam_dispinfo_5("group list", r_u->ctr->sam.info5, r_u->num_entries, ps, depth);
-                       break;
-               }
-               default:
-               {
-                       DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
-                       break;
-               }
+       switch (r_u->switch_level) {
+       case 0x1:
+               if(!sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth))
+                       return False;
+               break;
+       case 0x2:
+               if(!sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth))
+                       return False;
+               break;
+       default:
+               DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
+               break;
        }
 
-       prs_align(ps);
-       prs_align(ps);
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_OPEN_GROUP structure.
+ Inits a SAMR_Q_ENUM_DOM_GROUPS structure.
 ********************************************************************/
-BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c,
-                               const POLICY_HND *hnd, uint32 unk, uint32 rid)
+
+void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+                               uint16 switch_level, uint32 start_idx, uint32 size)
 {
-       if (q_c == NULL || hnd == NULL) return False;
+       DEBUG(5,("init_q_enum_dom_groups\n"));
 
-       DEBUG(5,("make_samr_q_open_group\n"));
+       memcpy(&q_e->pol, pol, sizeof(*pol));
 
-       memcpy(&(q_c->domain_pol), hnd, sizeof(q_c->domain_pol));
-       q_c->unknown = unk;
-       q_c->rid_group = rid;
+       q_e->switch_level = switch_level;
 
-       return True;
+       q_e->unknown_0 = 0;
+       q_e->start_idx = start_idx;
+       q_e->unknown_1 = 0x000007d0;
+       q_e->max_size  = size;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_open_group(char *desc,  SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_enum_dom_groups(char *desc,  SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_e == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_open_group");
+       prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
+       if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
+               return False;
+       if(!prs_uint16("unknown_0   ", ps, depth, &q_e->unknown_0))
+               return False;
+       if(!prs_uint32("start_idx   ", ps, depth, &q_e->start_idx))
+               return False;
+       if(!prs_uint32("unknown_1   ", ps, depth, &q_e->unknown_1))
+               return False;
+       if(!prs_uint32("max_size    ", ps, depth, &q_e->max_size))
+               return False;
 
-       prs_uint32("unknown  ", ps, depth, &(q_u->unknown  ));
-       prs_uint32("rid_group", ps, depth, &(q_u->rid_group));
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
+
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_R_ENUM_DOM_GROUPS structure.
 ********************************************************************/
-BOOL samr_io_r_open_group(char *desc,  SAMR_R_OPEN_GROUP *r_u, prs_struct *ps, int depth)
+
+void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+               uint32 start_idx, uint32 num_sam_entries,
+               SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
+               uint32 status)
 {
-       if (r_u == NULL) return False;
+       int i;
+       int entries_added;
 
-       prs_debug(ps, depth, desc, "samr_io_r_open_group");
-       depth++;
+       DEBUG(5,("init_samr_r_enum_dom_groups\n"));
 
-       prs_align(ps);
+       if (num_sam_entries >= MAX_SAM_ENTRIES) {
+               num_sam_entries = MAX_SAM_ENTRIES;
+               DEBUG(5,("limiting number of entries to %d\n", 
+                        num_sam_entries));
+       }
 
-       smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a GROUP_INFO1 structure.
-********************************************************************/
-BOOL make_samr_group_info1(GROUP_INFO1 *gr1,
-                               char *acct_name, char *acct_desc,
-                               uint32 num_members)
-{
-       int desc_len = acct_desc != NULL ? strlen(acct_desc) : 0;
-       int acct_len = acct_name != NULL ? strlen(acct_name) : 0;
-       if (gr1 == NULL) return False;
-
-       DEBUG(5,("make_samr_group_info1\n"));
-
-       make_uni_hdr(&(gr1->hdr_acct_name), acct_len);
+       if (status == 0x0) {
+               for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
+                       init_sam_entry3(&r_u->sam[entries_added],
+                                       start_idx + entries_added + 1,
+                                       pass[i].uni_user_name.uni_str_len,
+                                       pass[i].uni_acct_desc.uni_str_len,
+                                       pass[i].user_rid);
 
-       gr1->unknown_1 = 0x3;
-       gr1->num_members = num_members;
+                       copy_unistr2(&r_u->str[entries_added].uni_grp_name, 
+                                               &pass[i].uni_user_name);
+                       copy_unistr2(&r_u->str[entries_added].uni_grp_desc, 
+                                               &pass[i].uni_acct_desc);
 
-       make_uni_hdr(&(gr1->hdr_acct_desc), desc_len);
+                       entries_added++;
+               }
 
-       make_unistr2(&(gr1->uni_acct_name), acct_name, acct_len);
-       make_unistr2(&(gr1->uni_acct_desc), acct_desc, desc_len);
+               if (entries_added > 0) {
+                       r_u->unknown_0 = 0x0000492;
+                       r_u->unknown_1 = 0x000049a;
+               } else {
+                       r_u->unknown_0 = 0x0;
+                       r_u->unknown_1 = 0x0;
+               }
+               r_u->switch_level  = 3;
+               r_u->num_entries   = entries_added;
+               r_u->ptr_entries   = 1;
+               r_u->num_entries2  = entries_added;
+       } else {
+               r_u->switch_level = 0;
+       }
 
-       return True;
+       r_u->status = status;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_group_info1(char *desc,  GROUP_INFO1 *gr1, prs_struct *ps, int depth)
+
+BOOL samr_io_r_enum_dom_groups(char *desc,  SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
 {
-       if (gr1 == NULL) return False;
+       int i;
+
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_group_info1");
+       prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unihdr ("hdr_acct_name", &(gr1->hdr_acct_name) , ps, depth); 
+       if(!prs_uint32("unknown_0    ", ps, depth, &r_u->unknown_0))
+               return False;
+       if(!prs_uint32("unknown_1    ", ps, depth, &r_u->unknown_1))
+               return False;
+       if(!prs_uint32("switch_level ", ps, depth, &r_u->switch_level))
+               return False;
+
+       if (r_u->switch_level != 0) {
+               if(!prs_uint32("num_entries  ", ps, depth, &r_u->num_entries))
+                       return False;
+               if(!prs_uint32("ptr_entries  ", ps, depth, &r_u->ptr_entries))
+                       return False;
 
-       prs_uint32("unknown_1", ps, depth, &(gr1->unknown_1));
-       prs_uint32("num_members", ps, depth, &(gr1->num_members));
+               if(!prs_uint32("num_entries2 ", ps, depth, &r_u->num_entries2))
+                       return False;
 
-       smb_io_unihdr ("hdr_acct_desc", &(gr1->hdr_acct_desc) , ps, depth); 
+               SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
 
-       smb_io_unistr2("uni_acct_name", &(gr1->uni_acct_name), gr1->hdr_acct_name.buffer, ps, depth);
-       prs_align(ps);
+               for (i = 0; i < r_u->num_entries; i++) {
+                       if(!sam_io_sam_entry3("", &r_u->sam[i], ps, depth))
+                               return False;
+               }
 
-       smb_io_unistr2("uni_acct_desc", &(gr1->uni_acct_desc), gr1->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
+               for (i = 0; i < r_u->num_entries; i++) {
+                       if(!sam_io_sam_str3 ("", &r_u->str[i],
+                                            r_u->sam[i].hdr_grp_name.buffer,
+                                            r_u->sam[i].hdr_grp_desc.buffer,
+                                            ps, depth))
+                               return False;
+               }
+       }
+
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a GROUP_INFO4 structure.
+ Inits a SAMR_Q_QUERY_ALIASINFO structure.
 ********************************************************************/
-BOOL make_samr_group_info4(GROUP_INFO4 *gr4, const char *acct_desc)
-{
-       int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
-       if (gr4 == NULL) return False;
 
-       DEBUG(5,("make_samr_group_info4\n"));
+void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+                               POLICY_HND *pol,
+                               uint16 switch_level)
+{
+       DEBUG(5,("init_q_query_aliasinfo\n"));
 
-       make_uni_hdr(&(gr4->hdr_acct_desc), acct_len);
-       make_unistr2(&(gr4->uni_acct_desc), acct_desc, acct_len);
+       memcpy(&q_e->pol, pol, sizeof(*pol));
 
-       return True;
+       q_e->switch_level = switch_level;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_group_info4(char *desc,  GROUP_INFO4 *gr4, prs_struct *ps, int depth)
+
+BOOL samr_io_q_query_aliasinfo(char *desc,  SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
 {
-       if (gr4 == NULL) return False;
+       if (q_e == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_group_info4");
+       prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unihdr ("hdr_acct_desc", &(gr4->hdr_acct_desc) , ps, depth); 
-       smb_io_unistr2("uni_acct_desc", &(gr4->uni_acct_desc), gr4->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_R_QUERY_ALIASINFO structure.
 ********************************************************************/
-BOOL samr_group_info_ctr(char *desc,  GROUP_INFO_CTR *ctr, prs_struct *ps, int depth)
+
+void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
+               uint16 switch_value, char *acct_desc,
+               uint32 status)
 {
-       if (ctr == NULL) return False;
+       DEBUG(5,("init_samr_r_query_aliasinfo\n"));
 
-       prs_debug(ps, depth, desc, "samr_group_info_ctr");
-       depth++;
+       r_u->ptr = 0;
 
-       prs_uint16("switch_value1", ps, depth, &(ctr->switch_value1));
-       prs_uint16("switch_value2", ps, depth, &(ctr->switch_value2));
+       if (status == 0) {
+               r_u->switch_value = switch_value;
 
-       switch (ctr->switch_value1)
-       {
-               case 1:
-               {
-                       samr_io_group_info1("group_info1", &(ctr->group.info1), ps, depth);
-                       break;
-               }
-               case 4:
-               {
-                       samr_io_group_info4("group_info4", &(ctr->group.info4), ps, depth);
-                       break;
-               }
-               default:
-               {
-                       DEBUG(4,("samr_group_info_ctr: unsupported switch level\n"));
-                       break;
+               switch (switch_value) {
+                       case 3:
+                       {
+                               int acct_len = acct_desc ? strlen(acct_desc) : 0;
+
+                               r_u->ptr = 1;
+
+                               init_uni_hdr(&r_u->alias.info3.hdr_acct_desc, acct_len);
+                               init_unistr2(&r_u->alias.info3.uni_acct_desc, acct_desc, acct_len);
+
+                               break;
+                       }
+                       default:
+                               DEBUG(4,("init_samr_r_query_aliasinfo: unsupported switch level\n"));
+                               break;
                }
        }
 
-       prs_align(ps);
-
-       return True;
+       r_u->status = status;
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_CREATE_DOM_GROUP structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_e,
-                               POLICY_HND *pol,
-                               const char *acct_desc)
+
+BOOL samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
 {
-       int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
-       if (q_e == NULL || pol == NULL) return False;
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
+       depth++;
 
-       DEBUG(5,("make_samr_q_create_dom_group\n"));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr         ", ps, depth, &r_u->ptr))
+               return False;
+       
+       if (r_u->ptr != 0) {
+               if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
+                       return False;
+               if(!prs_align(ps))
+                       return False;
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
+               if (r_u->switch_value != 0) {
+                       switch (r_u->switch_value) {
+                               case 3:
+                                       if(!smb_io_unihdr ("", &r_u->alias.info3.hdr_acct_desc, ps, depth))
+                                               return False;
+                                       if(!smb_io_unistr2("", &r_u->alias.info3.uni_acct_desc, 
+                                                       r_u->alias.info3.hdr_acct_desc.buffer, ps, depth))
+                                               return False;
+                                       break;
+                               default:
+                                       DEBUG(4,("samr_io_r_query_aliasinfo: unsupported switch level\n"));
+                                       break;
+                       }
+               }
+       }
 
-       make_uni_hdr(&(q_e->hdr_acct_desc), acct_len);
-       make_unistr2(&(q_e->uni_acct_desc), acct_desc, acct_len);
+       if(!prs_align(ps))
+               return False;
 
-       q_e->unknown_1 = 0x0002;
-       q_e->unknown_2 = 0x0001;
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a SAMR_Q_LOOKUP_IDS structure.
 ********************************************************************/
-BOOL samr_io_q_create_dom_group(char *desc,  SAMR_Q_CREATE_DOM_GROUP *q_e, prs_struct *ps, int depth)
+
+BOOL samr_io_q_lookup_ids(char *desc,  SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth)
 {
-       if (q_e == NULL) return False;
+       fstring tmp;
+       int i;
 
-       prs_debug(ps, depth, desc, "samr_io_q_create_dom_group");
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_q_lookup_ids");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &(q_u->pol), ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unihdr ("hdr_acct_desc", &(q_e->hdr_acct_desc), ps, depth); 
-       smb_io_unistr2("uni_acct_desc", &(q_e->uni_acct_desc), q_e->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
+       if(!prs_uint32("num_sids1", ps, depth, &q_u->num_sids1))
+               return False;
+       if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
+               return False;
+       if(!prs_uint32("num_sids2", ps, depth, &q_u->num_sids2))
+               return False;
+
+       SMB_ASSERT_ARRAY(q_u->ptr_sid, q_u->num_sids2);
+
+       for (i = 0; i < q_u->num_sids2; i++) {
+               slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
+               if(!prs_uint32(tmp, ps, depth, &q_u->ptr_sid[i]))
+                       return False;
+       }
+
+       for (i = 0; i < q_u->num_sids2; i++) {
+               if (q_u->ptr_sid[i] != 0) {
+                       slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
+                       if(!smb_io_dom_sid2(tmp, &q_u->sid[i], ps, depth))
+                               return False;
+               }
+       }
 
-       prs_uint16("unknown_1", ps, depth, &(q_e->unknown_1));
-       prs_uint16("unknown_2", ps, depth, &(q_e->unknown_2));
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_R_CREATE_DOM_GROUP structure.
+ Inits a SAMR_R_LOOKUP_IDS structure.
 ********************************************************************/
-BOOL make_samr_r_create_dom_group(SAMR_R_CREATE_DOM_GROUP *r_u, POLICY_HND *pol,
-               uint32 rid, uint32 status)
+
+void init_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
+               uint32 num_rids, uint32 *rid, uint32 status)
 {
-       if (r_u == NULL) return False;
+       int i;
 
-       DEBUG(5,("make_samr_r_create_dom_group\n"));
+       DEBUG(5,("init_samr_r_lookup_ids\n"));
 
-       memcpy(&(r_u->pol), pol, sizeof(*pol));
+       if (status == 0x0) {
+               r_u->num_entries  = num_rids;
+               r_u->ptr = 1;
+               r_u->num_entries2 = num_rids;
 
-       r_u->rid    = rid   ;
-       r_u->status = status;
+               SMB_ASSERT_ARRAY(r_u->rid, num_rids);
 
-       return True;
-}
+               for (i = 0; i < num_rids; i++) {
+                       r_u->rid[i] = rid[i];
+               }
+       } else {
+               r_u->num_entries  = 0;
+               r_u->ptr = 0;
+               r_u->num_entries2 = 0;
+       }
 
+       r_u->status = status;
+}
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
-{
-       if (r_u == NULL) return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_create_dom_group");
-       depth++;
+BOOL samr_io_r_lookup_ids(char *desc,  SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth)
+{
+       fstring tmp;
+       int i;
 
-       prs_align(ps);
+       if (r_u == NULL)
+               return False;
 
-       smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
-       prs_align(ps);
+       prs_debug(ps, depth, desc, "samr_io_r_lookup_ids");
+       depth++;
 
-       prs_uint32("rid   ", ps, depth, &(r_u->rid   ));
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_align(ps))
+               return False;
 
-       return True;
-}
+       if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
+               return False;
+       if(!prs_uint32("ptr        ", ps, depth, &r_u->ptr))
+               return False;
+       if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
+               return False;
 
-/*******************************************************************
-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)
-{
-       if (q_c == NULL || hnd == NULL) return False;
+       if (r_u->num_entries != 0) {
+               SMB_ASSERT_ARRAY(r_u->rid, r_u->num_entries2);
 
-       DEBUG(5,("make_samr_q_delete_dom_group\n"));
+               for (i = 0; i < r_u->num_entries2; i++) {
+                       slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
+                       if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
+                               return False;
+               }
+       }
 
-       memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
+
+BOOL samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       int i;
+
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_delete_dom_group");
+       prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
        depth++;
 
        prs_align(ps);
 
-       smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth); 
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_names1", ps, depth, &q_u->num_names1))
+               return False;
+       if(!prs_uint32("flags     ", ps, depth, &q_u->flags))
+               return False;
+       if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
+               return False;
+       if(!prs_uint32("num_names2", ps, depth, &q_u->num_names2))
+               return False;
+
+       SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
+
+       for (i = 0; i < q_u->num_names2; i++) {
+               if(!smb_io_unihdr ("", &q_u->hdr_name[i], ps, depth))
+                       return False;
+       }
+       for (i = 0; i < q_u->num_names2; i++) {
+               if(!smb_io_unistr2("", &q_u->uni_name[i], q_u->hdr_name[i].buffer, ps, depth))
+                       return False;
+       }
 
        return True;
 }
 
+
 /*******************************************************************
-makes a SAMR_R_DELETE_DOM_GROUP structure.
+ Inits a SAMR_R_LOOKUP_NAMES structure.
 ********************************************************************/
-BOOL make_samr_r_delete_dom_group(SAMR_R_DELETE_DOM_GROUP *r_u,
-               uint32 status)
+
+void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+                       uint32 num_rids, uint32 *rid, uint8 *type, uint32 status)
 {
-       if (r_u == NULL) return False;
+       int i;
 
-       DEBUG(5,("make_samr_r_delete_dom_group\n"));
+       DEBUG(5,("init_samr_r_lookup_names\n"));
 
-       r_u->status = status;
+       if (status == 0x0) {
+               r_u->num_types1 = num_rids;
+               r_u->ptr_types  = 1;
+               r_u->num_types2 = num_rids;
 
-       return True;
+               r_u->num_rids1 = num_rids;
+               r_u->ptr_rids  = 1;
+               r_u->num_rids2 = num_rids;
+
+               SMB_ASSERT_ARRAY(r_u->rid, num_rids);
+
+               for (i = 0; i < num_rids; i++) {
+                       r_u->rid [i] = rid [i];
+                       r_u->type[i] = type[i];
+               }
+       } else {
+               r_u->num_types1 = 0;
+               r_u->ptr_types  = 0;
+               r_u->num_types2 = 0;
+
+               r_u->num_rids1 = 0;
+               r_u->ptr_rids  = 0;
+               r_u->num_rids2 = 0;
+       }
+
+       r_u->status = status;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ 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)
+
+BOOL samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       int i;
+       fstring tmp;
+
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_delete_dom_group");
+       prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("num_rids1", ps, depth, &r_u->num_rids1))
+               return False;
+       if(!prs_uint32("ptr_rids ", ps, depth, &r_u->ptr_rids ))
+               return False;
 
-       return True;
-}
+       if (r_u->ptr_rids != 0) {
+               if(!prs_uint32("num_rids2", ps, depth, &r_u->num_rids2))
+                       return False;
 
+               if (r_u->num_rids2 != r_u->num_rids1) {
+                       /* RPC fault */
+                       return False;
+               }
 
+               for (i = 0; i < r_u->num_rids2; i++) {
+                       slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
+                       if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
+                               return False;
+               }
+       }
 
-/*******************************************************************
-makes a SAMR_Q_DEL_GROUPMEM structure.
-********************************************************************/
-BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_e,
-                               POLICY_HND *pol,
-                               uint32 rid)
-{
-       if (q_e == NULL || pol == NULL) return False;
+       if(!prs_uint32("num_types1", ps, depth, &r_u->num_types1))
+               return False;
+       if(!prs_uint32("ptr_types ", ps, depth, &r_u->ptr_types))
+               return False;
+
+       if (r_u->ptr_types != 0) {
+               if(!prs_uint32("num_types2", ps, depth, &r_u->num_types2))
+                       return False;
 
-       DEBUG(5,("make_samr_q_del_groupmem\n"));
+               if (r_u->num_types2 != r_u->num_types1) {
+                       /* RPC fault */
+                       return False;
+               }
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
+               for (i = 0; i < r_u->num_types2; i++) {
+                       slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
+                       if(!prs_uint32(tmp, ps, depth, &r_u->type[i]))
+                               return False;
+               }
+       }
 
-       q_e->rid = rid;
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_del_groupmem(char *desc,  SAMR_Q_DEL_GROUPMEM *q_e, prs_struct *ps, int depth)
+
+BOOL samr_io_q_unknown_12(char *desc,  SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth)
 {
-       if (q_e == NULL) return False;
+       int i;
+       fstring tmp;
 
-       prs_debug(ps, depth, desc, "samr_io_q_del_groupmem");
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_q_unknown_12");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_gids1", ps, depth, &q_u->num_gids1))
+               return False;
+       if(!prs_uint32("rid      ", ps, depth, &q_u->rid))
+               return False;
+       if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
+               return False;
+       if(!prs_uint32("num_gids2", ps, depth, &q_u->num_gids2))
+               return False;
+
+       SMB_ASSERT_ARRAY(q_u->gid, q_u->num_gids2);
+
+       for (i = 0; i < q_u->num_gids2; i++) {
+               slprintf(tmp, sizeof(tmp) - 1, "gid[%02d]  ", i);
+               if(!prs_uint32(tmp, ps, depth, &q_u->gid[i]))
+                       return False;
+       }
 
-       prs_uint32("rid    ", ps, depth, &(q_e->rid));
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_R_DEL_GROUPMEM structure.
+ Inits a SAMR_R_UNKNOWN_12 structure.
 ********************************************************************/
-BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM *r_u, POLICY_HND *pol,
+
+void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+               uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
                uint32 status)
 {
-       if (r_u == NULL) return False;
+       int i;
 
-       DEBUG(5,("make_samr_r_del_groupmem\n"));
+       DEBUG(5,("init_samr_r_unknown_12\n"));
 
-       r_u->status = status;
-
-       return True;
-}
+       if (status == 0x0) {
+               r_u->num_aliases1 = num_aliases;
+               r_u->ptr_aliases  = 1;
+               r_u->num_aliases2 = num_aliases;
 
+               r_u->num_als_usrs1 = num_aliases;
+               r_u->ptr_als_usrs  = 1;
+               r_u->num_als_usrs2 = num_aliases;
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_del_groupmem(char *desc,  SAMR_R_DEL_GROUPMEM *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_del_groupmem");
-       depth++;
+               SMB_ASSERT_ARRAY(r_u->hdr_als_name, num_aliases);
 
-       prs_align(ps);
+               for (i = 0; i < num_aliases; i++) {
+                       int als_len = als_name[i] != NULL ? strlen(als_name[i]) : 0;
+                       init_uni_hdr(&r_u->hdr_als_name[i], als_len);
+                       init_unistr2(&r_u->uni_als_name[i], als_name[i], als_len);
+                       r_u->num_als_usrs[i] = num_als_usrs[i];
+               }
+       } else {
+               r_u->num_aliases1 = num_aliases;
+               r_u->ptr_aliases  = 0;
+               r_u->num_aliases2 = num_aliases;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+               r_u->num_als_usrs1 = num_aliases;
+               r_u->ptr_als_usrs  = 0;
+               r_u->num_als_usrs2 = num_aliases;
+       }
 
-       return True;
+       r_u->status = status;
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_ADD_GROUPMEM structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_e,
-                               POLICY_HND *pol,
-                               uint32 rid)
+
+BOOL samr_io_r_unknown_12(char *desc,  SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth)
 {
-       if (q_e == NULL || pol == NULL) return False;
+       int i;
+       fstring tmp;
 
-       DEBUG(5,("make_samr_q_add_groupmem\n"));
+       if (r_u == NULL)
+               return False;
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
+       prs_debug(ps, depth, desc, "samr_io_r_unknown_12");
+       depth++;
 
-       q_e->rid = rid;
-       q_e->unknown = 0x0005;
+       if(!prs_align(ps))
+               return False;
 
-       return True;
-}
+       if(!prs_uint32("num_aliases1", ps, depth, &r_u->num_aliases1))
+               return False;
+       if(!prs_uint32("ptr_aliases ", ps, depth, &r_u->ptr_aliases ))
+               return False;
+       if(!prs_uint32("num_aliases2", ps, depth, &r_u->num_aliases2))
+               return False;
 
+       if (r_u->ptr_aliases != 0 && r_u->num_aliases1 != 0) {
+               SMB_ASSERT_ARRAY(r_u->hdr_als_name, r_u->num_aliases2);
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_add_groupmem(char *desc,  SAMR_Q_ADD_GROUPMEM *q_e, prs_struct *ps, int depth)
-{
-       if (q_e == NULL) return False;
+               for (i = 0; i < r_u->num_aliases2; i++) {
+                       slprintf(tmp, sizeof(tmp) - 1, "als_hdr[%02d]  ", i);
+                       if(!smb_io_unihdr ("", &r_u->hdr_als_name[i], ps, depth))
+                               return False;
+               }
+               for (i = 0; i < r_u->num_aliases2; i++) {
+                       slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d]  ", i);
+                       if(!smb_io_unistr2("", &r_u->uni_als_name[i], r_u->hdr_als_name[i].buffer, ps, depth))
+                               return False;
+               }
+       }
 
-       prs_debug(ps, depth, desc, "samr_io_q_add_groupmem");
-       depth++;
+       if(!prs_align(ps))
+               return False;
 
-       prs_align(ps);
+       if(!prs_uint32("num_als_usrs1", ps, depth, &r_u->num_als_usrs1))
+               return False;
+       if(!prs_uint32("ptr_als_usrs ", ps, depth, &r_u->ptr_als_usrs))
+               return False;
+       if(!prs_uint32("num_als_usrs2", ps, depth, &r_u->num_als_usrs2))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if (r_u->ptr_als_usrs != 0 && r_u->num_als_usrs1 != 0) {
+               SMB_ASSERT_ARRAY(r_u->num_als_usrs, r_u->num_als_usrs2);
 
-       prs_uint32("rid    ", ps, depth, &(q_e->rid));
-       prs_uint32("unknown", ps, depth, &(q_e->unknown));
+               for (i = 0; i < r_u->num_als_usrs2; i++) {
+                       slprintf(tmp, sizeof(tmp) - 1, "als_usrs[%02d]  ", i);
+                       if(!prs_uint32(tmp, ps, depth, &r_u->num_als_usrs[i]))
+                               return False;
+               }
+       }
+
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a SAMR_R_ADD_GROUPMEM structure.
+ Inits a SAMR_Q_OPEN_USER struct.
 ********************************************************************/
-BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM *r_u, POLICY_HND *pol,
-               uint32 status)
+
+void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+                               POLICY_HND *pol,
+                               uint32 unk_0, uint32 rid)
 {
-       if (r_u == NULL) return False;
+       DEBUG(5,("samr_init_q_open_user\n"));
 
-       DEBUG(5,("make_samr_r_add_groupmem\n"));
-
-       r_u->status = status;
-
-       return True;
+       memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
+       
+       q_u->unknown_0 = unk_0;
+       q_u->user_rid  = rid;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_add_groupmem(char *desc,  SAMR_R_ADD_GROUPMEM *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_add_groupmem");
+       prs_debug(ps, depth, desc, "samr_io_q_open_user");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
+       if(!prs_align(ps))
+               return False;
 
-/*******************************************************************
-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)
-{
-       if (q_e == NULL || pol == NULL) return False;
+       if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       DEBUG(5,("make_samr_q_set_groupinfo\n"));
+       if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
+               return False;
+       if(!prs_uint32("user_rid ", ps, depth, &q_u->user_rid))
+               return False;
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-       q_e->ctr = ctr;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_set_groupinfo(char *desc,  SAMR_Q_SET_GROUPINFO *q_e, prs_struct *ps, int depth)
+
+BOOL samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
 {
-       if (q_e == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_set_groupinfo");
+       prs_debug(ps, depth, desc, "samr_io_r_open_user");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       samr_group_info_ctr("ctr", q_e->ctr, ps, depth);
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_R_SET_GROUPINFO structure.
+ Inits a SAMR_Q_QUERY_USERGROUPS structure.
 ********************************************************************/
-BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO *r_u, 
-               uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_samr_r_set_groupinfo\n"));
-
-       r_u->status = status;
+void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+                               POLICY_HND *hnd)
+{
+       DEBUG(5,("init_samr_q_query_usergroups\n"));
 
-       return True;
+       memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_set_groupinfo(char *desc,  SAMR_R_SET_GROUPINFO *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_set_groupinfo");
+       prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_QUERY_GROUPINFO structure.
+ Inits a SAMR_R_QUERY_USERGROUPS structure.
 ********************************************************************/
-BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_e,
-                               POLICY_HND *pol,
-                               uint16 switch_level)
-{
-       if (q_e == NULL || pol == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_groupinfo\n"));
-
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-
-       q_e->switch_level = switch_level;
-
-       return True;
-}
 
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_query_groupinfo(char *desc,  SAMR_Q_QUERY_GROUPINFO *q_e, prs_struct *ps, int depth)
+void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+               uint32 num_gids, DOM_GID *gid, uint32 status)
 {
-       if (q_e == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_groupinfo");
-       depth++;
+       DEBUG(5,("init_samr_r_query_usergroups\n"));
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+       if (status == 0x0) {
+               r_u->ptr_0        = 1;
+               r_u->num_entries  = num_gids;
+               r_u->ptr_1        = 1;
+               r_u->num_entries2 = num_gids;
 
-       prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+               r_u->gid = gid;
+       } else {
+               r_u->ptr_0       = 0;
+               r_u->num_entries = 0;
+               r_u->ptr_1       = 0;
+       }
 
-       return True;
+       r_u->status = status;
 }
 
-
 /*******************************************************************
-makes a SAMR_R_QUERY_GROUPINFO structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO *r_u, GROUP_INFO_CTR *ctr,
-               uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_samr_r_query_groupinfo\n"));
+BOOL samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
+{
+       int i;
 
-       r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
-       r_u->ctr = ctr;
-       r_u->status = status;
+       if (r_u == NULL)
+               return False;
 
-       return True;
-}
+       prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
+       depth++;
 
+       if(!prs_align(ps))
+               return False;
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_groupinfo(char *desc,  SAMR_R_QUERY_GROUPINFO *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
+       if(!prs_uint32("ptr_0       ", ps, depth, &r_u->ptr_0))
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_query_groupinfo");
-       depth++;
+       if (r_u->ptr_0 != 0) {
+               if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
+                       return False;
+               if(!prs_uint32("ptr_1       ", ps, depth, &r_u->ptr_1))
+                       return False;
 
-       prs_align(ps);
+               if (r_u->num_entries != 0) {
+                       if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
+                               return False;
 
-       prs_uint32("ptr", ps, depth, &(r_u->ptr));
-       
-       if (r_u->ptr != 0)
-       {
-               samr_group_info_ctr("ctr", r_u->ctr, ps, depth);
+                       for (i = 0; i < r_u->num_entries2; i++) {
+                               if(!smb_io_gid("", &r_u->gid[i], ps, depth))
+                                       return False;
+                       }
+               }
        }
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_QUERY_GROUPMEM structure.
+ Inits a SAMR_Q_QUERY_USERINFO structure.
 ********************************************************************/
-BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_c, POLICY_HND *hnd)
-{
-       if (q_c == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_groupmem\n"));
-
-       memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
 
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_query_groupmem(char *desc,  SAMR_Q_QUERY_GROUPMEM *q_u, prs_struct *ps, int depth)
+void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+                               POLICY_HND *hnd, uint16 switch_value)
 {
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_groupmem");
-       depth++;
+       DEBUG(5,("init_samr_q_query_userinfo\n"));
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth); 
-
-       return True;
+       memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
+       q_u->switch_value = switch_value;
 }
 
 /*******************************************************************
-makes a SAMR_R_QUERY_GROUPMEM structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u,
-               uint32 num_entries, uint32 *rid, uint32 *attr, uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_samr_r_query_groupmem\n"));
-
-       if (status == 0x0)
-       {
-               r_u->ptr         = 1;
-               r_u->num_entries = num_entries;
+BOOL samr_io_q_query_userinfo(char *desc,  SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
 
-               r_u->ptr_attrs = attr != NULL ? 1 : 0;
-               r_u->ptr_rids = rid != NULL ? 1 : 0;
+       prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
+       depth++;
 
-               r_u->num_rids = num_entries;
-               r_u->rid  = rid;
+       if(!prs_align(ps))
+               return False;
 
-               r_u->num_attrs = num_entries;
-               r_u->attr = attr;
-       }
-       else
-       {
-               r_u->ptr         = 0;
-               r_u->num_entries = 0;
-       }
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       r_u->status = status;
+       if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) /* 0x0015 or 0x0011 */
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a LOGON_HRS structure.
 ********************************************************************/
-BOOL samr_io_r_query_groupmem(char *desc,  SAMR_R_QUERY_GROUPMEM *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
 
-       if (r_u == NULL) return False;
+static BOOL sam_io_logon_hrs(char *desc,  LOGON_HRS *hrs, prs_struct *ps, int depth)
+{
+       if (hrs == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_query_groupmem");
+       prs_debug(ps, depth, desc, "sam_io_logon_hrs");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("ptr", ps, depth, &(r_u->ptr));
-       prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
-
-       if (r_u->ptr != 0)
-       {
-               prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids ));
-               prs_uint32("ptr_attrs", ps, depth, &(r_u->ptr_attrs));
-
-               if (r_u->ptr_rids != 0)
-               {
-                       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);
-                               if (r_u->rid == NULL)
-                               {
-                                       samr_free_r_query_groupmem(r_u);
-                                       return False;
-                               }
-                       }
-                       for (i = 0; i < r_u->num_rids; i++)
-                       {
-                               prs_uint32("", ps, depth, &(r_u->rid[i]));
-                       }
-               }
-
-               if (r_u->ptr_attrs != 0)
-               {
-                       prs_uint32("num_attrs", ps, depth, &(r_u->num_attrs));
+       if(!prs_align(ps))
+               return False;
+       
+       if(!prs_uint32 (       "len  ", ps, depth, &hrs->len))
+               return False;
 
-                       if (r_u->num_attrs != 0)
-                       {
-                               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);
-                                       return False;
-                               }
-                       }
-                       for (i = 0; i < r_u->num_attrs; i++)
-                       {
-                               prs_uint32("", ps, depth, &(r_u->attr[i]));
-                       }
-               }
+       if (hrs->len > 64) {
+               DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
+               hrs->len = 64;
        }
 
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       if (!ps->io)
-       {
-               /* storing.  memory no longer needed */
-               samr_free_r_query_groupmem(r_u);
-       }
+       if(!prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-frees a structure.
+ Inits a SAM_USER_INFO_10 structure.
 ********************************************************************/
-void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u)
-{
-       if (r_u->rid != NULL)
-       {
-               free(r_u->rid);
-               r_u->rid = NULL;
-       }
-       if (r_u->attr != NULL)
-       {
-               free(r_u->attr);
-               r_u->attr = NULL;
-       }
-}
 
-/*******************************************************************
-makes a SAMR_Q_QUERY_USERGROUPS structure.
-********************************************************************/
-BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
-                               POLICY_HND *hnd)
+void init_sam_user_info10(SAM_USER_INFO_10 *usr,
+                               uint32 acb_info)
 {
-       if (q_u == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_usergroups\n"));
+       DEBUG(5,("init_sam_user_info10\n"));
 
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
-
-       return True;
+       usr->acb_info = acb_info;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_query_usergroups(char *desc,  SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
+
+BOOL sam_io_user_info10(char *desc,  SAM_USER_INFO_10 *usr, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (usr == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
+       prs_debug(ps, depth, desc, "samr_io_r_user_info10");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
+       if(!prs_uint32("acb_info", ps, depth, &usr->acb_info))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_QUERY_USERGROUPS structure.
+ Inits a SAM_USER_INFO_11 structure.
 ********************************************************************/
-BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
-               uint32 num_gids, DOM_GID *gid, uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_usergroups\n"));
 
-       if (status == 0x0)
-       {
-               r_u->ptr_0        = 1;
-               r_u->num_entries  = num_gids;
-               r_u->ptr_1        = (num_gids != 0) ? 1 : 0;
-               r_u->num_entries2 = num_gids;
+void init_sam_user_info11(SAM_USER_INFO_11 *usr,
+                               NTTIME *expiry,
+                               char *mach_acct,
+                               uint32 rid_user,
+                               uint32 rid_group,
+                               uint16 acct_ctrl)
+                               
+{
+       int len_mach_acct;
 
-               r_u->gid = gid;
-       }
-       else
-       {
-               r_u->ptr_0       = 0;
-               r_u->num_entries = 0;
-               r_u->ptr_1       = 0;
-       }
+       DEBUG(5,("init_sam_user_info11\n"));
 
-       r_u->status = status;
+       len_mach_acct = strlen(mach_acct);
 
-       return True;
-}
+       memcpy(&usr->expiry,expiry, sizeof(usr->expiry)); /* expiry time or something? */
+       memset((char *)usr->padding_1, '\0', sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_usergroups(char *desc,  SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-       if (r_u == NULL) return False;
+       init_uni_hdr(&usr->hdr_mach_acct, len_mach_acct);  /* unicode header for machine account */
+       usr->padding_2 = 0;               /* 0 - padding 4 bytes */
 
-       prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
-       depth++;
+       usr->ptr_1        = 1;            /* pointer */
+       memset((char *)usr->padding_3, '\0', sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
+       usr->padding_4    = 0;            /* 0 - padding 4 bytes */
 
-       prs_align(ps);
+       usr->ptr_2        = 1;            /* pointer */
+       usr->padding_5    = 0;            /* 0 - padding 4 bytes */
 
-       prs_uint32("ptr_0       ", ps, depth, &(r_u->ptr_0      ));
+       usr->ptr_3        = 1;          /* pointer */
+       memset((char *)usr->padding_6, '\0', sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
 
-       if (r_u->ptr_0 != 0)
-       {
-               prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
-               prs_uint32("ptr_1       ", ps, depth, &(r_u->ptr_1      ));
+       usr->rid_user     = rid_user; 
+       usr->rid_group    = rid_group;
 
-               if (r_u->num_entries != 0)
-               {
-                       prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+       usr->acct_ctrl    = acct_ctrl;
+       usr->unknown_3    = 0x0000;
 
-                       r_u->gid = (DOM_GID*)malloc(r_u->num_entries2 * sizeof(r_u->gid[0]));
-                       if (r_u->gid == NULL)
-                       {
-                               return False;
-                       }
+       usr->unknown_4    = 0x003f;       /* 0x003f      - 16 bit unknown */
+       usr->unknown_5    = 0x003c;       /* 0x003c      - 16 bit unknown */
 
-                       for (i = 0; i < r_u->num_entries2; i++)
-                       {
-                               smb_io_gid("", &(r_u->gid[i]), ps, depth);
-                       }
-               }
-       }
-       prs_uint32("status", ps, depth, &(r_u->status));
+       memset((char *)usr->padding_7, '\0', sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
+       usr->padding_8    = 0;            /* 0 - padding 4 bytes */
+       
+       init_unistr2(&usr->uni_mach_acct, mach_acct, len_mach_acct);  /* unicode string for machine account */
 
-       return True;
+       memset((char *)usr->padding_9, '\0', sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
 }
 
-
 /*******************************************************************
-makes a SAMR_Q_ENUM_DOMAINS structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS *q_e, POLICY_HND *pol,
-                               uint32 start_idx, uint32 size)
-{
-       if (q_e == NULL || pol == NULL) return False;
-
-       DEBUG(5,("make_samr_q_enum_domains\n"));
 
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
+BOOL sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
+{
+       if (usr == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_r_unknown_24");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0))) 
+               return False;
+
+       if(!smb_io_time("time", &(usr->expiry), ps, depth))
+               return False;
+
+       if(!prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1)))
+               return False;
+
+       if(!smb_io_unihdr ("unihdr", &usr->hdr_mach_acct, ps, depth))
+               return False;
+       if(!prs_uint32(        "padding_2", ps, depth, &usr->padding_2))
+               return False;
+
+       if(!prs_uint32(        "ptr_1    ", ps, depth, &usr->ptr_1))
+               return False;
+       if(!prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3)))
+               return False;
+       if(!prs_uint32(        "padding_4", ps, depth, &usr->padding_4))
+               return False;
+
+       if(!prs_uint32(        "ptr_2    ", ps, depth, &usr->ptr_2))
+               return False;
+       if(!prs_uint32(        "padding_5", ps, depth, &usr->padding_5))
+               return False;
+
+       if(!prs_uint32(        "ptr_3    ", ps, depth, &usr->ptr_3))
+               return False;
+       if(!prs_uint8s(False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6)))
+               return False;
+
+       if(!prs_uint32(        "rid_user ", ps, depth, &usr->rid_user))
+               return False;
+       if(!prs_uint32(        "rid_group", ps, depth, &usr->rid_group))
+               return False;
+       if(!prs_uint16(        "acct_ctrl", ps, depth, &usr->acct_ctrl))
+               return False;
+       if(!prs_uint16(        "unknown_3", ps, depth, &usr->unknown_3))
+               return False;
+       if(!prs_uint16(        "unknown_4", ps, depth, &usr->unknown_4))
+               return False;
+       if(!prs_uint16(        "unknown_5", ps, depth, &usr->unknown_5))
+               return False;
+
+       if(!prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7)))
+               return False;
+       if(!prs_uint32(        "padding_8", ps, depth, &usr->padding_8))
+               return False;
+       
+       if(!smb_io_unistr2("unistr2", &usr->uni_mach_acct, True, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       q_e->start_idx = start_idx;
-       q_e->max_size = size;
+       if(!prs_uint8s(False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9)))
+               return False;
 
        return True;
 }
 
+/*************************************************************************
+ init_sam_user_info21
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS *q_e, prs_struct *ps, int depth)
-{
-       if (q_e == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_enum_domains");
-       depth++;
+ unknown_3 = 0x00ff ffff
+ unknown_5 = 0x0002 0000
+ unknown_6 = 0x0000 04ec 
 
-       prs_align(ps);
+ *************************************************************************/
 
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
+void init_sam_user_info21(SAM_USER_INFO_21 *usr,
+       NTTIME *logon_time,
+       NTTIME *logoff_time,
+       NTTIME *kickoff_time,
+       NTTIME *pass_last_set_time,
+       NTTIME *pass_can_change_time,
+       NTTIME *pass_must_change_time,
 
-       prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
-       prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+       char *user_name,
+       char *full_name,
+       char *home_dir,
+       char *dir_drive,
+       char *logon_script,
+       char *profile_path,
+       char *description,
+       char *workstations,
+       char *unknown_str,
+       char *munged_dial,
 
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_ENUM_DOMAINS structure.
-********************************************************************/
-BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS *r_u,
-               uint32 next_idx,
-               uint32 num_sam_entries, char **doms, uint32 status)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_enum_domains\n"));
-
-       r_u->next_idx = next_idx;
-       r_u->sam = NULL;
-       r_u->uni_dom_name = NULL;
-
-       if (num_sam_entries != 0)
-       {
-               r_u->ptr_entries1 = 1;
-               r_u->ptr_entries2 = 1;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->num_entries3 = num_sam_entries;
-
-               r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-               r_u->uni_dom_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_dom_name[0]));
-
-               if (r_u->sam == NULL || r_u->uni_dom_name == NULL)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOMAINS\n"));
-                       return False;
-               }
-
-               for (i = 0; i < num_sam_entries; i++)
-               {
-                       int acct_name_len = doms[i] != NULL ? strlen(doms[i]) : 0;
-
-                       make_sam_entry(&(r_u->sam[i]), acct_name_len, 0);
-                       make_unistr2(&(r_u->uni_dom_name[i]), doms[i], acct_name_len);
-               }
-
-               r_u->num_entries4 = num_sam_entries;
-       }
-       else
-       {
-               r_u->ptr_entries1 = 0;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->ptr_entries2 = 1;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_enum_domains");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx    ));
-       prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
-
-       if (r_u->ptr_entries1 != 0)
-       {
-               prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
-               prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
-               prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
-
-               if (ps->io)
-               {
-                       r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-                       r_u->uni_dom_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_dom_name[0]));
-               }
-
-               if ((r_u->sam == NULL || r_u->uni_dom_name == NULL) && r_u->num_entries2 != 0)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOMAINS\n"));
-                       r_u->num_entries4 = 0;
-                       r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       fstring tmp;
-                       slprintf(tmp, sizeof(tmp)-1, "dom[%d]", i);
-                       sam_io_sam_entry(tmp, &(r_u->sam[i]), ps, depth);
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       fstring tmp;
-                       slprintf(tmp, sizeof(tmp)-1, "dom[%d]", i);
-                       smb_io_unistr2(tmp, &(r_u->uni_dom_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
-                       prs_align(ps);
-               }
-
-               prs_align(ps);
-
-       }
-
-       prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAMR_Q_ENUM_DOM_GROUPS structure.
-********************************************************************/
-BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
-                               uint32 start_idx, uint32 size)
-{
-       if (q_e == NULL || pol == NULL) return False;
-
-       DEBUG(5,("make_samr_q_enum_dom_groups\n"));
-
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-
-       q_e->start_idx = start_idx;
-       q_e->max_size = size;
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (q_e == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
-       prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
-
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_ENUM_DOM_GROUPS structure.
-********************************************************************/
-BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
-               uint32 next_idx,
-               uint32 num_sam_entries, DOMAIN_GRP *grps, uint32 status)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_enum_dom_groups\n"));
-
-       r_u->next_idx = next_idx;
-       r_u->sam = NULL;
-       r_u->uni_grp_name = NULL;
-
-       if (num_sam_entries != 0)
-       {
-               r_u->ptr_entries1 = 1;
-               r_u->ptr_entries2 = 1;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->num_entries3 = num_sam_entries;
-
-               r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-               r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
-
-               if (r_u->sam == NULL || r_u->uni_grp_name == NULL)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
-                       return False;
-               }
-
-               for (i = 0; i < num_sam_entries; i++)
-               {
-                       int acct_name_len = strlen(grps[i].name);
-
-                       make_sam_entry(&(r_u->sam[i]),
-                                       acct_name_len,
-                                       grps[i].rid);
-
-                       make_unistr2(&(r_u->uni_grp_name[i]), grps[i].name, acct_name_len);
-               }
-
-               r_u->num_entries4 = num_sam_entries;
-       }
-       else
-       {
-               r_u->ptr_entries1 = 0;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->ptr_entries2 = 1;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx    ));
-       prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
-
-       if (r_u->ptr_entries1 != 0)
-       {
-               prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
-               prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
-               prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
-
-               if (ps->io)
-               {
-                       r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-                       r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
-               }
-
-               if ((r_u->sam == NULL || r_u->uni_grp_name == NULL) && r_u->num_entries2 != 0)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
-                       r_u->num_entries4 = 0;
-                       r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
-                       prs_align(ps);
-               }
-
-               prs_align(ps);
-
-       }
-
-       prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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, uint32 size)
-{
-       if (q_e == NULL || pol == NULL) return False;
-
-       DEBUG(5,("make_samr_q_enum_dom_aliases\n"));
-
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-
-       q_e->start_idx = start_idx;
-       q_e->max_size = size;
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (q_e == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
-       prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
-
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_ENUM_DOM_ALIASES structure.
-********************************************************************/
-BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
-               uint32 next_idx,
-               uint32 num_sam_entries, LOCAL_GRP *alss, uint32 status)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_enum_dom_aliases\n"));
-
-       r_u->next_idx = next_idx;
-       r_u->sam = NULL;
-       r_u->uni_grp_name = NULL;
-
-       if (num_sam_entries != 0)
-       {
-               r_u->ptr_entries1 = 1;
-               r_u->ptr_entries2 = 1;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->num_entries3 = num_sam_entries;
-
-               r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-               r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
-
-               if (r_u->sam == NULL || r_u->uni_grp_name == NULL)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
-                       return False;
-               }
-
-               for (i = 0; i < num_sam_entries; i++)
-               {
-                       int acct_name_len = strlen(alss[i].name);
-
-                       make_sam_entry(&(r_u->sam[i]),
-                                       acct_name_len,
-                                       alss[i].rid);
-
-                       make_unistr2(&(r_u->uni_grp_name[i]), alss[i].name, acct_name_len);
-               }
-
-               r_u->num_entries4 = num_sam_entries;
-       }
-       else
-       {
-               r_u->ptr_entries1 = 0;
-               r_u->num_entries2 = num_sam_entries;
-               r_u->ptr_entries2 = 1;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       uint32 i;
-
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx    ));
-       prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
-
-       if (r_u->ptr_entries1 != 0)
-       {
-               prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
-               prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
-               prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
-
-               if (ps->io)
-               {
-                       r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
-                       r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
-               }
-
-               if ((r_u->sam == NULL || r_u->uni_grp_name == NULL) && r_u->num_entries2 != 0)
-               {
-                       DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
-                       r_u->num_entries4 = 0;
-                       r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
-                       prs_align(ps);
-               }
-
-               prs_align(ps);
-
-       }
-
-       prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a ALIAS_INFO3 structure.
-********************************************************************/
-BOOL make_samr_alias_info3(ALIAS_INFO3 *al3, const char *acct_desc)
-{
-       int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
-       if (al3 == NULL) return False;
-
-       DEBUG(5,("make_samr_alias_info3\n"));
-
-       make_uni_hdr(&(al3->hdr_acct_desc), acct_len);
-       make_unistr2(&(al3->uni_acct_desc), acct_desc, acct_len);
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_alias_info3(char *desc,  ALIAS_INFO3 *al3, prs_struct *ps, int depth)
-{
-       if (al3 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_alias_info3");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_unihdr ("hdr_acct_desc", &(al3->hdr_acct_desc) , ps, depth); 
-       smb_io_unistr2("uni_acct_desc", &(al3->uni_acct_desc), al3->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_alias_info_ctr(char *desc,  ALIAS_INFO_CTR *ctr, prs_struct *ps, int depth)
-{
-       if (ctr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_alias_info_ctr");
-       depth++;
-
-       prs_uint16("switch_value1", ps, depth, &(ctr->switch_value1));
-       prs_uint16("switch_value2", ps, depth, &(ctr->switch_value2));
-
-       switch (ctr->switch_value1)
-       {
-               case 3:
-               {
-                       samr_io_alias_info3("alias_info3", &(ctr->alias.info3), ps, depth);
-                       break;
-               }
-               default:
-               {
-                       DEBUG(4,("samr_alias_info_ctr: unsupported switch level\n"));
-                       break;
-               }
-       }
-
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_Q_QUERY_ALIASINFO structure.
-********************************************************************/
-BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
-                               POLICY_HND *pol,
-                               uint16 switch_level)
-{
-       if (q_e == NULL || pol == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_aliasinfo\n"));
-
-       memcpy(&(q_e->pol), pol, sizeof(*pol));
-
-       q_e->switch_level = switch_level;
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_query_aliasinfo(char *desc,  SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
-{
-       if (q_e == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_QUERY_ALIASINFO structure.
-********************************************************************/
-BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, ALIAS_INFO_CTR *ctr,
-               uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_aliasinfo\n"));
-
-       r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
-       r_u->ctr = ctr;
-       r_u->status = status;
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_aliasinfo(char *desc,  SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("ptr", ps, depth, &(r_u->ptr));
-       
-       if (r_u->ptr != 0)
-       {
-               samr_alias_info_ctr("ctr", r_u->ctr, ps, depth);
-       }
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_Q_SET_ALIASINFO structure.
-********************************************************************/
-BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO *q_u, POLICY_HND *hnd,
-                               ALIAS_INFO_CTR *ctr)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_set_aliasinfo\n"));
-
-       memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
-       q_u->ctr = ctr;
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_set_aliasinfo(char *desc,  SAMR_Q_SET_ALIASINFO *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_set_aliasinfo");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
-       samr_alias_info_ctr("ctr", q_u->ctr, ps, depth);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_set_aliasinfo(char *desc,  SAMR_R_SET_ALIASINFO *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_set_aliasinfo");
-       depth++;
-
-       prs_align(ps);
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-
-/*******************************************************************
-makes a SAMR_Q_QUERY_USERALIASES structure.
-********************************************************************/
-BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
-                               const POLICY_HND *hnd,
-                               uint32 *ptr_sid, DOM_SID2 *sid)
-{
-       if (q_u == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_useraliases\n"));
-
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
-
-       q_u->num_sids1 = 1;
-       q_u->ptr = 1;
-       q_u->num_sids2 = 1;
-
-       q_u->ptr_sid = ptr_sid;
-       q_u->sid = sid;
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       fstring tmp;
-       uint32 i;
-
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_useraliases");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("num_sids1", ps, depth, &(q_u->num_sids1));
-       prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
-       prs_uint32("num_sids2", ps, depth, &(q_u->num_sids2));
-
-       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);
-               if (q_u->ptr_sid == NULL)
-               {
-                       samr_free_q_query_useraliases(q_u);
-                       return False;
-               }
-
-               q_u->sid = (DOM_SID2*)Realloc(q_u->sid,
-                                      sizeof(q_u->sid[0]) * q_u->num_sids2);
-               if (q_u->sid == NULL)
-               {
-                       samr_free_q_query_useraliases(q_u);
-                       return False;
-               }
-       }
-
-       for (i = 0; i < q_u->num_sids2; i++)
-       {
-               slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
-               prs_uint32(tmp, ps, depth, &(q_u->ptr_sid[i]));
-       }
-
-       for (i = 0; i < q_u->num_sids2; i++)
-       {
-               if (q_u->ptr_sid[i] != 0)
-               {
-                       slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
-                       smb_io_dom_sid2(tmp, &(q_u->sid[i]), ps, depth); 
-               }
-       }
-
-       prs_align(ps);
-
-       if (!ps->io)
-       {
-               /* storing.  memory no longer needed */
-               samr_free_q_query_useraliases(q_u);
-       }
-       return True;
-}
-
-/*******************************************************************
-frees memory in a SAMR_Q_QUERY_USERALIASES structure.
-********************************************************************/
-void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u)
-{
-       if (q_u->ptr_sid == NULL)
-       {
-               free(q_u->ptr_sid);
-               q_u->ptr_sid = NULL;
-       }
-
-       if (q_u->sid == NULL)
-       {
-               free(q_u->sid);
-               q_u->sid = NULL;
-       }
-}
-
-/*******************************************************************
-makes a SAMR_R_QUERY_USERALIASES structure.
-********************************************************************/
-BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u,
-               uint32 num_rids, uint32 *rid, uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_useraliases\n"));
-
-       if (status == 0x0)
-       {
-               r_u->num_entries  = num_rids;
-               r_u->ptr = 1;
-               r_u->num_entries2 = num_rids;
-
-               r_u->rid = rid;
-       }
-       else
-       {
-               r_u->num_entries  = 0;
-               r_u->ptr = 0;
-               r_u->num_entries2 = 0;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_useraliases(char *desc,  SAMR_R_QUERY_USERALIASES *r_u, prs_struct *ps, int depth)
-{
-       fstring tmp;
-       uint32 i;
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_query_useraliases");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
-       prs_uint32("ptr        ", ps, depth, &(r_u->ptr        ));
-       prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
-
-       if (r_u->num_entries != 0)
-       {
-               r_u->rid = (uint32*)Realloc(r_u->rid,
-                                      sizeof(r_u->rid[0]) * r_u->num_entries);
-               if (r_u->rid == NULL)
-               {
-                       samr_free_r_query_useraliases(r_u);
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_entries2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
-                       prs_uint32(tmp, ps, depth, &(r_u->rid[i]));
-               }
-       }
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       if (!ps->io)
-       {
-               /* storing.  memory no longer needed */
-               samr_free_r_query_useraliases(r_u);
-       }
-       return True;
-}
-
-/*******************************************************************
-frees memory in a SAMR_R_QUERY_USERALIASES structure.
-********************************************************************/
-void samr_free_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u)
-{
-       if (r_u->rid == NULL)
-       {
-               free(r_u->rid);
-               r_u->rid = NULL;
-       }
-}
-
-/*******************************************************************
-makes a SAMR_Q_OPEN_ALIAS structure.
-********************************************************************/
-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) return False;
-
-       DEBUG(5,("make_samr_q_open_alias\n"));
-
-       memcpy(&(q_u->dom_pol), pol, sizeof(q_u->dom_pol));
-
-       /* example values: 0x0000 0008 */
-       q_u->unknown_0 = unknown_0; 
-
-       q_u->rid_alias = rid; 
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_open_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("dom_pol", &(q_u->dom_pol), ps, depth); 
-
-       prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
-       prs_uint32("rid_alias", ps, depth, &(q_u->rid_alias));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_open_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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,
-               uint32 num_rids, uint32 *rid)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_unknwon_12\n"));
-
-       memcpy(&(q_u->pol), pol, sizeof(*pol));
-
-       q_u->num_rids1 = num_rids;
-       q_u->flags     = flags;
-       q_u->ptr       = 0;
-       q_u->num_rids2 = num_rids;
-       q_u->rid = rid;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_lookup_rids(char *desc,  SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-       fstring tmp;
-
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_lookup_rids");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("num_rids1", ps, depth, &(q_u->num_rids1));
-       prs_uint32("flags    ", ps, depth, &(q_u->flags    ));
-       prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
-       prs_uint32("num_rids2", ps, depth, &(q_u->num_rids2));
-
-       if (q_u->num_rids2 != 0)
-       {
-               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);
-                       return False;
-               }
-       }
-
-       for (i = 0; i < q_u->num_rids2; i++)
-       {
-               slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
-               prs_uint32(tmp, ps, depth, &(q_u->rid[i]));
-       }
-
-       prs_align(ps);
-
-       if (!ps->io)
-       {
-               /* storing.  don't need memory any more */
-               samr_free_q_lookup_rids(q_u);
-       }
-
-       return True;
-}
-
-/*******************************************************************
-frees a structure.
-********************************************************************/
-void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u)
-{
-       if (q_u->rid != NULL)
-       {
-               free(q_u->rid);
-               q_u->rid = NULL;
-       }
-}
-
-
-/*******************************************************************
-makes a SAMR_R_LOOKUP_RIDS structure.
-********************************************************************/
-BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
-               uint32 num_names, fstring *name, uint8 *type,
-               uint32 status)
-{
-       uint32 i;
-       if (r_u == NULL || name == NULL || type == NULL) return False;
-
-       DEBUG(5,("make_samr_r_lookup_rids\n"));
-
-       if (status == 0x0)
-       {
-               r_u->num_names1 = num_names;
-               r_u->ptr_names  = 1;
-               r_u->num_names2 = num_names;
-
-               r_u->num_types1 = num_names;
-               r_u->ptr_types  = 1;
-               r_u->num_types2 = num_names;
-
-               if (num_names != 0)
-               {
-                       r_u->hdr_name = (UNIHDR*)malloc(num_names * sizeof(r_u->hdr_name[0]));
-                       if (r_u->hdr_name == NULL)
-                       {
-                               samr_free_r_lookup_rids(r_u);
-                               return False;
-                       }
-                       r_u->uni_name = (UNISTR2*)malloc(num_names * sizeof(r_u->uni_name[0]));
-                       if (r_u->uni_name == NULL)
-                       {
-                               samr_free_r_lookup_rids(r_u);
-                               return False;
-                       }
-                       r_u->type = (uint32*)malloc(r_u->num_types2 * sizeof(r_u->type[0]));
-                       if (r_u->type == NULL)
-                       {
-                               samr_free_r_lookup_rids(r_u);
-                               return False;
-                       }
-               }
-
-               for (i = 0; i < num_names; i++)
-               {
-                       int len = name[i] != NULL ? strlen(name[i]) : 0;
-                       DEBUG(10,("name[%d]:%s\ttype:%d\n",
-                                  i, name[i], type[i]));
-                       make_uni_hdr(&(r_u->hdr_name[i]), len);
-                       make_unistr2(&(r_u->uni_name[i]), name[i], len);
-                       r_u->type[i] = type[i];
-               }
-       }
-       else
-       {
-               r_u->num_names1 = num_names;
-               r_u->ptr_names  = 0;
-               r_u->num_names2 = num_names;
-
-               r_u->num_types1 = num_names;
-               r_u->ptr_types  = 0;
-               r_u->num_types2 = num_names;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-       fstring tmp;
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_lookup_rids");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_names1", ps, depth, &(r_u->num_names1));
-       prs_uint32("ptr_names ", ps, depth, &(r_u->ptr_names ));
-       prs_uint32("num_names2", ps, depth, &(r_u->num_names2));
-
-       if (r_u->ptr_names != 0 && r_u->num_names1 != 0)
-       {
-               r_u->hdr_name = (UNIHDR*)Realloc(r_u->hdr_name,
-                                  r_u->num_names2 * sizeof(r_u->hdr_name[0]));
-               if (r_u->hdr_name == NULL)
-               {
-                       return False;
-               }
-
-               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);
-                       return False;
-               }
-               for (i = 0; i < r_u->num_names2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "hdr[%02d]  ", i);
-                       smb_io_unihdr ("", &(r_u->hdr_name[i]), ps, depth); 
-               }
-               for (i = 0; i < r_u->num_names2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "str[%02d]  ", i);
-                       smb_io_unistr2("", &(r_u->uni_name[i]), r_u->hdr_name[i].buffer, ps, depth); 
-                       prs_align(ps);
-               }
-       }
-
-       prs_align(ps);
-
-       prs_uint32("num_types1", ps, depth, &(r_u->num_types1));
-       prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types ));
-       prs_uint32("num_types2", ps, depth, &(r_u->num_types2));
-
-       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]));
-               if (r_u->type == NULL)
-               {
-                       if (r_u->uni_name != NULL)
-                       {
-                               free(r_u->uni_name);
-                       }
-                       if (r_u->hdr_name != NULL)
-                       {
-                               free(r_u->hdr_name);
-                       }
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_types2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
-                       prs_uint32(tmp, ps, depth, &(r_u->type[i]));
-               }
-       }
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       if (!ps->io)
-       {
-               /* storing.  don't need memory any more */
-               samr_free_r_lookup_rids(r_u);
-       }
-
-       return True;
-}
-
-/*******************************************************************
-frees a structure.
-********************************************************************/
-void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u)
-{
-       if (r_u->uni_name != NULL)
-       {
-               free(r_u->uni_name);
-               r_u->uni_name = NULL;
-       }
-       if (r_u->hdr_name != NULL)
-       {
-               free(r_u->hdr_name);
-               r_u->hdr_name = NULL;
-       }
-       if (r_u->type != NULL)
-       {
-               free(r_u->type);
-               r_u->type = NULL;
-       }
-}
-
-/*******************************************************************
-makes a SAMR_Q_OPEN_ALIAS structure.
-********************************************************************/
-BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u, POLICY_HND *hnd)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_delete_alias\n"));
-
-       memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_delete_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_delete_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(r_u->pol), ps, depth); 
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_create_dom_alias\n"));
-
-       memcpy(&(q_u->dom_pol), hnd, sizeof(q_u->dom_pol));
-
-       make_uni_hdr(&(q_u->hdr_acct_desc), acct_len);
-       make_unistr2(&(q_u->uni_acct_desc), acct_desc, acct_len);
-
-       q_u->unknown_1 = 0x001f;
-       q_u->unknown_2 = 0x000f;
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_create_dom_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("dom_pol", &(q_u->dom_pol), ps, depth); 
-
-       smb_io_unihdr ("hdr_acct_desc", &(q_u->hdr_acct_desc) , ps, depth); 
-       smb_io_unistr2("uni_acct_desc", &(q_u->uni_acct_desc), q_u->hdr_acct_desc.buffer, ps, depth);
-       prs_align(ps);
-
-       prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
-       prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAMR_R_CREATE_DOM_ALIAS structure.
-********************************************************************/
-BOOL make_samr_r_create_dom_alias(SAMR_R_CREATE_DOM_ALIAS *r_u, POLICY_HND *pol,
-               uint32 rid, uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_create_dom_alias\n"));
-
-       memcpy(&(r_u->alias_pol), pol, sizeof(*pol));
-       r_u->rid    = rid   ;
-       r_u->status = status;
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_create_dom_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(r_u->alias_pol), ps, depth); 
-       prs_uint32("rid", ps, depth, &(r_u->rid));
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_add_aliasmem\n"));
-
-       memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
-       make_dom_sid2(&q_u->sid, sid);
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_add_aliasmem(char *desc,  SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_add_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd ("alias_pol", &(q_u->alias_pol), ps, depth); 
-       smb_io_dom_sid2("sid      ", &(q_u->sid      ), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_add_aliasmem(char *desc,  SAMR_R_ADD_ALIASMEM *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_add_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_del_aliasmem\n"));
-
-       memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
-       make_dom_sid2(&q_u->sid, sid);
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_del_aliasmem(char *desc,  SAMR_Q_DEL_ALIASMEM *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_del_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
-       smb_io_dom_sid2("sid      ", &(q_u->sid      ), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_del_aliasmem(char *desc,  SAMR_R_DEL_ALIASMEM *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_del_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (q_c == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_delete_dom_alias\n"));
-
-       memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_delete_dom_alias");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAMR_R_DELETE_DOM_ALIAS structure.
-********************************************************************/
-BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS *r_u,
-               uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_delete_dom_alias\n"));
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_delete_dom_alias");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_Q_QUERY_ALIASMEM structure.
-********************************************************************/
-BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c,
-                               const POLICY_HND *hnd)
-{
-       if (q_c == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_aliasmem\n"));
-
-       memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_query_aliasmem(char *desc,  SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAMR_R_QUERY_ALIASMEM structure.
-********************************************************************/
-BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
-               uint32 num_sids, DOM_SID2 *sid, uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_aliasmem\n"));
-
-       if (status == 0x0)
-       {
-               r_u->num_sids  = num_sids;
-               r_u->ptr       = (num_sids != 0) ? 1 : 0;
-               r_u->num_sids1 = num_sids;
-
-               r_u->sid = sid;
-       }
-       else
-       {
-               r_u->ptr      = 0;
-               r_u->num_sids = 0;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_aliasmem(char *desc,  SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-       uint32 ptr_sid[MAX_LOOKUP_SIDS];
-
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_query_aliasmem");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_sids ", ps, depth, &(r_u->num_sids));
-       prs_uint32("ptr", ps, depth, &(r_u->ptr));
-
-       if (r_u->ptr != 0)
-       {
-               SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids);
-
-               if (r_u->num_sids != 0)
-               {
-                       prs_uint32("num_sids1", ps, depth, &(r_u->num_sids1));
-
-                       for (i = 0; i < r_u->num_sids1; i++)
-                       {
-                               ptr_sid[i] = 1;
-                               prs_uint32("", ps, depth, &(ptr_sid[i]));
-                       }
-                       for (i = 0; i < r_u->num_sids1; i++)
-                       {
-                               if (ptr_sid[i] != 0)
-                               {
-                                       smb_io_dom_sid2("", &(r_u->sid[i]), ps, depth);
-                               }
-                       }
-               }
-       }
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAMR_Q_LOOKUP_NAMES structure.
-********************************************************************/
-BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
-               POLICY_HND *pol, uint32 flags,
-               uint32 num_names, char **name)
-{
-       uint32 i;
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_lookup_names\n"));
-
-       memcpy(&(q_u->pol), pol, sizeof(*pol));
-
-       q_u->num_names1 = num_names;
-       q_u->flags     = flags;
-       q_u->ptr       = 0;
-       q_u->num_names2 = num_names;
-
-       for (i = 0; i < num_names; i++)
-       {
-               int len_name = name[i] != NULL ? strlen(name[i]) : 0;
-               make_uni_hdr(&(q_u->hdr_name[i]), len_name);  /* unicode header for user_name */
-               make_unistr2(&(q_u->uni_name[i]), name[i], len_name);  /* unicode string for machine account */
-       }
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_lookup_names(char *desc,  SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("num_names1", ps, depth, &(q_u->num_names1));
-       prs_uint32("flags     ", ps, depth, &(q_u->flags     ));
-       prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
-       prs_uint32("num_names2", ps, depth, &(q_u->num_names2));
-
-       SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
-
-       for (i = 0; i < q_u->num_names2; i++)
-       {
-               smb_io_unihdr ("", &(q_u->hdr_name[i]), ps, depth); 
-       }
-       for (i = 0; i < q_u->num_names2; i++)
-       {
-               smb_io_unistr2("", &(q_u->uni_name[i]), q_u->hdr_name[i].buffer, ps, depth); 
-               prs_align(ps);
-       }
-
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_LOOKUP_NAMES structure.
-********************************************************************/
-BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
-               uint32 num_rids, uint32 *rid, uint8 *type, uint32 status)
-{
-       uint32 i;
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("make_samr_r_lookup_names\n"));
-
-       if (status == 0x0)
-       {
-               r_u->num_types1 = num_rids;
-               r_u->ptr_types  = 1;
-               r_u->num_types2 = num_rids;
-
-               r_u->num_rids1 = num_rids;
-               r_u->ptr_rids  = 1;
-               r_u->num_rids2 = num_rids;
-
-               SMB_ASSERT_ARRAY(r_u->rid, num_rids);
-
-               for (i = 0; i < num_rids; i++)
-               {
-                       r_u->rid [i] = rid [i];
-                       r_u->type[i] = type[i];
-               }
-       }
-       else
-       {
-               r_u->num_types1 = 0;
-               r_u->ptr_types  = 0;
-               r_u->num_types2 = 0;
-
-               r_u->num_rids1 = 0;
-               r_u->ptr_rids  = 0;
-               r_u->num_rids2 = 0;
-       }
-
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_lookup_names(char *desc,  SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
-{
-       uint32 i;
-       fstring tmp;
-
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_rids1", ps, depth, &(r_u->num_rids1));
-       prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids ));
-
-       if (r_u->ptr_rids != 0)
-       {
-               prs_uint32("num_rids2", ps, depth, &(r_u->num_rids2));
-
-               if (r_u->num_rids2 != r_u->num_rids1)
-               {
-                       /* RPC fault */
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_rids2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "rid[%02d]  ", i);
-                       prs_uint32(tmp, ps, depth, &(r_u->rid[i]));
-               }
-       }
-
-       prs_uint32("num_types1", ps, depth, &(r_u->num_types1));
-       prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types ));
-
-       if (r_u->ptr_types != 0)
-       {
-               prs_uint32("num_types2", ps, depth, &(r_u->num_types2));
-
-               if (r_u->num_types2 != r_u->num_types1)
-               {
-                       /* RPC fault */
-                       return False;
-               }
-
-               for (i = 0; i < r_u->num_types2; i++)
-               {
-                       slprintf(tmp, sizeof(tmp) - 1, "type[%02d]  ", i);
-                       prs_uint32(tmp, ps, depth, &(r_u->type[i]));
-               }
-       }
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
-                               const POLICY_HND *pol,
-                               uint32 unk_0, uint32 rid)
-{
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("samr_make_samr_q_open_user\n"));
-
-       memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
-       
-       q_u->unknown_0 = unk_0;
-       q_u->user_rid  = rid;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_open_user(char *desc,  SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_open_user");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
-       prs_uint32("user_rid ", ps, depth, &(q_u->user_rid ));
-
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_open_user(char *desc,  SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_open_user");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
-                               POLICY_HND *pol,
-                               const char *name,
-                               uint16 acb_info, uint32 unk_1)
-{
-       int len_name;
-       if (q_u == NULL) return False;
-       len_name = strlen(name);
-
-       DEBUG(5,("samr_make_samr_q_create_user\n"));
-
-       memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
-       
-       make_uni_hdr(&(q_u->hdr_name), len_name);  
-       make_unistr2(&(q_u->uni_name), name, len_name);
-
-       q_u->acb_info = acb_info;
-       q_u->unknown_1 = unk_1;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_create_user(char *desc,  SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_create_user");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth); 
-       prs_align(ps);
-
-       smb_io_unihdr ("unihdr", &(q_u->hdr_name), ps, depth); 
-       smb_io_unistr2("unistr2", &(q_u->uni_name), q_u->hdr_name.buffer, ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("acb_info", ps, depth, &(q_u->acb_info));
-       prs_align(ps);
-       prs_uint32("unknown_1", ps, depth, &(q_u->unknown_1));
-
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL make_samr_r_create_user(SAMR_R_CREATE_USER *r_u,
-                               POLICY_HND *user_pol,
-                               uint32 unk_0, uint32 user_rid,
-                               uint32 status)
-{
-       if (r_u == NULL) return False;
-
-       DEBUG(5,("samr_make_samr_r_create_user\n"));
-
-       memcpy(&r_u->user_pol, user_pol, sizeof(r_u->user_pol));
-       
-       r_u->unknown_0 = unk_0;
-       r_u->user_rid = user_rid;
-       r_u->status = status;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_create_user(char *desc,  SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_create_user");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
-       prs_uint32("user_rid ", ps, depth, &(r_u->user_rid ));
-       prs_uint32("status", ps, depth, &(r_u->status));
-
-       return True;
-}
-
-/*******************************************************************
-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)
-{
-       if (q_u == NULL || hnd == NULL) return False;
-
-       DEBUG(5,("make_samr_q_query_userinfo\n"));
-
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
-       q_u->switch_value = switch_value;
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_q_query_userinfo(char *desc,  SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
-{
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
-       depth++;
-
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("switch_value", ps, depth, &(q_u->switch_value)); /* 0x0015 or 0x0011 */
-
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a LOGON_HRS structure.
-********************************************************************/
-static BOOL sam_io_logon_hrs(char *desc,  LOGON_HRS *hrs, prs_struct *ps, int depth)
-{
-       if (hrs == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_logon_hrs");
-       depth++;
-
-       prs_align(ps);
-       
-       prs_uint32 (       "len  ", ps, depth, &(hrs->len ));
-
-       if (hrs->len > 64)
-       {
-               DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
-               hrs->len = 64;
-       }
-
-       prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len);
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAM_USER_INFO_10 structure.
-********************************************************************/
-BOOL make_sam_user_info10(SAM_USER_INFO_10 *usr,
-                               uint32 acb_info)
-{
-       if (usr == NULL) return False;
-
-       DEBUG(5,("make_sam_user_info10\n"));
-
-       usr->acb_info = acb_info;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL sam_io_user_info10(char *desc,  SAM_USER_INFO_10 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_user_info10");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("acb_info", ps, depth, &(usr->acb_info));
-
-       return True;
-}
-
-/*******************************************************************
-makes a SAM_USER_INFO_11 structure.
-********************************************************************/
-BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
-                               NTTIME *expiry,
-                               char *mach_acct,
-                               uint32 rid_user,
-                               uint32 rid_group,
-                               uint16 acct_ctrl)
-                               
-{
-       int len_mach_acct;
-       if (usr == NULL || expiry == NULL || mach_acct == NULL) return False;
-
-       DEBUG(5,("make_sam_user_info11\n"));
-
-       len_mach_acct = strlen(mach_acct);
-
-       memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */
-       bzero(usr->padding_1, sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
-
-       make_uni_hdr(&(usr->hdr_mach_acct), len_mach_acct);  /* unicode header for machine account */
-       usr->padding_2 = 0;               /* 0 - padding 4 bytes */
-
-       usr->ptr_1        = 1;            /* pointer */
-       bzero(usr->padding_3, sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
-       usr->padding_4    = 0;            /* 0 - padding 4 bytes */
-
-       usr->ptr_2        = 1;            /* pointer */
-       usr->padding_5    = 0;            /* 0 - padding 4 bytes */
-
-       usr->ptr_3        = 1;          /* pointer */
-       bzero(usr->padding_6, sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
-
-       usr->rid_user     = rid_user; 
-       usr->rid_group    = rid_group;
-
-       usr->acct_ctrl    = acct_ctrl;
-       usr->unknown_3    = 0x0000;
-
-       usr->unknown_4    = 0x003f;       /* 0x003f      - 16 bit unknown */
-       usr->unknown_5    = 0x003c;       /* 0x003c      - 16 bit unknown */
-
-       bzero(usr->padding_7, sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
-       usr->padding_8    = 0;            /* 0 - padding 4 bytes */
-       
-       make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct);  /* unicode string for machine account */
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL sam_io_user_info11(char *desc,  SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_unknown_11");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0)); 
-
-       smb_io_time("time", &(usr->expiry), ps, depth); 
-
-       prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1));
-
-       smb_io_unihdr ("unihdr", &(usr->hdr_mach_acct), ps, depth); 
-       prs_uint32(        "padding_2", ps, depth, &(usr->padding_2));
-
-       prs_uint32(        "ptr_1    ", ps, depth, &(usr->ptr_1    ));
-       prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3));
-       prs_uint32(        "padding_4", ps, depth, &(usr->padding_4));
-
-       prs_uint32(        "ptr_2    ", ps, depth, &(usr->ptr_2    ));
-       prs_uint32(        "padding_5", ps, depth, &(usr->padding_5));
-
-       prs_uint32(        "ptr_3    ", ps, depth, &(usr->ptr_3    ));
-       prs_uint8s (False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6));
-
-       prs_uint32(        "rid_user ", ps, depth, &(usr->rid_user ));
-       prs_uint32(        "rid_group", ps, depth, &(usr->rid_group));
-       prs_uint16(        "acct_ctrl", ps, depth, &(usr->acct_ctrl));
-       prs_uint16(        "unknown_3", ps, depth, &(usr->unknown_3));
-       prs_uint16(        "unknown_4", ps, depth, &(usr->unknown_4));
-       prs_uint16(        "unknown_5", ps, depth, &(usr->unknown_5));
-
-       prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7));
-       prs_uint32(        "padding_8", ps, depth, &(usr->padding_8));
-       
-       smb_io_unistr2("unistr2", &(usr->uni_mach_acct), True, ps, depth); 
-       prs_align(ps);
-
-       prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
-
-       return True;
-}
-
-/*************************************************************************
- make_sam_user_infoa
-
- unknown_3 = 0x09f8 27fa
- unknown_5 = 0x0001 0000
- unknown_6 = 0x0000 04ec 
-
- *************************************************************************/
-BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
-       char newpass[516], uint16 passlen)
-{
-       memcpy(usr->pass, newpass, sizeof(usr->pass));
-       usr->unk_0 = passlen;
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_user_info24");
-       depth++;
-
-       prs_align(ps);
-       
-       prs_uint8s (False, "password", ps, depth, usr->pass, sizeof(usr->pass));
-       prs_uint16("unk_0", ps, depth, &(usr->unk_0));      /* unknown */
-       prs_align(ps);
-
-       return True;
-}
-
-
-/*************************************************************************
- make_sam_user_info23
-
- unknown_3 = 0x09f8 27fa
- unknown_5 = 0x0001 0000
- unknown_6 = 0x0000 04ec 
-
- *************************************************************************/
-BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
-
-       NTTIME *logon_time, /* all zeros */
-       NTTIME *logoff_time, /* all zeros */
-       NTTIME *kickoff_time, /* all zeros */
-       NTTIME *pass_last_set_time, /* all zeros */
-       NTTIME *pass_can_change_time, /* all zeros */
-       NTTIME *pass_must_change_time, /* all zeros */
-
-       UNISTR2 *user_name, /* NULL */
-       UNISTR2 *full_name,
-       UNISTR2 *home_dir,
-       UNISTR2 *dir_drive,
-       UNISTR2 *log_scr,
-       UNISTR2 *prof_path,
-       UNISTR2 *desc,
-       UNISTR2 *wkstas,
-       UNISTR2 *unk_str,
-       UNISTR2 *mung_dial,
-
-       uint32 user_rid, /* 0x0000 0000 */
-       uint32 group_rid,
-       uint16 acb_info, 
-
-       uint32 unknown_3,
-       uint16 logon_divs,
-       LOGON_HRS *hrs,
-       uint32 unknown_5,
-       char newpass[516],
-       uint32 unknown_6)
-{
-       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;
-       int len_home_dir     = home_dir  != NULL ? home_dir ->uni_str_len : 0;
-       int len_dir_drive    = dir_drive != NULL ? dir_drive->uni_str_len : 0;
-       int len_logon_script = log_scr   != NULL ? log_scr  ->uni_str_len : 0;
-       int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
-       int len_description  = desc      != NULL ? desc     ->uni_str_len : 0;
-       int len_workstations = wkstas    != NULL ? wkstas   ->uni_str_len : 0;
-       int len_unknown_str  = unk_str   != NULL ? unk_str  ->uni_str_len : 0;
-       int len_munged_dial  = mung_dial != NULL ? mung_dial->uni_str_len : 0;
-
-       usr->logon_time            = *logon_time; /* all zeros */
-       usr->logoff_time           = *logoff_time; /* all zeros */
-       usr->kickoff_time          = *kickoff_time; /* all zeros */
-       usr->pass_last_set_time    = *pass_last_set_time; /* all zeros */
-       usr->pass_can_change_time  = *pass_can_change_time; /* all zeros */
-       usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
-
-       make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   ); /* NULL */
-       make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   );
-       make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    );
-       make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   );
-       make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
-       make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
-       make_uni_hdr(&(usr->hdr_acct_desc   ), len_description );
-       make_uni_hdr(&(usr->hdr_workstations), len_workstations);
-       make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
-       make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
-
-       bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
-       bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
-
-       usr->user_rid  = user_rid; /* 0x0000 0000 */
-       usr->group_rid = group_rid;
-       usr->acb_info = acb_info;
-       usr->unknown_3 = unknown_3; /* 09f8 27fa */
-
-       usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
-       usr->ptr_logon_hrs = hrs ? 1 : 0;
-
-       bzero(usr->padding1, sizeof(usr->padding1));
-
-       usr->unknown_5 = unknown_5; /* 0x0001 0000 */
-
-       memcpy(usr->pass, newpass, sizeof(usr->pass));
-
-       copy_unistr2(&(usr->uni_user_name   ), user_name);
-       copy_unistr2(&(usr->uni_full_name   ), full_name);
-       copy_unistr2(&(usr->uni_home_dir    ), home_dir );
-       copy_unistr2(&(usr->uni_dir_drive   ), dir_drive);
-       copy_unistr2(&(usr->uni_logon_script), log_scr  );
-       copy_unistr2(&(usr->uni_profile_path), prof_path);
-       copy_unistr2(&(usr->uni_acct_desc   ), desc     );
-       copy_unistr2(&(usr->uni_workstations), wkstas   );
-       copy_unistr2(&(usr->uni_unknown_str ), unk_str  );
-       copy_unistr2(&(usr->uni_munged_dial ), mung_dial);
-
-       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));
-       }
-
-       return True;
-}
-
-/*************************************************************************
- make_sam_user_info23
-
- unknown_3 = 0x09f8 27fa
- unknown_5 = 0x0001 0000
- unknown_6 = 0x0000 04ec 
-
- *************************************************************************/
-BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
-
-       NTTIME *logon_time, /* all zeros */
-       NTTIME *logoff_time, /* all zeros */
-       NTTIME *kickoff_time, /* all zeros */
-       NTTIME *pass_last_set_time, /* all zeros */
-       NTTIME *pass_can_change_time, /* all zeros */
-       NTTIME *pass_must_change_time, /* all zeros */
-
-       char *user_name, /* NULL */
-       char *full_name,
-       char *home_dir,
-       char *dir_drive,
-       char *log_scr,
-       char *prof_path,
-       char *desc,
-       char *wkstas,
-       char *unk_str,
-       char *mung_dial,
-
-       uint32 user_rid, /* 0x0000 0000 */
-       uint32 group_rid,
-       uint16 acb_info, 
-
-       uint32 unknown_3,
-       uint16 logon_divs,
-       LOGON_HRS *hrs,
-       uint32 unknown_5,
-       char newpass[516],
-       uint32 unknown_6)
-{
-       int len_user_name    = user_name != NULL ? strlen(user_name) : 0;
-       int len_full_name    = full_name != NULL ? strlen(full_name) : 0;
-       int len_home_dir     = home_dir  != NULL ? strlen(home_dir ) : 0;
-       int len_dir_drive    = dir_drive != NULL ? strlen(dir_drive) : 0;
-       int len_logon_script = log_scr   != NULL ? strlen(log_scr  ) : 0;
-       int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
-       int len_description  = desc      != NULL ? strlen(desc     ) : 0;
-       int len_workstations = wkstas    != NULL ? strlen(wkstas   ) : 0;
-       int len_unknown_str  = unk_str   != NULL ? strlen(unk_str  ) : 0;
-       int len_munged_dial  = mung_dial != NULL ? strlen(mung_dial) : 0;
-
-       usr->logon_time            = *logon_time; /* all zeros */
-       usr->logoff_time           = *logoff_time; /* all zeros */
-       usr->kickoff_time          = *kickoff_time; /* all zeros */
-       usr->pass_last_set_time    = *pass_last_set_time; /* all zeros */
-       usr->pass_can_change_time  = *pass_can_change_time; /* all zeros */
-       usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
-
-       make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   ); /* NULL */
-       make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   );
-       make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    );
-       make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   );
-       make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
-       make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
-       make_uni_hdr(&(usr->hdr_acct_desc   ), len_description );
-       make_uni_hdr(&(usr->hdr_workstations), len_workstations);
-       make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
-       make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
-
-       bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
-       bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
-
-       usr->user_rid  = user_rid; /* 0x0000 0000 */
-       usr->group_rid = group_rid;
-       usr->acb_info = acb_info;
-       usr->unknown_3 = unknown_3; /* 09f8 27fa */
-
-       usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
-       usr->ptr_logon_hrs = hrs ? 1 : 0;
-
-       bzero(usr->padding1, sizeof(usr->padding1));
-
-       usr->unknown_5 = unknown_5; /* 0x0001 0000 */
-
-       memcpy(usr->pass, newpass, sizeof(usr->pass));
-
-       make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   ); /* NULL */
-       make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
-       make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
-       make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
-       make_unistr2(&(usr->uni_logon_script), log_scr, len_logon_script);
-       make_unistr2(&(usr->uni_profile_path), prof_path, len_profile_path);
-       make_unistr2(&(usr->uni_acct_desc ), desc , len_description );
-       make_unistr2(&(usr->uni_workstations), wkstas, len_workstations);
-       make_unistr2(&(usr->uni_unknown_str ), unk_str , len_unknown_str );
-       make_unistr2(&(usr->uni_munged_dial ), mung_dial , len_munged_dial );
-
-       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));
-       }
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL sam_io_user_info16(char *desc,  SAM_USER_INFO_16 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_user_info16");
-       depth++;
-
-       prs_align(ps);
-       
-       prs_uint16("acb_info", ps, depth, &(usr->acb_info));
-       prs_align(ps);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL sam_io_user_info23(char *desc,  SAM_USER_INFO_23 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_user_info23");
-       depth++;
-
-       prs_align(ps);
-       
-       smb_io_time("logon_time           ", &(usr->logon_time)           , ps, depth);
-       smb_io_time("logoff_time          ", &(usr->logoff_time)          , ps, depth); 
-       smb_io_time("kickoff_time         ", &(usr->kickoff_time)         , ps, depth); 
-       smb_io_time("pass_last_set_time   ", &(usr->pass_last_set_time)   , ps, depth); 
-       smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth); 
-       smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth); 
-
-       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 */
-       smb_io_unihdr("hdr_home_dir    ", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
-       smb_io_unihdr("hdr_dir_drive   ", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive */
-       smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
-       smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
-       smb_io_unihdr("hdr_acct_desc   ", &(usr->hdr_acct_desc  ) , ps, depth); /* account desc */
-       smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* wkstas user can log on from */
-       smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
-       smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* wkstas user can log on from */
-
-       prs_uint8s (False, "lm_pwd        ", ps, depth, usr->lm_pwd   , sizeof(usr->lm_pwd   ));
-       prs_uint8s (False, "nt_pwd        ", ps, depth, usr->nt_pwd   , sizeof(usr->nt_pwd   ));
-
-       prs_uint32("user_rid      ", ps, depth, &(usr->user_rid     ));       /* User ID */
-       prs_uint32("group_rid     ", ps, depth, &(usr->group_rid    ));      /* Group ID */
-       prs_uint16("acb_info      ", ps, depth, &(usr->acb_info     ));      /* Group ID */
-       prs_align(ps);
-
-       prs_uint32("unknown_3     ", ps, depth, &(usr->unknown_3    ));
-       prs_uint16("logon_divs    ", ps, depth, &(usr->logon_divs   ));     /* logon divisions per week */
-       prs_align(ps);
-       prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
-       prs_uint8s (False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1));
-       prs_uint32("unknown_5     ", ps, depth, &(usr->unknown_5    ));
-
-       prs_uint8s (False, "password      ", ps, depth, usr->pass, sizeof(usr->pass));
-
-       /* here begins pointed-to data */
-
-       smb_io_unistr2("uni_user_name   ", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_full_name   ", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_home_dir    ", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_dir_drive   ", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_acct_desc   ", &(usr->uni_acct_desc   ), usr->hdr_acct_desc   .buffer, ps, depth); /* user desc unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
-       prs_align(ps);
-       smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
-       prs_align(ps);
-       smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
-       prs_align(ps);
-
-       prs_uint32("unknown_6     ", ps, depth, &(usr->unknown_6  ));
-       prs_uint32("padding4      ", ps, depth, &(usr->padding4   ));
-
-       if (usr->ptr_logon_hrs)
-       {
-               sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs)   , ps, depth);
-               prs_align(ps);
-       }
-
-       return True;
-}
-
-
-/*************************************************************************
- make_sam_user_info21
-
- unknown_3 = 0x00ff ffff
- unknown_5 = 0x0002 0000
- unknown_6 = 0x0000 04ec 
-
- *************************************************************************/
-BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
-
-       NTTIME *logon_time,
-       NTTIME *logoff_time,
-       NTTIME *kickoff_time,
-       NTTIME *pass_last_set_time,
-       NTTIME *pass_can_change_time,
-       NTTIME *pass_must_change_time,
-
-       char *user_name,
-       char *full_name,
-       char *home_dir,
-       char *dir_drive,
-       char *log_scr,
-       char *prof_path,
-       char *desc,
-       char *wkstas,
-       char *unk_str,
-       char *mung_dial,
-
-       uint32 user_rid,
-       uint32 group_rid,
-       uint16 acb_info, 
+       uint32 user_rid,
+       uint32 group_rid,
+       uint16 acb_info, 
 
        uint32 unknown_3,
        uint16 logon_divs,
@@ -5294,16 +2740,16 @@ BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
        uint32 unknown_5,
        uint32 unknown_6)
 {
-       int len_user_name    = user_name != NULL ? strlen(user_name) : 0;
-       int len_full_name    = full_name != NULL ? strlen(full_name) : 0;
-       int len_home_dir     = home_dir  != NULL ? strlen(home_dir ) : 0;
-       int len_dir_drive    = dir_drive != NULL ? strlen(dir_drive) : 0;
-       int len_logon_script = log_scr   != NULL ? strlen(log_scr  ) : 0;
-       int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
-       int len_description  = desc      != NULL ? strlen(desc     ) : 0;
-       int len_workstations = wkstas    != NULL ? strlen(wkstas   ) : 0;
-       int len_unknown_str  = unk_str   != NULL ? strlen(unk_str  ) : 0;
-       int len_munged_dial  = mung_dial != NULL ? strlen(mung_dial) : 0;
+       int len_user_name    = user_name    != NULL ? strlen(user_name   ) : 0;
+       int len_full_name    = full_name    != NULL ? strlen(full_name   ) : 0;
+       int len_home_dir     = home_dir     != NULL ? strlen(home_dir    ) : 0;
+       int len_dir_drive    = dir_drive    != NULL ? strlen(dir_drive   ) : 0;
+       int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
+       int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
+       int len_description  = description  != NULL ? strlen(description ) : 0;
+       int len_workstations = workstations != NULL ? strlen(workstations) : 0;
+       int len_unknown_str  = unknown_str  != NULL ? strlen(unknown_str ) : 0;
+       int len_munged_dial  = munged_dial  != NULL ? strlen(munged_dial ) : 0;
 
        usr->logon_time            = *logon_time;
        usr->logoff_time           = *logoff_time;
@@ -5312,19 +2758,19 @@ BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
        usr->pass_can_change_time  = *pass_can_change_time;
        usr->pass_must_change_time = *pass_must_change_time;
 
-       make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   );
-       make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   );
-       make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    );
-       make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   );
-       make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
-       make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
-       make_uni_hdr(&(usr->hdr_acct_desc   ), len_description );
-       make_uni_hdr(&(usr->hdr_workstations), len_workstations);
-       make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
-       make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
+       init_uni_hdr(&usr->hdr_user_name, len_user_name);
+       init_uni_hdr(&usr->hdr_full_name, len_full_name);
+       init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
+       init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+       init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
+       init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
+       init_uni_hdr(&usr->hdr_acct_desc, len_description);
+       init_uni_hdr(&usr->hdr_workstations, len_workstations);
+       init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
+       init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
 
-       bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
-       bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
+       memset((char *)usr->nt_pwd, '\0', sizeof(usr->nt_pwd));
+       memset((char *)usr->lm_pwd, '\0', sizeof(usr->lm_pwd));
 
        usr->user_rid  = user_rid;
        usr->group_rid = group_rid;
@@ -5335,807 +2781,659 @@ BOOL make_sam_user_info21(SAM_USER_INFO_21 *usr,
        usr->ptr_logon_hrs = hrs ? 1 : 0;
        usr->unknown_5 = unknown_5; /* 0x0002 0000 */
 
-       bzero(usr->padding1, sizeof(usr->padding1));
+       memset((char *)usr->padding1, '\0', sizeof(usr->padding1));
 
-       make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
-       make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
-       make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
-       make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
-       make_unistr2(&(usr->uni_logon_script), log_scr, len_logon_script);
-       make_unistr2(&(usr->uni_profile_path), prof_path, len_profile_path);
-       make_unistr2(&(usr->uni_acct_desc ), desc , len_description );
-       make_unistr2(&(usr->uni_workstations), wkstas, len_workstations);
-       make_unistr2(&(usr->uni_unknown_str ), unk_str , len_unknown_str );
-       make_unistr2(&(usr->uni_munged_dial ), mung_dial , len_munged_dial );
+       init_unistr2(&usr->uni_user_name, user_name, len_user_name);
+       init_unistr2(&usr->uni_full_name, full_name, len_full_name);
+       init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
+       init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
+       init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
+       init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
+       init_unistr2(&usr->uni_acct_desc, description, len_description);
+       init_unistr2(&usr->uni_workstations, workstations, len_workstations);
+       init_unistr2(&usr->uni_unknown_str, unknown_str, len_unknown_str);
+       init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
 
        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));
-       }
-
-       return True;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL sam_io_user_info21(char *desc,  SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
-{
-       if (usr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "sam_io_user_info21");
-       depth++;
-
-       prs_align(ps);
-       
-       smb_io_time("logon_time           ", &(usr->logon_time)           , ps, depth);
-       smb_io_time("logoff_time          ", &(usr->logoff_time)          , ps, depth); 
-       smb_io_time("kickoff_time         ", &(usr->kickoff_time)         , ps, depth); 
-       smb_io_time("pass_last_set_time   ", &(usr->pass_last_set_time)   , ps, depth); 
-       smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth); 
-       smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth); 
-
-       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 */
-       smb_io_unihdr("hdr_home_dir    ", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
-       smb_io_unihdr("hdr_dir_drive   ", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive */
-       smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
-       smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
-       smb_io_unihdr("hdr_acct_desc   ", &(usr->hdr_acct_desc  ) , ps, depth); /* account desc */
-       smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* wkstas user can log on from */
-       smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
-       smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* wkstas user can log on from */
-
-       prs_uint8s (False, "lm_pwd        ", ps, depth, usr->lm_pwd   , sizeof(usr->lm_pwd   ));
-       prs_uint8s (False, "nt_pwd        ", ps, depth, usr->nt_pwd   , sizeof(usr->nt_pwd   ));
-
-       prs_uint32("user_rid      ", ps, depth, &(usr->user_rid     ));       /* User ID */
-       prs_uint32("group_rid     ", ps, depth, &(usr->group_rid    ));      /* Group ID */
-       prs_uint16("acb_info      ", ps, depth, &(usr->acb_info     ));      /* Group ID */
-       prs_align(ps);
-
-       prs_uint32("unknown_3     ", ps, depth, &(usr->unknown_3    ));
-       prs_uint16("logon_divs    ", ps, depth, &(usr->logon_divs   ));     /* logon divisions per week */
-       prs_align(ps);
-       prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
-       prs_uint32("unknown_5     ", ps, depth, &(usr->unknown_5    ));
-
-       prs_uint8s (False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1));
-
-       /* here begins pointed-to data */
-
-       smb_io_unistr2("uni_user_name   ", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_full_name   ", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_home_dir    ", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_dir_drive   ", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_acct_desc   ", &(usr->uni_acct_desc   ), usr->hdr_acct_desc   .buffer, ps, depth); /* user desc unicode string */
-       prs_align(ps);
-       smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
-       prs_align(ps);
-       smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
-       prs_align(ps);
-       smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
-       prs_align(ps);
-
-       prs_uint32("unknown_6     ", ps, depth, &(usr->unknown_6  ));
-       prs_uint32("padding4      ", ps, depth, &(usr->padding4   ));
-
-       if (usr->ptr_logon_hrs)
-       {
-               sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs)   , ps, depth);
-               prs_align(ps);
-       }
-
-       return True;
-}
-
-
-/*******************************************************************
-makes a SAMR_R_QUERY_USERINFO structure.
-********************************************************************/
-BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
-                               uint16 switch_value, void *info, uint32 status)
-                               
-{
-       if (r_u == NULL || info == NULL) return False;
-
-       DEBUG(5,("make_samr_r_query_userinfo\n"));
-
-       r_u->ptr = 0;
-       r_u->switch_value = 0;
-
-       if (status == 0)
-       {
-               r_u->switch_value = switch_value;
-
-               switch (switch_value)
-               {
-                       case 0x10:
-                       {
-                               r_u->ptr = 1;
-                               r_u->info.id10 = (SAM_USER_INFO_10*)info;
-
-                               break;
-                       }
-
-                       case 0x11:
-                       {
-                               r_u->ptr = 1;
-                               r_u->info.id11 = (SAM_USER_INFO_11*)info;
-
-                               break;
-                       }
-
-                       case 21:
-                       {
-                               r_u->ptr = 1;
-                               r_u->info.id21 = (SAM_USER_INFO_21*)info;
-
-                               break;
-                       }
-
-                       case 23:
-                       {
-                               r_u->ptr = 1;
-                               r_u->info.id23 = (SAM_USER_INFO_23*)info;
-
-                               break;
-                       }
-
-                       case 24:
-                       {
-                               r_u->ptr = 1;
-                               r_u->info.id24 = (SAM_USER_INFO_24*)info;
-
-                               break;
-                       }
-
-                       default:
-                       {
-                               DEBUG(4,("make_samr_r_query_userinfo: unsupported switch level\n"));
-                               break;
-                       }
-               }
-       }
-
-       r_u->status = status;         /* return status */
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
-{
-       if (r_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("ptr         ", ps, depth, &(r_u->ptr         ));
-       prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
-       prs_align(ps);
-
-       if (r_u->ptr != 0 && r_u->switch_value != 0 && r_u->info.id != NULL)
-       {
-               switch (r_u->switch_value)
-               {
-                       case 0x10:
-                       {
-                               if (r_u->info.id10 != NULL)
-                               {
-                                       sam_io_user_info10("", r_u->info.id10, ps, depth);
-                               }
-                               else
-                               {
-                                       DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
-                                       return False;
-                               }
-                               break;
-                       }
-/*
-                       case 0x11:
-                       {
-                               if (r_u->info.id11 != NULL)
-                               {
-                                       sam_io_user_info11("", r_u->info.id11, ps, depth);
-                               }
-                               else
-                               {
-                                       DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
-                                       return False;
-                               }
-                               break;
-                       }
-*/
-                       case 21:
-                       {
-                               if (r_u->info.id21 != NULL)
-                               {
-                                       sam_io_user_info21("", r_u->info.id21, ps, depth);
-                               }
-                               else
-                               {
-                                       DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
-                                       return False;
-                               }
-                               break;
-                       }
-                       case 23:
-                       {
-                               if (r_u->info.id23 != NULL)
-                               {
-                                       sam_io_user_info23("", r_u->info.id23, ps, depth);
-                               }
-                               else
-                               {
-                                       DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
-                                       return False;
-                               }
-                               break;
-                       }
-                       case 24:
-                       {
-                               if (r_u->info.id24 != NULL)
-                               {
-                                       sam_io_user_info24("", r_u->info.id24, ps, depth);
-                               }
-                               else
-                               {
-                                       DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
-                                       return False;
-                               }
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
-                               break;
-                       }
-                               
-               }
-       }
+}
+
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info21(char *desc,  SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
+{
+       if (usr == NULL)
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       prs_debug(ps, depth, desc, "lsa_io_user_info");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       
+       if(!smb_io_time("logon_time           ", &usr->logon_time, ps, depth))
+               return False;
+       if(!smb_io_time("logoff_time          ", &usr->logoff_time, ps, depth)) 
+               return False;
+       if(!smb_io_time("kickoff_time         ", &usr->kickoff_time, ps, depth)) 
+               return False;
+       if(!smb_io_time("pass_last_set_time   ", &usr->pass_last_set_time, ps, depth)) 
+               return False;
+       if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth)) 
+               return False;
+       if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth)) 
+               return False;
+
+       if(!smb_io_unihdr("hdr_user_name   ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
+               return False;
+       if(!smb_io_unihdr("hdr_full_name   ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
+               return False;
+       if(!smb_io_unihdr("hdr_home_dir    ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
+               return False;
+       if(!smb_io_unihdr("hdr_dir_drive   ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */
+               return False;
+       if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
+               return False;
+       if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
+               return False;
+       if(!smb_io_unihdr("hdr_acct_desc   ", &usr->hdr_acct_desc, ps, depth)) /* account description */
+               return False;
+       if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* workstations user can log on from */
+               return False;
+       if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
+               return False;
+       if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* workstations user can log on from */
+               return False;
+
+       if(!prs_uint8s (False, "lm_pwd        ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
+               return False;
+       if(!prs_uint8s (False, "nt_pwd        ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
+               return False;
+
+       if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User ID */
+               return False;
+       if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group ID */
+               return False;
+       if(!prs_uint16("acb_info      ", ps, depth, &usr->acb_info))      /* Group ID */
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("unknown_3     ", ps, depth, &usr->unknown_3))
+               return False;
+       if(!prs_uint16("logon_divs    ", ps, depth, &usr->logon_divs))     /* logon divisions per week */
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
+               return False;
+       if(!prs_uint32("unknown_5     ", ps, depth, &usr->unknown_5))
+               return False;
+
+       if(!prs_uint8s (False, "padding1      ", ps, depth, usr->padding1, sizeof(usr->padding1)))
+               return False;
+
+       /* here begins pointed-to data */
+
+       if(!smb_io_unistr2("uni_user_name   ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_full_name   ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_home_dir    ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_dir_drive   ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_acct_desc   ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user description unicode string */
+               return False;
+       if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */
+               return False;
+       if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str .buffer, ps, depth)) /* unknown string */
+               return False;
+       if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial .buffer, ps, depth)) /* worksations user can log on from */
+               return False;
+
+       if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
+               return False;
+       if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
+               return False;
+
+       if (usr->ptr_logon_hrs) {
+               if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
+                       return False;
+               if(!prs_align(ps))
+                       return False;
+       }
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_SET_USERINFO structure.
+ Inits a SAMR_R_QUERY_USERINFO structure.
 ********************************************************************/
-BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
-                               POLICY_HND *hnd,
-                               uint16 switch_value, void *info)
+
+void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+                               uint16 switch_value, void *info, uint32 status)
 {
-       if (q_u == NULL || hnd == NULL) return False;
+       DEBUG(5,("init_samr_r_query_userinfo\n"));
 
-       DEBUG(5,("make_samr_q_set_userinfo\n"));
+       r_u->ptr = 0;
+       r_u->switch_value = 0;
 
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
-       q_u->switch_value  = switch_value;
-       q_u->switch_value2 = switch_value;
-       q_u->info.id = info;
+       if (status == 0) {
+               r_u->switch_value = switch_value;
 
-       switch (switch_value)
-       {
-               case 0x18:
-               {
-                       uchar sess_key[16];
-                       if (!cli_get_usr_sesskey(hnd, sess_key))
-                       {
-                               return False;
-                       }
-                       SamOEMhash(q_u->info.id24->pass, sess_key, 1);
-#ifdef DEBUG_PASSWORD
-                       dump_data(100, sess_key, 16);
-                       dump_data(100, q_u->info.id24->pass, 516);
-#endif
+               switch (switch_value) {
+               case 0x10:
+                       r_u->ptr = 1;
+                       r_u->info.id10 = (SAM_USER_INFO_10*)info;
                        break;
-               }
-               case 0x17:
-               {
-                       uchar sess_key[16];
-                       if (!cli_get_usr_sesskey(hnd, sess_key))
-                       {
-                               return False;
-                       }
-                       SamOEMhash(q_u->info.id23->pass, sess_key, 1);
-#ifdef DEBUG_PASSWORD
-                       dump_data(100, sess_key, 16);
-                       dump_data(100, q_u->info.id23->pass, 516);
-#endif
+
+               case 0x11:
+                       r_u->ptr = 1;
+                       r_u->info.id11 = (SAM_USER_INFO_11*)info;
                        break;
-               }
+
+               case 21:
+                       r_u->ptr = 1;
+                       r_u->info.id21 = (SAM_USER_INFO_21*)info;
+                       break;
+
                default:
-               {
-                       DEBUG(4,("make_samr_q_set_userinfo: unsupported switch level\n"));
-                       return False;
+                       DEBUG(4,("init_samr_r_query_aliasinfo: unsupported switch level\n"));
+                       break;
                }
        }
 
-       return True;
+       r_u->status = status;         /* return status */
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth)
+
+BOOL samr_io_r_query_userinfo(char *desc,  SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
+       prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("switch_value ", ps, depth, &(q_u->switch_value )); 
-       prs_uint16("switch_value2", ps, depth, &(q_u->switch_value2)); 
+       if(!prs_align(ps))
+               return False;
 
-       prs_align(ps);
+       if(!prs_uint32("ptr         ", ps, depth, &r_u->ptr))
+               return False;
+       if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       switch (q_u->switch_value)
-       {
-               case 0:
-               {
-                       break;
-               }
-               case 24:
-               {
-                       if (ps->io)
-                       {
-                               /* reading */
-                               q_u->info.id = (SAM_USER_INFO_24*)Realloc(NULL,
-                                                sizeof(*q_u->info.id24));
-                       }
-                       if (q_u->info.id == NULL)
-                       {
-                               DEBUG(2,("samr_io_q_query_userinfo: info pointer not initialised\n"));
+       if (r_u->ptr != 0 && r_u->switch_value != 0) {
+               switch (r_u->switch_value) {
+               case 0x10:
+                       if (r_u->info.id10 != NULL) {
+                               if(!sam_io_user_info10("", r_u->info.id10, ps, depth))
+                                       return False;
+                       } else {
+                               DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
                                return False;
                        }
-                       sam_io_user_info24("", q_u->info.id24, ps, depth);
                        break;
-               }
-               case 23:
-               {
-                       if (ps->io)
-                       {
-                               /* reading */
-                               q_u->info.id = (SAM_USER_INFO_23*)Realloc(NULL,
-                                                sizeof(*q_u->info.id23));
+/*
+               case 0x11:
+                       if (r_u->info.id11 != NULL) {
+                               if(!sam_io_user_info11("", r_u->info.id11, ps, depth))
+                                       return False;
+                       } else {
+                               DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+                               return False;
                        }
-                       if (q_u->info.id == NULL)
-                       {
-                               DEBUG(2,("samr_io_q_query_userinfo: info pointer not initialised\n"));
+                       break;
+*/
+               case 21:
+                       if (r_u->info.id21 != NULL) {
+                               if(!sam_io_user_info21("", r_u->info.id21, ps, depth))
+                                       return False;
+                       } else {
+                               DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
                                return False;
                        }
-                       sam_io_user_info23("", q_u->info.id23, ps, depth);
                        break;
-               }
                default:
-               {
-                       DEBUG(2,("samr_io_q_query_userinfo: unknown switch level\n"));
+                       DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
                        break;
                }
-                       
        }
-       prs_align(ps);
 
-       if (!ps->io)
-       {
-               /* writing */
-               free_samr_q_set_userinfo(q_u);
-       }
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-frees a structure.
+ Reads or writes a structure.
 ********************************************************************/
-void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u)
-{
-       if (q_u->info.id == NULL)
-       {
-               free(q_u->info.id);
-       }
-       q_u->info.id = NULL;
-}
 
-/*******************************************************************
-makes a SAMR_R_SET_USERINFO structure.
-********************************************************************/
-BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status)
-                               
+BOOL samr_io_q_unknown_32(char *desc,  SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_q_unknown_32");
+       depth++;
 
-       DEBUG(5,("make_samr_r_set_userinfo\n"));
+       if(!prs_align(ps))
+               return False;
 
-       r_u->status = status;         /* return status */
+       if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_unihdr ("", &q_u->hdr_mach_acct, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_mach_acct, q_u->hdr_mach_acct.buffer, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("acct_ctrl", ps, depth, &q_u->acct_ctrl))
+               return False;
+       if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
+               return False;
+       if(!prs_uint16("unknown_2", ps, depth, &q_u->unknown_2))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_set_userinfo(char *desc,  SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_r_unknown_32(char *desc,  SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
+       prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_SET_USERINFO2 structure.
+ Inits a SAMR_Q_CONNECT structure.
 ********************************************************************/
-BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
-                               POLICY_HND *hnd,
-                               uint16 switch_value, void *info)
-{
-       if (q_u == NULL || hnd == NULL) return False;
 
-       DEBUG(5,("make_samr_q_set_userinfo2\n"));
+void init_samr_q_connect(SAMR_Q_CONNECT *q_u,
+                               char *srv_name, uint32 unknown_0)
+{
+       int len_srv_name = strlen(srv_name);
 
-       memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
-       q_u->switch_value  = switch_value;
-       q_u->switch_value2 = switch_value;
-       q_u->info.id = info;
+       DEBUG(5,("init_q_connect\n"));
 
-       switch (switch_value)
-       {
-               case 0x10:
-               {
-                       break;
-               }
-               default:
-               {
-                       DEBUG(4,("make_samr_q_set_userinfo2: unsupported switch level\n"));
-                       return False;
-               }
-       }
+       /* make PDC server name \\server */
+       q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0; 
+       init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name+1);  
 
-       return True;
+       /* example values: 0x0000 0002 */
+       q_u->unknown_0 = unknown_0; 
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
+       prs_debug(ps, depth, desc, "samr_io_q_connect");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); 
-       prs_align(ps);
-
-       prs_uint16("switch_value ", ps, depth, &(q_u->switch_value )); 
-       prs_uint16("switch_value2", ps, depth, &(q_u->switch_value2)); 
+       if(!prs_align(ps))
+               return False;
 
-       prs_align(ps);
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
+               return False;
 
-       switch (q_u->switch_value)
-       {
-               case 0:
-               {
-                       break;
-               }
-               case 16:
-               {
-                       if (ps->io)
-                       {
-                               /* reading */
-                               q_u->info.id = (SAM_USER_INFO_16*)Realloc(NULL,
-                                                sizeof(*q_u->info.id16));
-                       }
-                       if (q_u->info.id == NULL)
-                       {
-                               DEBUG(2,("samr_io_q_query_userinfo2: info pointer not initialised\n"));
-                               return False;
-                       }
-                       sam_io_user_info16("", q_u->info.id16, ps, depth);
-                       break;
-               }
-               default:
-               {
-                       DEBUG(2,("samr_io_q_query_userinfo2: unknown switch level\n"));
-                       break;
-               }
-                       
-       }
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       if (!ps->io)
-       {
-               /* writing */
-               free_samr_q_set_userinfo2(q_u);
-       }
+       if(!prs_uint32("unknown_0   ", ps, depth, &q_u->unknown_0))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-frees a structure.
+ Reads or writes a structure.
 ********************************************************************/
-void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u)
+
+BOOL samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
 {
-       if (q_u->info.id == NULL)
-       {
-               free(q_u->info.id);
-       }
-       q_u->info.id = NULL;
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_r_connect");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_SET_USERINFO2 structure.
+ Inits a SAMR_Q_CONNECT_ANON structure.
 ********************************************************************/
-BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
-                               uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_samr_r_set_userinfo2\n"));
-
-       r_u->status = status;         /* return status */
+void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
+{
+       DEBUG(5,("init_q_connect_anon\n"));
 
-       return True;
+       q_u->ptr       = 1;
+       q_u->unknown_0 = 0x5c; /* server name (?!!) */
+       q_u->unknown_1 = 0x01;
+       q_u->unknown_2 = 0x20;
 }
 
+
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_set_userinfo2(char *desc,  SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_connect_anon(char *desc,  SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
+       prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("ptr      ", ps, depth, &q_u->ptr))
+               return False;
+       if(!prs_uint16("unknown_0", ps, depth, &q_u->unknown_0))
+               return False;
+       if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
+               return False;
+       if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_CONNECT structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
-                               const char *srv_name, uint32 unknown_0)
+
+BOOL samr_io_r_connect_anon(char *desc,  SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
 {
-       int len_srv_name = strlen(srv_name);
+       if (r_u == NULL)
+               return False;
 
-       if (q_u == NULL) return False;
+       prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
+       depth++;
 
-       DEBUG(5,("make_samr_q_connect\n"));
+       if(!prs_align(ps))
+               return False;
 
-       /* make PDC server name \\server */
-       q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0; 
-       make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name+1);  
+       if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       /* example values: 0x0000 0002 */
-       q_u->unknown_0 = unknown_0; 
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_Q_OPEN_ALIAS structure.
 ********************************************************************/
-BOOL samr_io_q_connect(char *desc,  SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
+void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
+                               uint32 unknown_0, uint32 rid)
 {
-       if (q_u == NULL) return False;
-
-       prs_debug(ps, depth, desc, "samr_io_q_connect");
-       depth++;
-
-       prs_align(ps);
+       DEBUG(5,("init_q_open_alias\n"));
 
-       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); 
-
-       prs_align(ps);
-
-       prs_uint32("unknown_0   ", ps, depth, &(q_u->unknown_0   ));
+       /* example values: 0x0000 0008 */
+       q_u->unknown_0 = unknown_0; 
 
-       return True;
+       q_u->rid_alias = rid; 
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL samr_io_r_connect(char *desc,  SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
+
+BOOL samr_io_q_open_alias(char *desc,  SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_connect");
+       prs_debug(ps, depth, desc, "samr_io_q_open_alias");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth); 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
+               return False;
+       if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_Q_CONNECT_ANON structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
+
+BOOL samr_io_r_open_alias(char *desc,  SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
-       DEBUG(5,("make_samr_q_connect_anon\n"));
+       prs_debug(ps, depth, desc, "samr_io_r_open_alias");
+       depth++;
 
-       q_u->ptr       = 1;
-       q_u->unknown_0 = 0x5c; /* server name (?!!) */
-       q_u->unknown_1 = 0x01;
-       q_u->unknown_2 = 0x20;
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_Q_UNKNOWN_12 structure.
 ********************************************************************/
-BOOL samr_io_q_connect_anon(char *desc,  SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
+
+void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+               POLICY_HND *pol, uint32 rid,
+               uint32 num_gids, uint32 *gid)
 {
-       if (q_u == NULL) return False;
+       int i;
 
-       prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
-       depth++;
+       DEBUG(5,("init_samr_r_unknwon_12\n"));
 
-       prs_align(ps);
+       memcpy(&q_u->pol, pol, sizeof(*pol));
 
-       prs_uint32("ptr      ", ps, depth, &(q_u->ptr      ));
-       prs_uint16("unknown_0", ps, depth, &(q_u->unknown_0));
-       prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
-       prs_uint32("unknown_2", ps, depth, &(q_u->unknown_2));
+       q_u->num_gids1 = num_gids;
+       q_u->rid       = rid;
+       q_u->ptr       = 0;
+       q_u->num_gids2 = num_gids;
 
-       return True;
+       for (i = 0; i < num_gids; i++) {
+               q_u->gid[i] = gid[i];
+       }
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SAMR_Q_UNKNOWN_21 structure.
 ********************************************************************/
-BOOL samr_io_r_connect_anon(char *desc,  SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
+
+void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
 {
-       if (r_u == NULL) return False;
+       DEBUG(5,("init_samr_q_unknown_21\n"));
 
-       prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
-       depth++;
+       memcpy(&q_c->group_pol, hnd, sizeof(q_c->group_pol));
+       q_c->unknown_1 = unk_1;
+       q_c->unknown_2 = unk_2;
+}
 
-       prs_align(ps);
 
-       smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth); 
-       prs_align(ps);
+/*******************************************************************
+ Inits a SAMR_Q_UNKNOWN_13 structure.
+********************************************************************/
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+void init_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+                               POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+{
+       DEBUG(5,("init_samr_q_unknown_13\n"));
 
-       return True;
+       memcpy(&q_c->alias_pol, hnd, sizeof(q_c->alias_pol));
+       q_c->unknown_1 = unk_1;
+       q_c->unknown_2 = unk_2;
 }
 
 /*******************************************************************
-makes a SAMR_Q_UNKNOWN_38 structure.
+ Inits a SAMR_Q_UNKNOWN_38 structure.
 ********************************************************************/
-BOOL make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
+void init_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
 {
        int len_srv_name = strlen(srv_name);
 
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_unknown_38\n"));
+       DEBUG(5,("init_q_unknown_38\n"));
 
        q_u->ptr = 1;
-       make_uni_hdr(&(q_u->hdr_srv_name), len_srv_name);
-       make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);  
+       init_uni_hdr(&q_u->hdr_srv_name, len_srv_name);
+       init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name);  
 
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_q_unknown_38(char *desc,  SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_unknown_38");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr", ps, depth, &(q_u->ptr));
-       if (q_u->ptr != 0)
-       {
-               smb_io_unihdr ("", &(q_u->hdr_srv_name), ps, depth); 
-               smb_io_unistr2("", &(q_u->uni_srv_name), q_u->hdr_srv_name.buffer, ps, depth); 
-               prs_align(ps);
+       if(!prs_uint32("ptr", ps, depth, &q_u->ptr))
+               return False;
+
+       if (q_u->ptr != 0) {
+               if(!smb_io_unihdr ("", &q_u->hdr_srv_name, ps, depth))
+                       return False;
+               if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->hdr_srv_name.buffer, ps, depth))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_UNKNOWN_38 structure.
+ Inits a SAMR_R_UNKNOWN_38 structure.
 ********************************************************************/
-BOOL make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_r_unknown_38\n"));
+void init_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u)
+{
+       DEBUG(5,("init_r_unknown_38\n"));
 
        r_u->unk_0 = 0;
        r_u->unk_1 = 0;
        r_u->unk_2 = 0;
        r_u->unk_3 = 0;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_unknown_38");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16("unk_0", ps, depth, &(r_u->unk_0));
-       prs_align(ps);
-       prs_uint16("unk_1", ps, depth, &(r_u->unk_1));
-       prs_align(ps);
-       prs_uint16("unk_2", ps, depth, &(r_u->unk_2));
-       prs_align(ps);
-       prs_uint16("unk_3", ps, depth, &(r_u->unk_3));
-       prs_align(ps);
+       if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint16("unk_1", ps, depth, &r_u->unk_1))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint16("unk_2", ps, depth, &r_u->unk_2))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint16("unk_3", ps, depth, &r_u->unk_3))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
@@ -6143,69 +3441,74 @@ BOOL samr_io_r_unknown_38(char *desc,  SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, i
 /*******************************************************************
 make a SAMR_ENC_PASSWD structure.
 ********************************************************************/
-BOOL make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
-{
-       if (pwd == NULL) return False;
 
+void init_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
+{
        pwd->ptr = 1;
        memcpy(pwd->pass, pass, sizeof(pwd->pass)); 
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a SAMR_ENC_PASSWD structure.
+ Reads or writes a SAMR_ENC_PASSWD structure.
 ********************************************************************/
+
 BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth)
 {
-       if (pwd == NULL) return False;
+       if (pwd == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_enc_passwd");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr", ps, depth, &(pwd->ptr));
-       prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)); 
+       if(!prs_uint32("ptr", ps, depth, &pwd->ptr))
+               return False;
+       if(!prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_ENC_HASH structure.
+ Inits a SAMR_ENC_HASH structure.
 ********************************************************************/
-BOOL make_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16])
-{
-       if (hsh == NULL) return False;
 
+void init_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16])
+{
        hsh->ptr = 1;
        memcpy(hsh->hash, hash, sizeof(hsh->hash));
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a SAMR_ENC_HASH structure.
+ Reads or writes a SAMR_ENC_HASH structure.
 ********************************************************************/
+
 BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
 {
-       if (hsh == NULL) return False;
+       if (hsh == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_enc_hash");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr ", ps, depth, &(hsh->ptr));
-       prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash)); 
+       if(!prs_uint32("ptr ", ps, depth, &hsh->ptr))
+               return False;
+       if(!prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash))) 
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_UNKNOWN_38 structure.
+ Inits a SAMR_R_UNKNOWN_38 structure.
 ********************************************************************/
-BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+
+void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
                                char *dest_host, char *user_name,
                                char nt_newpass[516], uchar nt_oldhash[16],
                                char lm_newpass[516], uchar lm_oldhash[16])
@@ -6213,89 +3516,94 @@ BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
        int len_dest_host = strlen(dest_host);
        int len_user_name = strlen(user_name);
 
-       if (q_u == NULL) return False;
-
-       DEBUG(5,("make_samr_q_chgpasswd_user\n"));
+       DEBUG(5,("init_samr_q_chgpasswd_user\n"));
 
        q_u->ptr_0 = 1;
-       make_uni_hdr(&(q_u->hdr_dest_host), len_dest_host);
-       make_unistr2(&(q_u->uni_dest_host), dest_host, len_dest_host);  
-       make_uni_hdr(&(q_u->hdr_user_name), len_user_name);
-       make_unistr2(&(q_u->uni_user_name), user_name, len_user_name);  
+       init_uni_hdr(&q_u->hdr_dest_host, len_dest_host);
+       init_unistr2(&q_u->uni_dest_host, dest_host, len_dest_host);  
+       init_uni_hdr(&q_u->hdr_user_name, len_user_name);
+       init_unistr2(&q_u->uni_user_name, user_name, len_user_name);  
 
-       make_enc_passwd(&(q_u->nt_newpass), nt_newpass);
-       make_enc_hash  (&(q_u->nt_oldhash), nt_oldhash);
+       init_enc_passwd(&q_u->nt_newpass, nt_newpass);
+       init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
 
        q_u->unknown = 0x01;
 
-       make_enc_passwd(&(q_u->lm_newpass), lm_newpass);
-       make_enc_hash  (&(q_u->lm_oldhash), lm_oldhash);
-
-       return True;
+       init_enc_passwd(&q_u->lm_newpass, lm_newpass);
+       init_enc_hash  (&q_u->lm_oldhash, lm_oldhash);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("ptr_0", ps, depth, &(q_u->ptr_0));
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unihdr ("", &(q_u->hdr_dest_host), ps, depth); 
-       smb_io_unistr2("", &(q_u->uni_dest_host), q_u->hdr_dest_host.buffer, ps, depth); 
-       prs_align(ps);
+       if(!prs_uint32("ptr_0", ps, depth, &q_u->ptr_0))
+               return False;
 
-       smb_io_unihdr ("", &(q_u->hdr_user_name), ps, depth); 
-       smb_io_unistr2("", &(q_u->uni_user_name), q_u->hdr_user_name.buffer, ps, depth); 
-       prs_align(ps);
+       if(!smb_io_unihdr ("", &q_u->hdr_dest_host, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_dest_host, q_u->hdr_dest_host.buffer, ps, depth))
+               return False;
+       if(!smb_io_unihdr ("", &q_u->hdr_user_name, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_user_name, q_u->hdr_user_name.buffer, ps, depth))
+               return False;
 
-       samr_io_enc_passwd("nt_newpass", &(q_u->nt_newpass), ps, depth); 
-       samr_io_enc_hash  ("nt_oldhash", &(q_u->nt_oldhash), ps, depth); 
+       if(!samr_io_enc_passwd("nt_newpass", &q_u->nt_newpass, ps, depth))
+               return False;
+       if(!samr_io_enc_hash  ("nt_oldhash", &q_u->nt_oldhash, ps, depth))
+               return False;
 
-       prs_uint32("unknown", ps, depth, &(q_u->unknown));
+       if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
+               return False;
 
-       samr_io_enc_passwd("lm_newpass", &(q_u->lm_newpass), ps, depth); 
-       samr_io_enc_hash  ("lm_oldhash", &(q_u->lm_oldhash), ps, depth); 
+       if(!samr_io_enc_passwd("lm_newpass", &q_u->lm_newpass, ps, depth))
+               return False;
+       if(!samr_io_enc_hash("lm_oldhash", &q_u->lm_oldhash, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a SAMR_R_CHGPASSWD_USER structure.
+ Inits a SAMR_R_CHGPASSWD_USER structure.
 ********************************************************************/
-BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
-{
-       if (r_u == NULL) return False;
 
-       DEBUG(5,("make_r_chgpasswd_user\n"));
+void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
+{
+       DEBUG(5,("init_r_chgpasswd_user\n"));
 
        r_u->status = status;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
+
 BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("status", ps, depth, &(r_u->status));
+       if(!prs_uint32("status", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
-
-
index d4f4f8185fc2959866ff39d9929f05ec80babe2c..541949e51e4f3f3e3e80e52f639f34aca5b9d748 100644 (file)
@@ -2,10 +2,10 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Jeremy R. Allison            1995-1999
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1998,
+ *  Copyright (C) Jeremy R. Allison            1995-1998
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ *  Copyright (C) Paul Ashton                  1997-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
 
 extern int DEBUGLEVEL;
 
+#define SD_HEADER_SIZE 0x14
 
 /*******************************************************************
-makes a structure.
+ Sets up a SEC_ACCESS structure.
 ********************************************************************/
-BOOL make_sec_access(SEC_ACCESS *t, uint32 mask)
+
+void init_sec_access(SEC_ACCESS *t, uint32 mask)
 {
        t->mask = mask;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a SEC_ACCESS structure.
 ********************************************************************/
+
 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);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("mask", ps, depth, &(t->mask));
+       if(!prs_uint32("mask", ps, depth, &(t->mask)))
+               return False;
 
        return True;
 }
 
 
 /*******************************************************************
-makes a structure.
+ Sets up a SEC_ACE structure.
 ********************************************************************/
-BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+
+void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
 {
        t->type = type;
        t->flags = flag;
        t->size = sid_size(sid) + 8;
        t->info = mask;
 
+       ZERO_STRUCTP(&t->sid);
        sid_copy(&t->sid, sid);
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a SEC_ACE structure.
 ********************************************************************/
-BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
+
+BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
 {
        uint32 old_offset;
        uint32 offset_ace_size;
-       if (t == NULL) return False;
+
+       if (psa == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "sec_io_ace");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       old_offset = ps->offset;
+       old_offset = prs_offset(ps);
+
+       if(!prs_uint8("type ", ps, depth, &psa->type))
+               return False;
+
+       if(!prs_uint8("flags", ps, depth, &psa->flags))
+               return False;
 
-       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);
+       if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
+               return False;
+
+       if(!sec_io_access("info ", &psa->info, ps, depth))
+               return False;
 
-       sec_io_access   ("info ", &t->info, ps, depth);
-       prs_align(ps);
-       smb_io_dom_sid("sid  ", &t->sid , ps, depth);
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size, old_offset);
+       if(!smb_io_dom_sid("sid  ", &psa->sid , ps, depth))
+               return False;
+
+       if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-makes a structure.  
+ Create a SEC_ACL structure.  
 ********************************************************************/
-BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
+
+SEC_ACL *make_sec_acl(uint16 revision, int num_aces, SEC_ACE *ace_list)
 {
+       SEC_ACL *dst;
        int i;
-       t->revision = revision;
-       t->num_aces = num_aces;
-       t->size = 4;
-       t->ace = ace;
-
-       for (i = 0; i < num_aces; i++)
-       {
-               t->size += ace[i].size;
+
+       if((dst = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
+               return NULL;
+
+       ZERO_STRUCTP(dst);
+
+       dst->revision = revision;
+       dst->num_aces = num_aces;
+       dst->size = 8;
+
+       if((dst->ace_list = (SEC_ACE *)malloc( sizeof(SEC_ACE) * num_aces )) == NULL) {
+               free_sec_acl(&dst);
+               return NULL;
        }
 
-       return True;
+       for (i = 0; i < num_aces; i++) {
+               dst->ace_list[i] = ace_list[i]; /* Structure copy. */
+               dst->size += ace_list[i].size;
+       }
+
+       return dst;
 }
 
 /*******************************************************************
-frees a structure.  
+ Duplicate a SEC_ACL structure.  
 ********************************************************************/
-void free_sec_acl(SEC_ACL *t)
+
+SEC_ACL *dup_sec_acl( SEC_ACL *src)
 {
-       if (t->ace != NULL)
-       {
-               free(t->ace);
-       }
+       if(src == NULL)
+               return NULL;
+
+       return make_sec_acl( src->revision, src->num_aces, src->ace_list);
 }
 
 /*******************************************************************
-reads or writes a structure.  
+ Delete a SEC_ACL structure.  
+********************************************************************/
+
+void free_sec_acl(SEC_ACL **ppsa)
+{
+       SEC_ACL *psa;
 
-first of the xx_io_xx functions that allocates its data structures
+       if(ppsa == NULL || *ppsa == NULL)
+               return;
+
+       psa = *ppsa;
+       if (psa->ace_list != NULL)
+               free(psa->ace_list);
+
+       free(psa);
+       *ppsa = NULL;
+}
+
+/*******************************************************************
+ Reads or writes a SEC_ACL 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 **ppsa, prs_struct *ps, int depth)
 {
-       uint32 i;
+       int i;
        uint32 old_offset;
        uint32 offset_acl_size;
+       SEC_ACL *psa;
 
-       if (t == NULL) return False;
+       if (ppsa == NULL)
+               return False;
+
+       psa = *ppsa;
+
+       if(UNMARSHALLING(ps) && psa == NULL) {
+               /*
+                * This is a read and we must allocate the stuct to read into.
+                */
+               if((psa = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
+                       return False;
+               ZERO_STRUCTP(psa);
+               *ppsa = psa;
+       }
 
        prs_debug(ps, depth, desc, "sec_io_acl");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       old_offset = ps->offset;
+       old_offset = prs_offset(ps);
 
-       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 ));
+       if(!prs_uint16("revision", ps, depth, &psa->revision))
+               return False;
 
-       if (ps->io && t->num_aces != 0)
-       {
-               /* reading */
-               t->ace = (SEC_ACE*)malloc(sizeof(t->ace[0]) * t->num_aces);
-               ZERO_STRUCTP(t->ace);
-               }
+       if(!prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size))
+               return False;
 
-       if (t->ace == NULL && t->num_aces != 0)
-       {
-               DEBUG(0,("INVALID ACL\n"));
-               ps->offset = 0xfffffffe;
+       if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
                return False;
+
+       if (UNMARSHALLING(ps) && psa->num_aces != 0) {
+               /* reading */
+               if((psa->ace_list = malloc(sizeof(psa->ace_list[0]) * psa->num_aces)) == NULL)
+                       return False;
+               ZERO_STRUCTP(psa->ace_list);
        }
 
-       for (i = 0; i < MIN(t->num_aces, MAX_SEC_ACES); i++)
-       {
+       for (i = 0; i < psa->num_aces; i++) {
                fstring tmp;
-               slprintf(tmp, sizeof(tmp)-1, "ace[%02d]: ", i);
-               sec_io_ace(tmp, &t->ace[i], ps, depth);
+               slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
+               if(!sec_io_ace(tmp, &psa->ace_list[i], ps, depth))
+                       return False;
        }
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16_post("size     ", ps, depth, &t->size    , offset_acl_size, old_offset);
+       if(!prs_uint16_post("size     ", ps, depth, &psa->size, offset_acl_size, old_offset))
+               return False;
 
        return True;
 }
 
-
 /*******************************************************************
-makes a structure
+ Creates a SEC_DESC structure
 ********************************************************************/
-int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
+
+SEC_DESC *make_sec_desc(uint16 revision, uint16 type,
                        DOM_SID *owner_sid, DOM_SID *grp_sid,
-                               SEC_ACL *sacl, SEC_ACL *dacl)
+                       SEC_ACL *sacl, SEC_ACL *dacl, size_t *sec_desc_size)
 {
+       SEC_DESC *dst;
        uint32 offset;
 
-       t->revision = revision;
-       t->type     = type;
+       *sec_desc_size = 0;
+
+       if(( dst = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
+               return NULL;
+
+       ZERO_STRUCTP(dst);
+
+       dst->revision = revision;
+       dst->type     = type;
+
+       dst->off_owner_sid = 0;
+       dst->off_grp_sid   = 0;
+       dst->off_sacl      = 0;
+       dst->off_dacl      = 0;
+
+       if(owner_sid && ((dst->owner_sid = sid_dup(owner_sid)) == NULL))
+               goto error_exit;
 
-       t->off_owner_sid = 0;
-       t->off_grp_sid   = 0;
-       t->off_sacl      = 0;
-       t->off_dacl      = 0;
+       if(grp_sid && ((dst->grp_sid = sid_dup(grp_sid)) == NULL))
+               goto error_exit;
 
-       t->dacl      = dacl;
-       t->sacl      = sacl;
-       t->owner_sid = owner_sid;
-       t->grp_sid   = grp_sid;
+       if(sacl && ((dst->sacl = dup_sec_acl(sacl)) == NULL))
+               goto error_exit;
 
+       if(dacl && ((dst->dacl = dup_sec_acl(dacl)) == NULL))
+               goto error_exit;
+               
        offset = 0x0;
 
-       if (dacl != NULL)
-       {
+       /*
+        * Work out the linearization sizes.
+        */
+
+       if (dst->owner_sid != NULL) {
+
                if (offset == 0)
-               {
-                       offset = 0x14;
-               }
-               t->off_dacl = offset;
-               offset += dacl->size;
+                       offset = SD_HEADER_SIZE;
+
+               dst->off_owner_sid = offset;
+               offset += ((sid_size(dst->owner_sid) + 3) & ~3);
        }
 
-       if (sacl != NULL)
-       {
+       if (dst->grp_sid != NULL) {
+
                if (offset == 0)
-               {
-                       offset = 0x14;
-               }
-               t->off_dacl = offset;
-               offset += dacl->size;
+                       offset = SD_HEADER_SIZE;
+
+               dst->off_grp_sid = offset;
+               offset += ((sid_size(dst->grp_sid) + 3) & ~3);
        }
 
-       if (owner_sid != NULL)
-       {
+       if (dst->sacl != NULL) {
+
                if (offset == 0)
-               {
-                       offset = 0x14;
-               }
-               t->off_owner_sid = offset;
-               offset += sid_size(owner_sid);
+                       offset = SD_HEADER_SIZE;
+
+               dst->off_sacl = offset;
+               offset += ((sacl->size + 3) & ~3);
        }
 
-       if (grp_sid != NULL)
-       {
+       if (dst->dacl != NULL) {
+
                if (offset == 0)
-               {
-                       offset = 0x14;
-               }
-               t->off_grp_sid = offset;
-               offset += sid_size(grp_sid);
+                       offset = SD_HEADER_SIZE;
+
+               dst->off_dacl = offset;
+               offset += ((dacl->size + 3) & ~3);
        }
 
-       return (offset == 0) ? 0x14 : offset;
+       *sec_desc_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset);
+       return dst;
+
+error_exit:
+
+       *sec_desc_size = 0;
+       free_sec_desc(&dst);
+       return NULL;
 }
 
+/*******************************************************************
+ Duplicate a SEC_DESC structure.  
+********************************************************************/
+
+SEC_DESC *dup_sec_desc( SEC_DESC *src)
+{
+       size_t dummy;
+
+       if(src == NULL)
+               return NULL;
+
+       return make_sec_desc( src->revision, src->type, 
+                               src->owner_sid, src->grp_sid, src->sacl,
+                               src->dacl, &dummy);
+}
 
 /*******************************************************************
-frees a structure
+ Deletes a SEC_DESC structure
 ********************************************************************/
-void free_sec_desc(SEC_DESC *t)
+
+void free_sec_desc(SEC_DESC **ppsd)
 {
-       if (t->dacl != NULL)
-       {
-               free_sec_acl(t->dacl);
-       }
+       SEC_DESC *psd;
 
-       if (t->sacl != NULL)
-       {
-               free_sec_acl(t->dacl);
+       if(ppsd == NULL || *ppsd == NULL)
+               return;
 
-       }
+       psd = *ppsd;
 
-       if (t->owner_sid != NULL)
-       {
-               free(t->owner_sid);
-       }
+       free_sec_acl(&psd->dacl);
+       free_sec_acl(&psd->dacl);
+       free(psd->owner_sid);
+       free(psd->grp_sid);
+       free(psd);
+       *ppsd = NULL;
+}
 
-       if (t->grp_sid != NULL)
-       {
-               free(t->grp_sid);
-       }
+/*******************************************************************
+ Creates a SEC_DESC structure with typical defaults.
+********************************************************************/
+
+SEC_DESC *make_standard_sec_desc(DOM_SID *owner_sid, DOM_SID *grp_sid,
+                                SEC_ACL *dacl, size_t *sec_desc_size)
+{
+       return make_sec_desc(1, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+                            owner_sid, grp_sid, NULL, dacl, sec_desc_size);
 }
 
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a SEC_DESC structure.
+ If reading and the *ppsd = NULL, allocates the structure.
 ********************************************************************/
-static BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
+
+BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
 {
-#if 0
-       uint32 off_owner_sid;
-       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 */
+       SEC_DESC *psd;
+
+       if (ppsd == NULL)
+               return False;
 
-       if (t == NULL) return False;
+       psd = *ppsd;
+
+       if(UNMARSHALLING(ps) && psd == NULL) {
+               if((psd = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
+                       return False;
+               ZERO_STRUCTP(psd);
+               *ppsd = psd;
+       }
 
        prs_debug(ps, depth, desc, "sec_io_desc");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
        /* start of security descriptor stored for back-calc offset purposes */
-       old_offset = ps->offset;
-
-       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     ));
-#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     );
-#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);
-#endif
-               ps->offset = old_offset + t->off_dacl;
-               if (ps->io)
-               {
-                       /* reading */
-                       t->dacl = (SEC_ACL*)malloc(sizeof(*t->dacl));
-                       ZERO_STRUCTP(t->dacl);
-               }
+       old_offset = prs_offset(ps);
 
-               if (t->dacl == NULL)
-               {
-                       DEBUG(0,("INVALID DACL\n"));
-                       ps->offset = 0xfffffffe;
-                       return False;
-               }
+       if(!prs_uint16("revision ", ps, depth, &psd->revision))
+               return False;
 
-               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);
-       }
-#endif
-
-       max_offset = MAX(max_offset, ps->offset);
-
-       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);
-#endif
-               ps->offset = old_offset + t->off_sacl;
-               if (ps->io)
-               {
-                       /* reading */
-                       t->sacl = (SEC_ACL*)malloc(sizeof(*t->sacl));
-                       ZERO_STRUCTP(t->sacl);
-               }
+       if(!prs_uint16("type     ", ps, depth, &psd->type))
+               return False;
 
-               if (t->sacl == NULL)
-               {
-                       DEBUG(0,("INVALID SACL\n"));
-                       ps->offset = 0xfffffffe;
-                       return False;
-               }
+       if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
+               return False;
 
-               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);
-       }
-#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);
-#endif
-       if (t->off_owner_sid != 0)
-       {
-               if (ps->io)
-               {
-                       ps->offset = old_offset + t->off_owner_sid;
-                       }
-               if (ps->io)
-               {
+       if(!prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid))
+               return False;
+
+       if(!prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl))
+               return False;
+
+       if(!prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
+               return False;
+
+       max_offset = MAX(max_offset, prs_offset(ps));
+
+       if (psd->off_owner_sid != 0) {
+
+               if (UNMARSHALLING(ps)) {
+                       if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
+                               return False;
                        /* reading */
-                       t->owner_sid = (DOM_SID*)malloc(sizeof(*t->owner_sid));
-                       ZERO_STRUCTP(t->owner_sid);
+                       if((psd->owner_sid = malloc(sizeof(*psd->owner_sid))) == NULL)
+                               return False;
+                       ZERO_STRUCTP(psd->owner_sid);
                }
 
-               if (t->owner_sid == NULL)
-               {
-                       DEBUG(0,("INVALID OWNER SID\n"));
-                       ps->offset = 0xfffffffe;
+               if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
+                       return False;
+               if(!prs_align(ps))
                        return False;
-               }
-
-               smb_io_dom_sid("owner_sid ", t->owner_sid , ps, depth);
-               prs_align(ps);
        }
 
-       max_offset = MAX(max_offset, ps->offset);
+       max_offset = MAX(max_offset, prs_offset(ps));
 
-#if 0
-       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)
-       {
-               if (ps->io)
-               {
-                       ps->offset = old_offset + t->off_grp_sid;
+       if (psd->off_grp_sid != 0) {
 
-               }
-               if (ps->io)
-               {
+               if (UNMARSHALLING(ps)) {
                        /* reading */
-                       t->grp_sid = (DOM_SID*)malloc(sizeof(*t->grp_sid));
-                       ZERO_STRUCTP(t->grp_sid);
+                       if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
+                               return False;
+                       if((psd->grp_sid = malloc(sizeof(*psd->grp_sid))) == NULL)
+                               return False;
+                       ZERO_STRUCTP(psd->grp_sid);
                }
 
-               if (t->grp_sid == NULL)
-               {
-                       DEBUG(0,("INVALID GROUP SID\n"));
-                       ps->offset = 0xfffffffe;
+               if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
                        return False;
-               }
+               if(!prs_align(ps))
+                       return False;
+       }
+
+       max_offset = MAX(max_offset, prs_offset(ps));
 
-               smb_io_dom_sid("grp_sid", t->grp_sid, ps, depth);
-               prs_align(ps);
+       if (IS_BITS_SET_ALL(psd->type, SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
+               if(!prs_set_offset(ps, old_offset + psd->off_sacl))
+                       return False;
+               if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
+                       return False;
+               if(!prs_align(ps))
+                       return False;
        }
 
-       max_offset = MAX(max_offset, ps->offset);
+       max_offset = MAX(max_offset, prs_offset(ps));
+
+       if (IS_BITS_SET_ALL(psd->type, SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
+               if(!prs_set_offset(ps, old_offset + psd->off_dacl))
+                       return False;
+               if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
+                       return False;
+               if(!prs_align(ps))
+                       return False;
+       }
 
-       ps->offset = max_offset;
+       max_offset = MAX(max_offset, prs_offset(ps));
 
+       if(!prs_set_offset(ps, max_offset))
+               return False;
        return True;
 }
 
 /*******************************************************************
-creates a SEC_DESC_BUF structure.
+ Creates a SEC_DESC_BUF structure.
 ********************************************************************/
-BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
+
+SEC_DESC_BUF *make_sec_desc_buf(int len, SEC_DESC *sec_desc)
 {
-       ZERO_STRUCTP(buf);
+       SEC_DESC_BUF *dst;
+
+       if((dst = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
+               return NULL;
+
+       ZERO_STRUCTP(dst);
 
        /* max buffer size (allocated size) */
-       buf->max_len = len;
-       buf->undoc       = 0;
-       buf->len = data != NULL ? len : 0;
-       buf->sec = data;
+       dst->max_len = len;
+       dst->len = len;
 
-       return True;
+       if(sec_desc && ((dst->sec = dup_sec_desc(sec_desc)) == NULL)) {
+               free_sec_desc_buf(&dst);
+               return NULL;
+       }
+
+       return dst;
 }
 
 /*******************************************************************
-frees a SEC_DESC_BUF structure.
+ Duplicates a SEC_DESC_BUF structure.
 ********************************************************************/
-void free_sec_desc_buf(SEC_DESC_BUF *buf)
+
+SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src)
 {
-       if (buf->sec != NULL)
-       {
-               free_sec_desc(buf->sec);
-               free(buf->sec);
-       }
+       if(src == NULL)
+               return NULL;
+
+       return make_sec_desc_buf( src->len, src->sec);
+}
+
+/*******************************************************************
+ Deletes a SEC_DESC_BUF structure.
+********************************************************************/
+
+void free_sec_desc_buf(SEC_DESC_BUF **ppsdb)
+{
+       SEC_DESC_BUF *psdb;
+
+       if(ppsdb == NULL || *ppsdb == NULL)
+               return;
+
+       psdb = *ppsdb;
+       free_sec_desc(&psdb->sec);
+       free(psdb);
+       *ppsdb = NULL;
 }
 
 
 /*******************************************************************
-reads or writes a SEC_DESC_BUF structure.
+ 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 **ppsdb, prs_struct *ps, int depth)
 {
        uint32 off_len;
        uint32 off_max_len;
        uint32 old_offset;
        uint32 size;
+       SEC_DESC_BUF *psdb;
+
+       if (ppsdb == NULL)
+               return False;
 
-       if (sec == NULL) return False;
+       psdb = *ppsdb;
+
+       if (UNMARSHALLING(ps) && psdb == NULL) {
+               if((psdb = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
+                       return False;
+               ZERO_STRUCTP(psdb);
+               *ppsdb = psdb;
+       }
 
        prs_debug(ps, depth, desc, "sec_io_desc_buf");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       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);
+       if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
+               return False;
 
-       old_offset = ps->offset;
+       if(!prs_uint32    ("undoc  ", ps, depth, &psdb->undoc))
+               return False;
 
-       if (sec->len != 0 && ps->io)
-       {
-               /* reading */
-               sec->sec = (SEC_DESC*)malloc(sizeof(*sec->sec));
-               ZERO_STRUCTP(sec->sec);
+       if(!prs_uint32_pre("len    ", ps, depth, &psdb->len, &off_len))
+               return False;
 
-               if (sec->sec == NULL)
-               {
-                       DEBUG(0,("INVALID SEC_DESC\n"));
-                       ps->offset = 0xfffffffe;
-                       return False;
-               }
-       }
+       old_offset = prs_offset(ps);
 
        /* reading, length is non-zero; writing, descriptor is non-NULL */
-       if ((sec->len != 0 || (!ps->io)) && sec->sec != NULL)
-       {
-               sec_io_desc("sec   ", sec->sec, ps, depth);
+       if ((psdb->len != 0 || MARSHALLING(ps)) && psdb->sec != NULL) {
+               if(!sec_io_desc("sec   ", &psdb->sec, ps, depth))
+                       return False;
        }
 
-       prs_align(ps);
-       
-       size = ps->offset - old_offset;
-       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);
+       size = prs_offset(ps) - old_offset;
+       if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
+               return False;
+
+       if(!prs_uint32_post("len    ", ps, depth, &psdb->len, off_len, size))
+               return False;
 
        return True;
 }
-
index 63d27c8c91338f5930424497c10544bd18bfa68d..8997b05e0b75a2713275eac56cf7a74bf3d7a3c5 100644 (file)
@@ -3,9 +3,10 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
+ *  Copyright (C) Jeremy Allison                   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
 
 extern int DEBUGLEVEL;
 
-
 /*******************************************************************
makes a SH_INFO_1_STR structure
Inits a SH_INFO_1_STR structure
 ********************************************************************/
-BOOL make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
-{
-       if (sh1 == NULL) return False;
-
-       DEBUG(5,("make_srv_share_info1_str\n"));
 
-       make_unistr2(&(sh1->uni_netname), net_name, strlen(net_name)+1);
-       make_unistr2(&(sh1->uni_remark ), remark  , strlen(remark  )+1);
+void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
+{
+       DEBUG(5,("init_srv_share_info1_str\n"));
 
-       return True;
+       init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
+       init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_share_info1_str(char *desc,  SH_INFO_1_STR *sh1, prs_struct *ps, int depth)
+
+static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *ps, int depth)
 {
-       if (sh1 == NULL) return False;
+       if (sh1 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_share_info1_str");
        depth++;
 
-       prs_align(ps);
-
-       smb_io_unistr2("", &(sh1->uni_netname), True, ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("", &(sh1->uni_remark ), True, ps, depth); 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
+       if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
+               return False;
 
        return True;
 }
@@ -67,940 +66,768 @@ static BOOL srv_io_share_info1_str(char *desc,  SH_INFO_1_STR *sh1, prs_struct *
 /*******************************************************************
  makes a SH_INFO_1 structure
 ********************************************************************/
-BOOL make_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark)
-{
-       if (sh1 == NULL) return False;
 
-       DEBUG(5,("make_srv_share_info1: %s %8x %s\n", net_name, type, remark));
+void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark)
+{
+       DEBUG(5,("init_srv_share_info1: %s %8x %s\n", net_name, type, remark));
 
-       sh1->ptr_netname = net_name != NULL ? 1 : 0;
+       sh1->ptr_netname = (net_name != NULL) ? 1 : 0;
        sh1->type        = type;
-       sh1->ptr_remark  = remark   != NULL ? 1 : 0;
-
-       return True;
+       sh1->ptr_remark  = (remark != NULL) ? 1 : 0;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_share_info1(char *desc,  SH_INFO_1 *sh1, prs_struct *ps, int depth)
+
+static BOOL srv_io_share_info1(char *desc, SH_INFO_1 *sh1, prs_struct *ps, int depth)
 {
-       if (sh1 == NULL) return False;
+       if (sh1 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_share_info1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_netname", ps, depth, &(sh1->ptr_netname));
-       prs_uint32("type       ", ps, depth, &(sh1->type       ));
-       prs_uint32("ptr_remark ", ps, depth, &(sh1->ptr_remark));
+       if(!prs_uint32("ptr_netname", ps, depth, &sh1->ptr_netname))
+               return False;
+       if(!prs_uint32("type       ", ps, depth, &sh1->type))
+               return False;
+       if(!prs_uint32("ptr_remark ", ps, depth, &sh1->ptr_remark))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SH_INFO_2_STR structure
 ********************************************************************/
-static BOOL srv_io_srv_share_info_1(char *desc,  SRV_SHARE_INFO_1 *ctr, prs_struct *ps, int depth)
-{
-       if (ctr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "srv_io_share_1_ctr");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
-       prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
 
-       if (ctr->ptr_share_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ctr->num_entries_read;
-               if (num_entries > MAX_SHARE_ENTRIES)
-               {
-                       num_entries = MAX_SHARE_ENTRIES; /* report this! */
-               }
-
-               prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
-
-               SMB_ASSERT_ARRAY(ctr->info_1, num_entries);
-
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_share_info1("", &(ctr->info_1[i]), ps, depth); 
-               }
-
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_share_info1_str("", &(ctr->info_1_str[i]), ps, depth); 
-               }
-
-               prs_align(ps);
-       }
-
-       return True;
-}
-
-/*******************************************************************
- makes a SH_INFO_2_STR structure
-********************************************************************/
-BOOL make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
                                char *net_name, char *remark,
-                               char *path, char *pass)
+                               char *path, char *passwd)
 {
-       if (sh2 == NULL) return False;
-
-       DEBUG(5,("make_srv_share_info2_str\n"));
-
-       make_unistr2(&(sh2->uni_netname), net_name, strlen(net_name)+1);
-       make_unistr2(&(sh2->uni_remark ), remark  , strlen(remark  )+1);
-       make_unistr2(&(sh2->uni_path   ), path    , strlen(path    )+1);
-       make_unistr2(&(sh2->uni_passwd ), pass    , strlen(pass    )+1);
+       DEBUG(5,("init_srv_share_info2_str\n"));
 
-       return True;
+       init_unistr2(&sh2->uni_netname, net_name, strlen(net_name)+1);
+       init_unistr2(&sh2->uni_remark, remark, strlen(remark)+1);
+       init_unistr2(&sh2->uni_path, path, strlen(path)+1);
+       init_unistr2(&sh2->uni_passwd, passwd, strlen(passwd)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_share_info2_str(char *desc,  SH_INFO_2_STR *ss2, SH_INFO_2 *sh2, prs_struct *ps, int depth)
+
+static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2_STR *sh2, prs_struct *ps, int depth)
 {
-       if (ss2 == NULL) return False;
+       if (sh2 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_share_info2_str");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("", &(ss2->uni_netname), sh2->ptr_netname, ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("", &(ss2->uni_remark ), sh2->ptr_remark , ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("", &(ss2->uni_path   ), sh2->ptr_path   , ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("", &(ss2->uni_passwd ), sh2->ptr_passwd , ps, depth); 
-       prs_align(ps);
+       if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &sh2->uni_remark, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &sh2->uni_path, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &sh2->uni_passwd, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a SH_INFO_2 structure
Inits a SH_INFO_2 structure
 ********************************************************************/
-BOOL make_srv_share_info2(SH_INFO_2 *sh2,
+
+void init_srv_share_info2(SH_INFO_2 *sh2,
                                char *net_name, uint32 type, char *remark,
                                uint32 perms, uint32 max_uses, uint32 num_uses,
-                               char *path, char *pass)
+                               char *path, char *passwd)
 {
-       if (sh2 == NULL) return False;
-
-       DEBUG(5,("make_srv_share_info2: %s %8x %s\n", net_name, type, remark));
+       DEBUG(5,("init_srv_share_info2: %s %8x %s\n", net_name, type, remark));
 
-       sh2->ptr_netname = net_name != NULL ? 1 : 0;
+       sh2->ptr_netname = (net_name != NULL) ? 1 : 0;
        sh2->type        = type;
-       sh2->ptr_remark  = remark   != NULL ? 1 : 0;
+       sh2->ptr_remark  = (remark != NULL) ? 1 : 0;
        sh2->perms       = perms;
        sh2->max_uses    = max_uses;
        sh2->num_uses    = num_uses;
        sh2->type        = type;
-       sh2->ptr_path    = path     != NULL ? 1 : 0;
-       sh2->ptr_passwd  = pass     != NULL ? 1 : 0;
-
-       return True;
+       sh2->ptr_path    = (path != NULL) ? 1 : 0;
+       sh2->ptr_passwd  = (passwd != NULL) ? 1 : 0;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_share_info2(char *desc,  SH_INFO_2 *sh2, prs_struct *ps, int depth)
+
+static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int depth)
 {
-       if (sh2 == NULL) return False;
+       if (sh2 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_share_info2");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_netname", ps, depth, &(sh2->ptr_netname));
-       prs_uint32("type       ", ps, depth, &(sh2->type       ));
-       prs_uint32("ptr_remark ", ps, depth, &(sh2->ptr_remark ));
-       prs_uint32("perms      ", ps, depth, &(sh2->perms      ));
-       prs_uint32("max_uses   ", ps, depth, &(sh2->max_uses   ));
-       prs_uint32("num_uses   ", ps, depth, &(sh2->num_uses   ));
-       prs_uint32("ptr_path   ", ps, depth, &(sh2->ptr_path   ));
-       prs_uint32("ptr_passwd ", ps, depth, &(sh2->ptr_passwd ));
+       if(!prs_uint32("ptr_netname", ps, depth, &sh2->ptr_netname))
+               return False;
+       if(!prs_uint32("type       ", ps, depth, &sh2->type))
+               return False;
+       if(!prs_uint32("ptr_remark ", ps, depth, &sh2->ptr_remark))
+               return False;
+       if(!prs_uint32("perms      ", ps, depth, &sh2->perms))
+               return False;
+       if(!prs_uint32("max_uses   ", ps, depth, &sh2->max_uses))
+               return False;
+       if(!prs_uint32("num_uses   ", ps, depth, &sh2->num_uses))
+               return False;
+       if(!prs_uint32("ptr_path   ", ps, depth, &sh2->ptr_path))
+               return False;
+       if(!prs_uint32("ptr_passwd ", ps, depth, &sh2->ptr_passwd))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_share_info_2(char *desc,  SRV_SHARE_INFO_2 *ctr, prs_struct *ps, int depth)
-{
-       if (ctr == NULL) return False;
-
-       prs_debug(ps, depth, desc, "srv_io_share_2_ctr");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
-       prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
-
-       if (ctr->ptr_share_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ctr->num_entries_read;
-               if (num_entries > MAX_SHARE_ENTRIES)
-               {
-                       num_entries = MAX_SHARE_ENTRIES; /* report this! */
-               }
-
-               prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
-
-               SMB_ASSERT_ARRAY(ctr->info_2, num_entries);
-
-               for (i = 0; i < num_entries; i++)
-               {
-                       if (!srv_io_share_info2("", &(ctr->info_2[i]), ps, depth)) return False;
-               }
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       if (!srv_io_share_info2_str("", &(ctr->info_2_str[i]), &(ctr->info_2[i]), ps, depth)) return False;
-               }
-
-               prs_align(ps);
-       }
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL srv_io_srv_share_ctr(char *desc,  SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ctr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_srv_share_ctr");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_share_ctr", ps, depth, &(ctr->ptr_share_ctr));
-
-       if (ctr->ptr_share_ctr != 0)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 2:
-                       {
-                               srv_io_srv_share_info_2("", &(ctr->share.info2), ps, depth); 
-                               break;
-                       }
-                       case 1:
-                       {
-                               srv_io_srv_share_info_1("", &(ctr->share.info1), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no share info at switch_value %d\n",
-                                        tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
-               }
+       if (UNMARSHALLING(ps)) {
+               memset(ctr, '\0', sizeof(SRV_SHARE_INFO_CTR));
        }
 
-       return True;
-}
+       if(!prs_align(ps))
+               return False;
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, 
-                               const char *srv_name, 
-                               uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
-                               uint32 preferred_len,
-                               ENUM_HND *hnd)
-{
-       if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
-
-       q_n->ctr = ctr;
+       if(!prs_uint32("info_level", ps, depth, &ctr->info_level))
+               return False;
 
-       DEBUG(5,("make_q_net_share_enum\n"));
+       if (ctr->info_level == 0)
+               return True;
 
-       make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+       if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+               return False;
+       if(!prs_uint32("ptr_share_info", ps, depth, &ctr->ptr_share_info))
+               return False;
 
-       q_n->share_level    = share_level;
-       q_n->preferred_len = preferred_len;
+       if (ctr->ptr_share_info == 0)
+               return True;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       if(!prs_uint32("num_entries", ps, depth, &ctr->num_entries))
+               return False;
+       if(!prs_uint32("ptr_entries", ps, depth, &ctr->ptr_entries))
+               return False;
 
-       return True;
-}
+       if (ctr->ptr_entries == 0) {
+               if (ctr->num_entries == 0)
+                       return True;
+               else
+                       return False;
+       }
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL srv_io_q_net_share_enum(char *desc,  SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth)
-{
-       if (q_n == NULL) return False;
+       if(!prs_uint32("num_entries2", ps, depth, &ctr->num_entries2))
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_q_net_share_enum");
-       depth++;
+       if (ctr->num_entries2 != ctr->num_entries)
+               return False;
 
-       prs_align(ps);
+       switch (ctr->switch_value) {
+       case 1:
+       {
+               SRV_SHARE_INFO_1 *info1 = ctr->share.info1;
+               int num_entries = ctr->num_entries;
+               int i;
 
-       prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth); 
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1))))
+                               return False;
+                       memset(info1, '\0', num_entries * sizeof(SRV_SHARE_INFO_1));
+                       ctr->share.info1 = info1;
+               }
 
-       prs_align(ps);
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1("", &info1[i].info_1, ps, depth))
+                               return False;
+               }
 
-       prs_uint32("share_level", ps, depth, &(q_n->share_level  ));
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1_str("", &info1[i].info_1_str, ps, depth))
+                               return False;
+               }
 
-       if (((int)q_n->share_level) != -1)
-       {
-               srv_io_srv_share_ctr("share_ctr", q_n->ctr, ps, depth);
+               break;
        }
 
-       prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
-
-       smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL srv_io_r_net_share_enum(char *desc,  SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth)
-{
-       if (r_n == NULL) return False;
+       case 2:
+       {
+               SRV_SHARE_INFO_2 *info2 = ctr->share.info2;
+               int num_entries = ctr->num_entries;
+               int i;
 
-       prs_debug(ps, depth, desc, "srv_io_r_net_share_enum");
-       depth++;
+               if (UNMARSHALLING(ps)) {
+                       if (!(info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2))))
+                               return False;
+                       memset(info2, '\0', num_entries * sizeof(SRV_SHARE_INFO_2));
+                       ctr->share.info2 = info2;
+               }
 
-       prs_align(ps);
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info2("", &info2[i].info_2, ps, depth))
+                               return False;
+               }
 
-       prs_uint32("share_level", ps, depth, &(r_n->share_level));
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info2_str("", &info2[i].info_2_str, ps, depth))
+                               return False;
+               }
 
-       if (r_n->share_level != 0)
-       {
-               srv_io_srv_share_ctr("share_ctr", r_n->ctr, ps, depth);
+               break;
        }
 
-       prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
-       smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth); 
-       prs_uint32("status     ", ps, depth, &(r_n->status));
+       default:
+               DEBUG(5,("%s no share info at switch_value %d\n",
+                        tab_depth(depth), ctr->switch_value));
+               break;
+       }
 
        return True;
 }
 
 /*******************************************************************
- makes a SESS_INFO_0_STR structure
+ Frees a SRV_SHARE_INFO_CTR structure.
 ********************************************************************/
-BOOL make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name)
-{
-       if (ss0 == NULL) return False;
 
-       DEBUG(5,("make_srv_sess_info0_str\n"));
-
-       make_unistr2(&(ss0->uni_name), name, strlen(name)+1);
-
-       return True;
+void free_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr)
+{
+       if(!ctr)
+               return;
+       if(ctr->share.info)
+               free(ctr->share.info);
+       memset(ctr, '\0', sizeof(SRV_SHARE_INFO_CTR));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Frees a SRV_Q_NET_SHARE_ENUM structure.
 ********************************************************************/
-static BOOL srv_io_sess_info0_str(char *desc,  SESS_INFO_0_STR *ss0, 
-const SESS_INFO_0 *si0, prs_struct *ps, int depth)
-{
-       if (ss0 == NULL) return False;
-
-       prs_debug(ps, depth, desc, "srv_io_sess_info0_str");
-       depth++;
-
-       prs_align(ps);
 
-       smb_io_unistr2("", &(ss0->uni_name), si0->ptr_name, ps, depth); 
-
-       return True;
+void free_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n)
+{
+       if(!q_n)
+               return;
+       free_srv_share_info_ctr(&q_n->ctr);
+       memset(q_n, '\0', sizeof(SRV_Q_NET_SHARE_ENUM));
 }
 
 /*******************************************************************
- makes a SESS_INFO_0 structure
+ Frees a SRV_R_NET_SHARE_ENUM structure.
 ********************************************************************/
-BOOL make_srv_sess_info0(SESS_INFO_0 *ss0, char *name)
-{
-       if (ss0 == NULL) return False;
-
-       DEBUG(5,("make_srv_sess_info0: %s\n", name));
 
-       ss0->ptr_name = name != NULL ? 1 : 0;
-
-       return True;
+void free_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n)
+{
+       if(!r_n)
+               return;
+       free_srv_share_info_ctr(&r_n->ctr);
+       memset(r_n, '\0', sizeof(SRV_R_NET_SHARE_ENUM));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SRV_Q_NET_SHARE_ENUM structure.
 ********************************************************************/
-static BOOL srv_io_sess_info0(char *desc,  SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+
+void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, 
+                               char *srv_name, uint32 info_level,
+                               uint32 preferred_len, ENUM_HND *hnd)
 {
-       if (ss0 == NULL) return False;
 
-       prs_debug(ps, depth, desc, "srv_io_sess_info0");
-       depth++;
+       DEBUG(5,("init_q_net_share_enum\n"));
 
-       prs_align(ps);
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
 
-       prs_uint32("ptr_name", ps, depth, &(ss0->ptr_name));
+       q_n->ctr.info_level = q_n->ctr.switch_value = info_level;
+       q_n->ctr.ptr_share_info = 0;
+       q_n->preferred_len = preferred_len;
 
-       return True;
+       memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_sess_info_0(char *desc,  SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth)
 {
-       if (ss0 == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_sess_info_0");
+       prs_debug(ps, depth, desc, "srv_io_q_net_share_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
-       prs_uint32("ptr_sess_info", ps, depth, &(ss0->ptr_sess_info));
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
-       if (ss0->ptr_sess_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ss0->num_entries_read;
-               if (num_entries > MAX_SESS_ENTRIES)
-               {
-                       num_entries = MAX_SESS_ENTRIES; /* report this! */
-               }
-
-               prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
-
-               SMB_ASSERT_ARRAY(ss0->info_0, num_entries);
+       if(!srv_io_srv_share_ctr("share_ctr", &q_n->ctr, ps, depth))
+               return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_sess_info0("", &(ss0->info_0[i]), ps, depth); 
-               }
+       if(!prs_align(ps))
+               return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_sess_info0_str("", &(ss0->info_0_str[i]),
-                                                 &(ss0->info_0[i]),
-                                                 ps, depth); 
-               }
+       if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
+               return False;
 
-               prs_align(ps);
-       }
+       if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
- makes a SESS_INFO_1_STR structure
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user)
-{
-       if (ss1 == NULL) return False;
-
-       DEBUG(5,("make_srv_sess_info1_str\n"));
 
-       make_unistr2(&(ss1->uni_name), name, strlen(name)+1);
-       make_unistr2(&(ss1->uni_user), name, strlen(user)+1);
-
-       return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL srv_io_sess_info1_str(char *desc,  SESS_INFO_1_STR *ss1,
-                               SESS_INFO_1 *si1,
-                               prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth)
 {
-       if (ss1 == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_sess_info1_str");
+       prs_debug(ps, depth, desc, "srv_io_r_net_share_enum");
        depth++;
 
-       prs_align(ps);
+       if(!srv_io_srv_share_ctr("share_ctr", &r_n->ctr, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("", &(ss1->uni_name), si1->ptr_name, ps, depth); 
-       smb_io_unistr2("", &(ss1->uni_user), si1->ptr_user, ps, depth); 
+       if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
+               return False;
+       if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
+               return False;
+       if(!prs_uint32("status     ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
- makes a SESS_INFO_1 structure
+ Frees a SRV_Q_NET_SHARE_GET_INFO structure.
 ********************************************************************/
-BOOL make_srv_sess_info1(SESS_INFO_1 *ss1, 
-                               char *name, char *user,
-                               uint32 num_opens, uint32 open_time, uint32 idle_time,
-                               uint32 user_flags)
-{
-       if (ss1 == NULL) return False;
-
-       DEBUG(5,("make_srv_sess_info1: %s\n", name));
 
-       ss1->ptr_name = name != NULL ? 1 : 0;
-       ss1->ptr_user = user != NULL ? 1 : 0;
-
-       ss1->num_opens  = num_opens;
-       ss1->open_time  = open_time;
-       ss1->idle_time  = idle_time;
-       ss1->user_flags = user_flags;
-
-       return True;
+void free_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n)
+{
+       if(!q_n)
+               return;
+       memset(q_n, '\0', sizeof(SRV_Q_NET_SHARE_GET_INFO));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Frees a SRV_R_NET_SHARE_GET_INFO structure.
 ********************************************************************/
-static BOOL srv_io_sess_info1(char *desc,  SESS_INFO_1 *ss1, prs_struct *ps, int depth)
-{
-       if (ss1 == NULL) return False;
 
-       prs_debug(ps, depth, desc, "srv_io_sess_info1");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("ptr_name  ", ps, depth, &(ss1->ptr_name  ));
-       prs_uint32("ptr_user  ", ps, depth, &(ss1->ptr_user  ));
-
-       prs_uint32("num_opens ", ps, depth, &(ss1->num_opens ));
-       prs_uint32("open_time ", ps, depth, &(ss1->open_time ));
-       prs_uint32("idle_time ", ps, depth, &(ss1->idle_time ));
-       prs_uint32("user_flags", ps, depth, &(ss1->user_flags));
-
-       return True;
+void free_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n)
+{
+       if(!r_n)
+               return;
+       memset(r_n, '\0', sizeof(SRV_R_NET_SHARE_GET_INFO));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_sess_info_1(char *desc,  SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n, prs_struct *ps, int depth)
 {
-       if (ss1 == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_sess_info_1");
+       prs_debug(ps, depth, desc, "srv_io_q_net_share_get_info");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
-       prs_uint32("ptr_sess_info", ps, depth, &(ss1->ptr_sess_info));
-
-       if (ss1->ptr_sess_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ss1->num_entries_read;
-               if (num_entries > MAX_SESS_ENTRIES)
-               {
-                       num_entries = MAX_SESS_ENTRIES; /* report this! */
-               }
-
-               prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
+       if(!prs_align(ps))
+               return False;
 
-               SMB_ASSERT_ARRAY(ss1->info_1, num_entries);
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_sess_info1("", &(ss1->info_1[i]), ps, depth); 
-               }
+       if(!smb_io_unistr2("", &q_n->uni_share_name, True, ps, depth))
+               return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_sess_info1_str("", &(ss1->info_1_str[i]),
-                                             &(ss1->info_1[i]),
-                                             ps, depth); 
-               }
+       if(!prs_align(ps))
+               return False;
 
-               prs_align(ps);
-       }
+       if(!prs_uint32("info_level", ps, depth, &q_n->info_level))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_sess_ctr(char *desc,  SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth)
+
+BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_sess_ctr");
+       prs_debug(ps, depth, desc, "srv_io_r_net_share_get_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_sess_ctr", ps, depth, &(ctr->ptr_sess_ctr));
+       if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value ))
+               return False;
 
-       if (ctr->ptr_sess_ctr != 0)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 0:
-                       {
-                               srv_io_srv_sess_info_0("", &(ctr->sess.info0), ps, depth); 
-                               break;
-                       }
-                       case 1:
-                       {
-                               srv_io_srv_sess_info_1("", &(ctr->sess.info1), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no session info at switch_value %d\n",
-                                        tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
-               }
-       }
+       if(!prs_uint32("ptr_share_ctr", ps, depth, &r_n->ptr_share_ctr))
+               return False;
 
-       return True;
-}
+       if (r_n->ptr_share_ctr != 0) {
+               switch (r_n->switch_value) {
+               case 1:
+                       if(!srv_io_share_info1("", &r_n->share.info1.info_1, ps, depth))
+                               return False;
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
-                               char *user_name,
-                               uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
-                               uint32 preferred_len,
-                               ENUM_HND *hnd)
-{
-       if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
+                       if(!srv_io_share_info1_str("", &r_n->share.info1.info_1_str, ps, depth))
+                               return False;
 
-       q_n->ctr = ctr;
+                       break;
+               case 2:
+                       if(!srv_io_share_info2("", &r_n->share.info2.info_2, ps, depth))
+                               return False;
 
-       DEBUG(5,("make_q_net_sess_enum\n"));
+                       if(!srv_io_share_info2_str("", &r_n->share.info2.info_2_str, ps, depth))
+                               return False;
 
-       make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
-       make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
-       make_buf_unistr2(&(q_n->uni_user_name), &(q_n->ptr_user_name), user_name);
+                       break;
+               default:
+                       DEBUG(5,("%s no share info at switch_value %d\n",
+                                tab_depth(depth), r_n->switch_value));
+                       break;
+               }
+       }
 
-       q_n->sess_level    = sess_level;
-       q_n->preferred_len = preferred_len;
+       if(!prs_align(ps))
+               return False;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+       if(!prs_uint32("status", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SESS_INFO_0_STR structure
 ********************************************************************/
-BOOL srv_io_q_net_sess_enum(char *desc,  SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth)
-{
-       if (q_n == NULL) return False;
-
-       prs_debug(ps, depth, desc, "srv_io_q_net_sess_enum");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth); 
-
-       prs_align(ps);
-
-       prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
-       smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth); 
-       prs_align(ps);
-
-       prs_uint32("ptr_user_name", ps, depth, &(q_n->ptr_user_name));
-       smb_io_unistr2("", &(q_n->uni_user_name), q_n->ptr_user_name, ps, depth); 
-       prs_align(ps);
 
-       prs_uint32("sess_level", ps, depth, &(q_n->sess_level  ));
-       
-       if (((int)q_n->sess_level) != -1)
-       {
-               srv_io_srv_sess_ctr("sess_ctr", q_n->ctr, ps, depth);
-       }
-
-       prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
-
-       smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth); 
+void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name)
+{
+       DEBUG(5,("init_srv_sess_info0_str\n"));
 
-       return True;
+       init_unistr2(&ss0->uni_name, name, strlen(name)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_r_net_sess_enum(char *desc,  SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth)
+
+static BOOL srv_io_sess_info0_str(char *desc,  SESS_INFO_0_STR *ss0, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (ss0 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_r_net_sess_enum");
+       prs_debug(ps, depth, desc, "srv_io_sess_info0_str");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("sess_level", ps, depth, &(r_n->sess_level));
-
-       if (((int)r_n->sess_level) != -1)
-       {
-               srv_io_srv_sess_ctr("sess_ctr", r_n->ctr, ps, depth);
-       }
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
-       smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth); 
-       prs_uint32("status     ", ps, depth, &(r_n->status));
+       if(!smb_io_unistr2("", &ss0->uni_name, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a CONN_INFO_0 structure
Inits a SESS_INFO_0 structure
 ********************************************************************/
-BOOL make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id)
-{
-       if (ss0 == NULL) return False;
-
-       DEBUG(5,("make_srv_conn_info0\n"));
 
-       ss0->id = id;
+void init_srv_sess_info0(SESS_INFO_0 *ss0, char *name)
+{
+       DEBUG(5,("init_srv_sess_info0: %s\n", name));
 
-       return True;
+       ss0->ptr_name = (name != NULL) ? 1 : 0;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_conn_info0(char *desc,  CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+
+static BOOL srv_io_sess_info0(char *desc, SESS_INFO_0 *ss0, prs_struct *ps, int depth)
 {
-       if (ss0 == NULL) return False;
+       if (ss0 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_conn_info0");
+       prs_debug(ps, depth, desc, "srv_io_sess_info0");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("id", ps, depth, &(ss0->id));
+       if(!prs_uint32("ptr_name", ps, depth, &ss0->ptr_name))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_conn_info_0(char *desc,  SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+
+static BOOL srv_io_srv_sess_info_0(char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth)
 {
-       if (ss0 == NULL) return False;
+       if (ss0 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_conn_info_0");
+       prs_debug(ps, depth, desc, "srv_io_srv_sess_info_0");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
-       prs_uint32("ptr_conn_info", ps, depth, &(ss0->ptr_conn_info));
+       if(!prs_uint32("num_entries_read", ps, depth, &ss0->num_entries_read))
+               return False;
+       if(!prs_uint32("ptr_sess_info", ps, depth, &ss0->ptr_sess_info))
+               return False;
 
-       if (ss0->ptr_conn_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ss0->num_entries_read;
-               if (num_entries > MAX_CONN_ENTRIES)
-               {
-                       num_entries = MAX_CONN_ENTRIES; /* report this! */
+       if (ss0->ptr_sess_info != 0) {
+               int i;
+               int num_entries = ss0->num_entries_read;
+
+               if (num_entries > MAX_SESS_ENTRIES) {
+                       num_entries = MAX_SESS_ENTRIES; /* report this! */
                }
 
-               prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
+               if(!prs_uint32("num_entries_read2", ps, depth, &ss0->num_entries_read2))
+                       return False;
+
+               SMB_ASSERT_ARRAY(ss0->info_0, num_entries);
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_sess_info0("", &ss0->info_0[i], ps, depth))
+                               return False;
+               }
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_conn_info0("", &(ss0->info_0[i]), ps, depth); 
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_sess_info0_str("", &ss0->info_0_str[i], ps, depth))
+                               return False;
                }
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
makes a CONN_INFO_1_STR structure
Inits a SESS_INFO_1_STR structure
 ********************************************************************/
-BOOL make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name)
-{
-       if (ss1 == NULL) return False;
 
-       DEBUG(5,("make_srv_conn_info1_str\n"));
-
-       make_unistr2(&(ss1->uni_usr_name), usr_name, strlen(usr_name)+1);
-       make_unistr2(&(ss1->uni_net_name), net_name, strlen(net_name)+1);
+void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user)
+{
+       DEBUG(5,("init_srv_sess_info1_str\n"));
 
-       return True;
+       init_unistr2(&ss1->uni_name, name, strlen(name)+1);
+       init_unistr2(&ss1->uni_user, name, strlen(user)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1,
-                               CONN_INFO_1 *ci1, prs_struct *ps, int depth)
+
+static BOOL srv_io_sess_info1_str(char *desc, SESS_INFO_1_STR *ss1, prs_struct *ps, int depth)
 {
-       if (ss1 == NULL) return False;
+       if (ss1 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_conn_info1_str");
+       prs_debug(ps, depth, desc, "srv_io_sess_info1_str");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("", &(ss1->uni_usr_name), ci1->ptr_usr_name, ps, depth); 
-       smb_io_unistr2("", &(ss1->uni_net_name), ci1->ptr_net_name, ps, depth); 
+       if(!smb_io_unistr2("", &ss1->uni_name, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &(ss1->uni_user), True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a CONN_INFO_1 structure
Inits a SESS_INFO_1 structure
 ********************************************************************/
-BOOL make_srv_conn_info1(CONN_INFO_1 *ss1, 
-                               uint32 id, uint32 type,
-                               uint32 num_opens, uint32 num_users, uint32 open_time,
-                               char *usr_name, char *net_name)
-{
-       if (ss1 == NULL) return False;
-
-       DEBUG(5,("make_srv_conn_info1: %s %s\n", usr_name, net_name));
 
-       ss1->id        = id       ;
-       ss1->type      = type     ;
-       ss1->num_opens = num_opens ;
-       ss1->num_users = num_users;
-       ss1->open_time = open_time;
+void init_srv_sess_info1(SESS_INFO_1 *ss1, 
+                               char *name, char *user,
+                               uint32 num_opens, uint32 open_time, uint32 idle_time,
+                               uint32 user_flags)
+{
+       DEBUG(5,("init_srv_sess_info1: %s\n", name));
 
-       ss1->ptr_usr_name = usr_name != NULL ? 1 : 0;
-       ss1->ptr_net_name = net_name != NULL ? 1 : 0;
+       ss1->ptr_name = (name != NULL) ? 1 : 0;
+       ss1->ptr_user = (user != NULL) ? 1 : 0;
 
-       return True;
+       ss1->num_opens  = num_opens;
+       ss1->open_time  = open_time;
+       ss1->idle_time  = idle_time;
+       ss1->user_flags = user_flags;
 }
 
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_conn_info1(char *desc,  CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+
+static BOOL srv_io_sess_info1(char *desc, SESS_INFO_1 *ss1, prs_struct *ps, int depth)
 {
-       if (ss1 == NULL) return False;
+       if (ss1 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_conn_info1");
+       prs_debug(ps, depth, desc, "srv_io_sess_info1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("id          ", ps, depth, &(ss1->id        ));
-       prs_uint32("type        ", ps, depth, &(ss1->type      ));
-       prs_uint32("num_opens   ", ps, depth, &(ss1->num_opens ));
-       prs_uint32("num_users   ", ps, depth, &(ss1->num_users ));
-       prs_uint32("open_time   ", ps, depth, &(ss1->open_time ));
+       if(!prs_uint32("ptr_name  ", ps, depth, &ss1->ptr_name))
+               return False;
+       if(!prs_uint32("ptr_user  ", ps, depth, &ss1->ptr_user))
+               return False;
 
-       prs_uint32("ptr_usr_name", ps, depth, &(ss1->ptr_usr_name));
-       prs_uint32("ptr_net_name", ps, depth, &(ss1->ptr_net_name));
+       if(!prs_uint32("num_opens ", ps, depth, &ss1->num_opens))
+               return False;
+       if(!prs_uint32("open_time ", ps, depth, &ss1->open_time))
+               return False;
+       if(!prs_uint32("idle_time ", ps, depth, &ss1->idle_time))
+               return False;
+       if(!prs_uint32("user_flags", ps, depth, &ss1->user_flags))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_conn_info_1(char *desc,  SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+
+static BOOL srv_io_srv_sess_info_1(char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth)
 {
-       if (ss1 == NULL) return False;
+       if (ss1 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_conn_info_1");
+       prs_debug(ps, depth, desc, "srv_io_srv_sess_info_1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
-       prs_uint32("ptr_conn_info", ps, depth, &(ss1->ptr_conn_info));
+       if(!prs_uint32("num_entries_read", ps, depth, &ss1->num_entries_read))
+               return False;
+       if(!prs_uint32("ptr_sess_info", ps, depth, &ss1->ptr_sess_info))
+               return False;
 
-       if (ss1->ptr_conn_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = ss1->num_entries_read;
-               if (num_entries > MAX_CONN_ENTRIES)
-               {
-                       num_entries = MAX_CONN_ENTRIES; /* report this! */
+       if (ss1->ptr_sess_info != 0) {
+               int i;
+               int num_entries = ss1->num_entries_read;
+
+               if (num_entries > MAX_SESS_ENTRIES) {
+                       num_entries = MAX_SESS_ENTRIES; /* report this! */
                }
 
-               prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
+               if(!prs_uint32("num_entries_read2", ps, depth, &ss1->num_entries_read2))
+                       return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_conn_info1("", &(ss1->info_1[i]), ps, depth); 
+               SMB_ASSERT_ARRAY(ss1->info_1, num_entries);
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_sess_info1("", &ss1->info_1[i], ps, depth))
+                               return False;
                }
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_conn_info1_str("", &(ss1->info_1_str[i]),
-                                                 &(ss1->info_1[i]),
-                                                 ps, depth); 
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_sess_info1_str("", &ss1->info_1_str[i], ps, depth))
+                               return False;
                }
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_conn_ctr(char *desc,  SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth)
+
+static BOOL srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ctr == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_conn_ctr");
+       prs_debug(ps, depth, desc, "srv_io_srv_sess_ctr");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_conn_ctr", ps, depth, &(ctr->ptr_conn_ctr));
+       if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+               return False;
+       if(!prs_uint32("ptr_sess_ctr", ps, depth, &ctr->ptr_sess_ctr))
+               return False;
 
-       if (ctr->ptr_conn_ctr != 0)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 0:
-                       {
-                               srv_io_srv_conn_info_0("", &(ctr->conn.info0), ps, depth); 
-                               break;
-                       }
-                       case 1:
-                       {
-                               srv_io_srv_conn_info_1("", &(ctr->conn.info1), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no connection info at switch_value %d\n",
-                                        tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
+       if (ctr->ptr_sess_ctr != 0) {
+               switch (ctr->switch_value) {
+               case 0:
+                       if(!srv_io_srv_sess_info_0("", &ctr->sess.info0, ps, depth))
+                               return False;
+                       break;
+               case 1:
+                       if(!srv_io_srv_sess_info_1("", &ctr->sess.info1, ps, depth))
+                               return False;
+                       break;
+               default:
+                       DEBUG(5,("%s no session info at switch_value %d\n",
+                                tab_depth(depth), ctr->switch_value));
+                       break;
                }
        }
 
@@ -1008,540 +835,626 @@ static BOOL srv_io_srv_conn_ctr(char *desc,  SRV_CONN_INFO_CTR *ctr, prs_struct
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SRV_Q_NET_SESS_ENUM structure.
 ********************************************************************/
-BOOL make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
-                               uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
+
+void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
+                               uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd)
 {
-       if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
-
        q_n->ctr = ctr;
 
-       DEBUG(5,("make_q_net_conn_enum\n"));
+       DEBUG(5,("init_q_net_sess_enum\n"));
 
-       make_buf_unistr2(&(q_n->uni_srv_name ), &(q_n->ptr_srv_name ), srv_name );
-       make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
 
-       q_n->conn_level    = conn_level;
+       q_n->sess_level    = sess_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
-
-       return True;
+       memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_q_net_conn_enum(char *desc,  SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_q_net_conn_enum");
+       prs_debug(ps, depth, desc, "srv_io_q_net_sess_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), q_n->ptr_srv_name, ps, depth); 
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
-       smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth); 
+       if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("conn_level", ps, depth, &(q_n->conn_level  ));
+       if(!prs_uint32("sess_level", ps, depth, &q_n->sess_level))
+               return False;
        
-       if (((int)q_n->conn_level) != -1)
-       {
-               srv_io_srv_conn_ctr("conn_ctr", q_n->ctr, ps, depth);
+       if (q_n->sess_level != -1) {
+               if(!srv_io_srv_sess_ctr("sess_ctr", q_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+       if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
+               return False;
 
-       smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth); 
+       if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_r_net_conn_enum(char *desc,  SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth)
+
+BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_r_net_conn_enum");
+       prs_debug(ps, depth, desc, "srv_io_r_net_sess_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("conn_level", ps, depth, &(r_n->conn_level));
+       if(!prs_uint32("sess_level", ps, depth, &r_n->sess_level))
+               return False;
 
-       if (((int)r_n->conn_level) != -1)
-       {
-               srv_io_srv_conn_ctr("conn_ctr", r_n->ctr, ps, depth);
+       if (r_n->sess_level != -1) {
+               if(!srv_io_srv_sess_ctr("sess_ctr", r_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
-       smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth); 
-       prs_uint32("status     ", ps, depth, &(r_n->status));
+       if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
+               return False;
+       if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
+               return False;
+       if(!prs_uint32("status     ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a TPRT_INFO_0_STR structure
Inits a CONN_INFO_0 structure
 ********************************************************************/
-BOOL make_srv_tprt_info0_str(TPRT_INFO_0_STR *tp0,
-                               char *trans_name,
-                               char *trans_addr, uint32 trans_addr_len,
-                               char *addr_name)
-{
-       if (tp0 == NULL) return False;
-
-       DEBUG(5,("make_srv_tprt_info0_str\n"));
 
-       make_unistr2(&(tp0->uni_trans_name), trans_name, strlen(trans_name)+1);
-       make_buffer4_str(&(tp0->buf_trans_addr), trans_addr, trans_addr_len);
-       make_unistr2(&(tp0->uni_addr_name ), addr_name, strlen(addr_name)+1);
+void init_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id)
+{
+       DEBUG(5,("init_srv_conn_info0\n"));
 
-       return True;
+       ss0->id = id;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_tprt_info0_str(char *desc,  TPRT_INFO_0_STR *tp0,
-                               TPRT_INFO_0 *ti0,
-                               prs_struct *ps, int depth)
+
+static BOOL srv_io_conn_info0(char *desc, CONN_INFO_0 *ss0, prs_struct *ps, int depth)
 {
-       if (tp0 == NULL) return False;
+       if (ss0 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_tprt_info0_str");
+       prs_debug(ps, depth, desc, "srv_io_conn_info0");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("", &(tp0->uni_trans_name), ti0->ptr_trans_name, ps, depth); 
-       smb_io_buffer4("", &(tp0->buf_trans_addr), ti0->ptr_trans_addr, ps, depth); 
-       smb_io_unistr2("", &(tp0->uni_addr_name ), ti0->ptr_addr_name, ps, depth); 
+       if(!prs_uint32("id", ps, depth, &ss0->id))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
- makes a TPRT_INFO_0 structure
+ Reads or writes a structure.
 ********************************************************************/
-BOOL make_srv_tprt_info0(TPRT_INFO_0 *tp0, 
-                               uint32 num_vcs, uint32 trans_addr_len,
-                               char *trans_name, char *trans_addr,
-                               char *addr_name)
+
+static BOOL srv_io_srv_conn_info_0(char *desc, SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth)
 {
-       if (tp0 == NULL) return False;
+       if (ss0 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_srv_conn_info_0");
+       depth++;
 
-       DEBUG(5,("make_srv_tprt_info0: %s %s\n", trans_name, addr_name));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("num_entries_read", ps, depth, &ss0->num_entries_read))
+               return False;
+       if(!prs_uint32("ptr_conn_info", ps, depth, &ss0->ptr_conn_info))
+               return False;
+
+       if (ss0->ptr_conn_info != 0) {
+               int i;
+               int num_entries = ss0->num_entries_read;
+
+               if (num_entries > MAX_CONN_ENTRIES) {
+                       num_entries = MAX_CONN_ENTRIES; /* report this! */
+               }
+
+               if(!prs_uint32("num_entries_read2", ps, depth, &ss0->num_entries_read2))
+                       return False;
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_conn_info0("", &ss0->info_0[i], ps, depth))
+                               return False;
+               }
 
-       tp0->num_vcs = num_vcs;
-       tp0->ptr_trans_name = trans_name != NULL ? 1 : 0;
-       tp0->ptr_trans_addr = trans_addr != NULL ? 1 : 0;
-       tp0->trans_addr_len = trans_addr_len;
-       tp0->ptr_addr_name  = addr_name  != NULL ? 1 : 0;
+               if(!prs_align(ps))
+                       return False;
+       }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a CONN_INFO_1_STR structure
 ********************************************************************/
-static BOOL srv_io_tprt_info0(char *desc,  TPRT_INFO_0 *tp0, prs_struct *ps, int depth)
-{
-       if (tp0 == NULL) return False;
 
-       prs_debug(ps, depth, desc, "srv_io_tprt_info0");
-       depth++;
-
-       prs_align(ps);
-
-       prs_uint32("num_vcs       ", ps, depth, &(tp0->num_vcs       ));
-       prs_uint32("ptr_trans_name", ps, depth, &(tp0->ptr_trans_name));
-       prs_uint32("ptr_trans_addr", ps, depth, &(tp0->ptr_trans_addr));
-       prs_uint32("trans_addr_len", ps, depth, &(tp0->trans_addr_len));
-       prs_uint32("ptr_addr_name ", ps, depth, &(tp0->ptr_addr_name ));
+void init_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name)
+{
+       DEBUG(5,("init_srv_conn_info1_str\n"));
 
-       return True;
+       init_unistr2(&ss1->uni_usr_name, usr_name, strlen(usr_name)+1);
+       init_unistr2(&ss1->uni_net_name, net_name, strlen(net_name)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_tprt_info_0(char *desc,  SRV_TPRT_INFO_0 *tp0, prs_struct *ps, int depth)
+
+static BOOL srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1, prs_struct *ps, int depth)
 {
-       if (tp0 == NULL) return False;
+       if (ss1 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_tprt_info_0");
+       prs_debug(ps, depth, desc, "srv_io_conn_info1_str");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("num_entries_read", ps, depth, &(tp0->num_entries_read));
-       prs_uint32("ptr_tprt_info", ps, depth, &(tp0->ptr_tprt_info));
+       if(!smb_io_unistr2("", &ss1->uni_usr_name, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &ss1->uni_net_name, True, ps, depth))
+               return False;
 
-       if (tp0->ptr_tprt_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = tp0->num_entries_read;
+       return True;
+}
 
-               prs_uint32("num_entries_read2", ps, depth, &(tp0->num_entries_read2));
+/*******************************************************************
+ Inits a CONN_INFO_1 structure
+********************************************************************/
 
-               if (ps->io)
-               {
-                       /* reading */
-                       tp0->info_0 = (TPRT_INFO_0*)malloc(num_entries *
-                                     sizeof(tp0->info_0[0]));
+void init_srv_conn_info1(CONN_INFO_1 *ss1, 
+                               uint32 id, uint32 type,
+                               uint32 num_opens, uint32 num_users, uint32 open_time,
+                               char *usr_name, char *net_name)
+{
+       DEBUG(5,("init_srv_conn_info1: %s %s\n", usr_name, net_name));
 
-                       tp0->info_0_str = (TPRT_INFO_0_STR*)malloc(num_entries *
-                                     sizeof(tp0->info_0_str[0]));
+       ss1->id        = id       ;
+       ss1->type      = type     ;
+       ss1->num_opens = num_opens ;
+       ss1->num_users = num_users;
+       ss1->open_time = open_time;
 
-                       if (tp0->info_0 == NULL || tp0->info_0_str == NULL)
-                       {
-                               free_srv_tprt_info_0(tp0);
-                               return False;
-                       }
-               }
+       ss1->ptr_usr_name = (usr_name != NULL) ? 1 : 0;
+       ss1->ptr_net_name = (net_name != NULL) ? 1 : 0;
+}
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_tprt_info0("", &(tp0->info_0[i]), ps, depth); 
-               }
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_tprt_info0_str("", &(tp0->info_0_str[i]),
-                                                 &(tp0->info_0[i]),
-                                                 ps, depth); 
-               }
+static BOOL srv_io_conn_info1(char *desc, CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+{
+       if (ss1 == NULL)
+               return False;
 
-               prs_align(ps);
-       }
+       prs_debug(ps, depth, desc, "srv_io_conn_info1");
+       depth++;
 
-       if (!ps->io)
-       {
-               /* writing */
-               free_srv_tprt_info_0(tp0);
-       }
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("id          ", ps, depth, &ss1->id))
+               return False;
+       if(!prs_uint32("type        ", ps, depth, &ss1->type))
+               return False;
+       if(!prs_uint32("num_opens   ", ps, depth, &ss1->num_opens))
+               return False;
+       if(!prs_uint32("num_users   ", ps, depth, &ss1->num_users))
+               return False;
+       if(!prs_uint32("open_time   ", ps, depth, &ss1->open_time))
+               return False;
+
+       if(!prs_uint32("ptr_usr_name", ps, depth, &ss1->ptr_usr_name))
+               return False;
+       if(!prs_uint32("ptr_net_name", ps, depth, &ss1->ptr_net_name))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-frees a structure.
+ Reads or writes a structure.
 ********************************************************************/
-void free_srv_tprt_info_0(SRV_TPRT_INFO_0 *tp0)
-{
-       if (tp0->info_0 != NULL)
-       {
-               free(tp0->info_0);
-               tp0->info_0 = NULL;
-       }
-       if (tp0->info_0_str != NULL)
-       {
-               free(tp0->info_0_str);
-               tp0->info_0_str = NULL;
-       }
-}
 
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-static BOOL srv_io_srv_tprt_ctr(char *desc,  SRV_TPRT_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL srv_io_srv_conn_info_1(char *desc, SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ss1 == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_srv_tprt_ctr");
+       prs_debug(ps, depth, desc, "srv_io_srv_conn_info_1");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_tprt_ctr", ps, depth, &(ctr->ptr_tprt_ctr));
+       if(!prs_uint32("num_entries_read", ps, depth, &ss1->num_entries_read))
+               return False;
+       if(!prs_uint32("ptr_conn_info", ps, depth, &ss1->ptr_conn_info))
+               return False;
 
-       if (ctr->ptr_tprt_ctr != 0)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 0:
-                       {
-                               srv_io_srv_tprt_info_0("", &(ctr->tprt.info0), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no transport info at switch_value %d\n",
-                                        tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
+       if (ss1->ptr_conn_info != 0) {
+               int i;
+               int num_entries = ss1->num_entries_read;
+
+               if (num_entries > MAX_CONN_ENTRIES) {
+                       num_entries = MAX_CONN_ENTRIES; /* report this! */
+               }
+
+               if(!prs_uint32("num_entries_read2", ps, depth, &ss1->num_entries_read2))
+                       return False;
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_conn_info1("", &ss1->info_1[i], ps, depth))
+                               return False;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_conn_info1_str("", &ss1->info_1_str[i], ps, depth))
+                               return False;
                }
+
+               if(!prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-void free_srv_tprt_ctr(SRV_TPRT_INFO_CTR *ctr)
+
+static BOOL srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       switch (ctr->switch_value)
-       {
+       if (ctr == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_srv_conn_ctr");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+               return False;
+       if(!prs_uint32("ptr_conn_ctr", ps, depth, &ctr->ptr_conn_ctr))
+               return False;
+
+       if (ctr->ptr_conn_ctr != 0) {
+               switch (ctr->switch_value) {
                case 0:
-               {
-                       free_srv_tprt_info_0(&(ctr->tprt.info0));
+                       if(!srv_io_srv_conn_info_0("", &ctr->conn.info0, ps, depth))
+                               return False;
+                       break;
+               case 1:
+                       if(!srv_io_srv_conn_info_1("", &ctr->conn.info1, ps, depth))
+                               return False;
                        break;
-               }
                default:
-               {
-                       DEBUG(5,("no transport info at switch_value %d\n",
-                                ctr->switch_value));
+                       DEBUG(5,("%s no connection info at switch_value %d\n",
+                                tab_depth(depth), ctr->switch_value));
                        break;
                }
        }
+
+       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+  Reads or writes a structure.
 ********************************************************************/
-BOOL make_srv_q_net_tprt_enum(SRV_Q_NET_TPRT_ENUM *q_n, 
-                               const char *srv_name, 
-                               uint32 tprt_level, SRV_TPRT_INFO_CTR *ctr,
+
+void init_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
+                               uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd)
 {
-       if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
+       DEBUG(5,("init_q_net_conn_enum\n"));
 
        q_n->ctr = ctr;
 
-       DEBUG(5,("make_q_net_tprt_enum\n"));
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name );
+       init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
 
-       make_buf_unistr2(&(q_n->uni_srv_name ), &(q_n->ptr_srv_name ), srv_name );
-
-       q_n->tprt_level    = tprt_level;
+       q_n->conn_level    = conn_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
-
-       return True;
+       memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_q_net_tprt_enum(char *desc,  SRV_Q_NET_TPRT_ENUM *q_n, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_q_net_tprt_enum");
+       prs_debug(ps, depth, desc, "srv_io_q_net_conn_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, q_n->ptr_srv_name, ps, depth))
+               return False;
 
-       prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), q_n->ptr_srv_name, ps, depth); 
+       if(!prs_align(ps))
+               return False;
 
-       prs_align(ps);
+       if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
+               return False;
 
-       prs_uint32("tprt_level", ps, depth, &(q_n->tprt_level  ));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("conn_level", ps, depth, &q_n->conn_level))
+               return False;
        
-       if (((int)q_n->tprt_level) != -1)
-       {
-               srv_io_srv_tprt_ctr("tprt_ctr", q_n->ctr, ps, depth);
+       if (q_n->conn_level != -1) {
+               if(!srv_io_srv_conn_ctr("conn_ctr", q_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+       if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
+               return False;
 
-       smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth); 
+       if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_r_net_tprt_enum(char *desc,  SRV_R_NET_TPRT_ENUM *r_n, prs_struct *ps, int depth)
+
+BOOL srv_io_r_net_conn_enum(char *desc,  SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
-       prs_debug(ps, depth, desc, "srv_io_r_net_tprt_enum");
+       prs_debug(ps, depth, desc, "srv_io_r_net_conn_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("tprt_level", ps, depth, &(r_n->tprt_level));
+       if(!prs_uint32("conn_level", ps, depth, &r_n->conn_level))
+               return False;
 
-       if (((int)r_n->tprt_level) != -1)
-       {
-               srv_io_srv_tprt_ctr("tprt_ctr", r_n->ctr, ps, depth);
+       if (r_n->conn_level != -1) {
+               if(!srv_io_srv_conn_ctr("conn_ctr", r_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
-       smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth); 
-       prs_uint32("status     ", ps, depth, &(r_n->status));
+       if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
+               return False;
+       if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
+               return False;
+       if(!prs_uint32("status     ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a FILE_INFO_3_STR structure
Inits a FILE_INFO_3_STR structure
 ********************************************************************/
-BOOL make_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name)
-{
-       if (fi3 == NULL) return False;
 
-       DEBUG(5,("make_srv_file_info3_str\n"));
-
-       make_unistr2(&(fi3->uni_path_name), path_name, strlen(path_name)+1);
-       make_unistr2(&(fi3->uni_user_name), user_name, strlen(user_name)+1);
+void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name)
+{
+       DEBUG(5,("init_srv_file_info3_str\n"));
 
-       return True;
+       init_unistr2(&fi3->uni_path_name, path_name, strlen(path_name)+1);
+       init_unistr2(&fi3->uni_user_name, user_name, strlen(user_name)+1);
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_file_info3_str(char *desc,  FILE_INFO_3_STR *sh1, prs_struct *ps, int depth)
+
+static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *ps, int depth)
 {
-       if (sh1 == NULL) return False;
+       if (sh1 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_file_info3_str");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("", &(sh1->uni_path_name), True, ps, depth); 
-       smb_io_unistr2("", &(sh1->uni_user_name), True, ps, depth); 
+       if(!smb_io_unistr2("", &sh1->uni_path_name, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("", &sh1->uni_user_name, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a FILE_INFO_3 structure
Inits a FILE_INFO_3 structure
 ********************************************************************/
-BOOL make_srv_file_info3(FILE_INFO_3 *fl3,
+
+void init_srv_file_info3(FILE_INFO_3 *fl3,
                                uint32 id, uint32 perms, uint32 num_locks,
                                char *path_name, char *user_name)
 {
-       if (fl3 == NULL) return False;
-
-       DEBUG(5,("make_srv_file_info3: %s %s\n", path_name, user_name));
+       DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name));
 
        fl3->id        = id;    
        fl3->perms     = perms;
        fl3->num_locks = num_locks;
 
-       fl3->ptr_path_name = path_name != NULL ? 1 : 0;
-       fl3->ptr_user_name = user_name != NULL ? 1 : 0;
-
-       return True;
+       fl3->ptr_path_name = (path_name != NULL) ? 1 : 0;
+       fl3->ptr_user_name = (user_name != NULL) ? 1 : 0;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_file_info3(char *desc,  FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+
+static BOOL srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int depth)
 {
-       if (fl3 == NULL) return False;
+       if (fl3 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_file_info3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("id           ", ps, depth, &(fl3->id           ));
-       prs_uint32("perms        ", ps, depth, &(fl3->perms        ));
-       prs_uint32("num_locks    ", ps, depth, &(fl3->num_locks    ));
-       prs_uint32("ptr_path_name", ps, depth, &(fl3->ptr_path_name));
-       prs_uint32("ptr_user_name", ps, depth, &(fl3->ptr_user_name));
+       if(!prs_uint32("id           ", ps, depth, &fl3->id))
+               return False;
+       if(!prs_uint32("perms        ", ps, depth, &fl3->perms))
+               return False;
+       if(!prs_uint32("num_locks    ", ps, depth, &fl3->num_locks))
+               return False;
+       if(!prs_uint32("ptr_path_name", ps, depth, &fl3->ptr_path_name))
+               return False;
+       if(!prs_uint32("ptr_user_name", ps, depth, &fl3->ptr_user_name))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_file_info_3(char *desc,  SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+
+static BOOL srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
 {
-       if (fl3 == NULL) return False;
+       if (fl3 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_file_3_fl3");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("num_entries_read", ps, depth, &(fl3->num_entries_read));
-       prs_uint32("ptr_file_fl3", ps, depth, &(fl3->ptr_file_info));
-       if (fl3->ptr_file_info != 0)
-       {
-               uint32 i;
-               uint32 num_entries = fl3->num_entries_read;
+       if(!prs_uint32("num_entries_read", ps, depth, &fl3->num_entries_read))
+               return False;
+       if(!prs_uint32("ptr_file_fl3", ps, depth, &fl3->ptr_file_info))
+               return False;
 
-               if (num_entries > MAX_FILE_ENTRIES)
-               {
+       if (fl3->ptr_file_info != 0) {
+               int i;
+               int num_entries = fl3->num_entries_read;
+
+               if (num_entries > MAX_FILE_ENTRIES) {
                        num_entries = MAX_FILE_ENTRIES; /* report this! */
                }
 
-               prs_uint32("num_entries_read2", ps, depth, &(fl3->num_entries_read2));
+               if(!prs_uint32("num_entries_read2", ps, depth, &fl3->num_entries_read2))
+                       return False;
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_file_info3("", &(fl3->info_3[i]), ps, depth); 
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_file_info3("", &fl3->info_3[i], ps, depth))
+                               return False;
                }
 
-               for (i = 0; i < num_entries; i++)
-               {
-                       srv_io_file_info3_str("", &(fl3->info_3_str[i]), ps, depth); 
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_file_info3_str("", &fl3->info_3_str[i], ps, depth))
+                               return False;
                }
 
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-static BOOL srv_io_srv_file_ctr(char *desc,  SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
+
+static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ctr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_file_ctr", ps, depth, &(ctr->ptr_file_ctr));
+       if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+               return False;
+       if(!prs_uint32("ptr_file_ctr", ps, depth, &ctr->ptr_file_ctr))
+               return False;
 
-       if (ctr->ptr_file_ctr != 0)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 3:
-                       {
-                               srv_io_srv_file_info_3("", &(ctr->file.info3), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no file info at switch_value %d\n",
-                                        tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
+       if (ctr->ptr_file_ctr != 0) {
+               switch (ctr->switch_value) {
+               case 3:
+                       if(!srv_io_srv_file_info_3("", &ctr->file.info3, ps, depth))
+                               return False;
+                       break;
+               default:
+                       DEBUG(5,("%s no file info at switch_value %d\n",
+                                tab_depth(depth), ctr->switch_value));
+                       break;
                }
        }
 
@@ -1549,164 +1462,184 @@ static BOOL srv_io_srv_file_ctr(char *desc,  SRV_FILE_INFO_CTR *ctr, prs_struct
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Inits a SRV_Q_NET_FILE_ENUM structure.
 ********************************************************************/
-BOOL make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
-                               const char *srv_name, const char *qual_name,
-                               uint32 file_id,
+
+void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
+                               char *srv_name, char *qual_name,
                                uint32 file_level, SRV_FILE_INFO_CTR *ctr,
                                uint32 preferred_len,
                                ENUM_HND *hnd)
 {
-       if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
+       DEBUG(5,("init_q_net_file_enum\n"));
 
        q_n->ctr = ctr;
 
-       DEBUG(5,("make_q_net_file_enum\n"));
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
 
-       make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
-       make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
-
-       q_n->file_id       = file_id;
        q_n->file_level    = file_level;
        q_n->preferred_len = preferred_len;
 
-       memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
-
-       return True;
+       memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_q_net_file_enum(char *desc,  SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_q_net_file_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth); 
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
-       smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth); 
+       if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("file_id   ", ps, depth, &(q_n->file_id   ));
-       prs_uint32("file_level", ps, depth, &(q_n->file_level));
+       if(!prs_uint32("file_level", ps, depth, &q_n->file_level))
+               return False;
 
-       if (((int)q_n->file_level) != -1)
-       {
-               srv_io_srv_file_ctr("file_ctr", q_n->ctr, ps, depth);
+       if (q_n->file_level != -1) {
+               if(!srv_io_srv_file_ctr("file_ctr", q_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+       if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
+               return False;
 
-       smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth); 
+       if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_r_net_file_enum(char *desc,  SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth)
+
+BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_r_net_file_enum");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("file_level", ps, depth, &(r_n->file_level));
+       if(!prs_uint32("file_level", ps, depth, &r_n->file_level))
+               return False;
 
-       if (r_n->file_level != 0)
-       {
-               srv_io_srv_file_ctr("file_ctr", r_n->ctr, ps, depth);
+       if (r_n->file_level != 0) {
+               if(!srv_io_srv_file_ctr("file_ctr", r_n->ctr, ps, depth))
+                       return False;
        }
 
-       prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
-       smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth); 
-       prs_uint32("status     ", ps, depth, &(r_n->status));
+       if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
+               return False;
+       if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
+               return False;
+       if(!prs_uint32("status     ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a SRV_INFO_101 structure.
Inits a SRV_INFO_101 structure.
  ********************************************************************/
-BOOL make_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
+
+void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
                                uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, char *comment)
 {
-       if (sv101 == NULL) return False;
-
-       DEBUG(5,("make_srv_info_101\n"));
+       DEBUG(5,("init_srv_info_101\n"));
 
        sv101->platform_id  = platform_id;
-       make_buf_unistr2(&(sv101->uni_name    ), &(sv101->ptr_name   ) , name    );
+       init_buf_unistr2(&sv101->uni_name, &sv101->ptr_name, name);
        sv101->ver_major    = ver_major;
        sv101->ver_minor    = ver_minor;
        sv101->srv_type     = srv_type;
-       make_buf_unistr2(&(sv101->uni_comment ), &(sv101->ptr_comment) , comment );
-
-       return True;
+       init_buf_unistr2(&sv101->uni_comment, &sv101->ptr_comment, comment);
 }
 
-
 /*******************************************************************
reads or writes a SRV_INFO_101 structure.
Reads or writes a SRV_INFO_101 structure.
  ********************************************************************/
-static BOOL srv_io_info_101(char *desc,  SRV_INFO_101 *sv101, prs_struct *ps, int depth)
+
+static BOOL srv_io_info_101(char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth)
 {
-       if (sv101 == NULL) return False;
+       if (sv101 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_info_101");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("platform_id ", ps, depth, &(sv101->platform_id ));
-       prs_uint32("ptr_name    ", ps, depth, &(sv101->ptr_name    ));
-       prs_uint32("ver_major   ", ps, depth, &(sv101->ver_major   ));
-       prs_uint32("ver_minor   ", ps, depth, &(sv101->ver_minor   ));
-       prs_uint32("srv_type    ", ps, depth, &(sv101->srv_type    ));
-       prs_uint32("ptr_comment ", ps, depth, &(sv101->ptr_comment ));
+       if(!prs_uint32("platform_id ", ps, depth, &sv101->platform_id))
+               return False;
+       if(!prs_uint32("ptr_name    ", ps, depth, &sv101->ptr_name))
+               return False;
+       if(!prs_uint32("ver_major   ", ps, depth, &sv101->ver_major))
+               return False;
+       if(!prs_uint32("ver_minor   ", ps, depth, &sv101->ver_minor))
+               return False;
+       if(!prs_uint32("srv_type    ", ps, depth, &sv101->srv_type))
+               return False;
+       if(!prs_uint32("ptr_comment ", ps, depth, &sv101->ptr_comment))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       smb_io_unistr2("uni_name    ", &(sv101->uni_name    ), True, ps, depth); 
-       smb_io_unistr2("uni_comment ", &(sv101->uni_comment ), True, ps, depth); 
+       if(!smb_io_unistr2("uni_name    ", &sv101->uni_name, True, ps, depth))
+               return False;
+       if(!smb_io_unistr2("uni_comment ", &sv101->uni_comment, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a SRV_INFO_102 structure.
Inits a SRV_INFO_102 structure.
  ********************************************************************/
-BOOL make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
+
+void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
                                char *comment, uint32 ver_major, uint32 ver_minor,
                                uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
                                uint32 announce, uint32 ann_delta, uint32 licenses,
                                char *usr_path)
 {
-       if (sv102 == NULL) return False;
-
-       DEBUG(5,("make_srv_info_102\n"));
+       DEBUG(5,("init_srv_info_102\n"));
 
        sv102->platform_id  = platform_id;
-       make_buf_unistr2(&(sv102->uni_name    ), &(sv102->ptr_name    ), name    );
+       init_buf_unistr2(&sv102->uni_name, &sv102->ptr_name, name);
        sv102->ver_major    = ver_major;
        sv102->ver_minor    = ver_minor;
        sv102->srv_type     = srv_type;
-       make_buf_unistr2(&(sv102->uni_comment ), &(sv102->ptr_comment ), comment );
+       init_buf_unistr2(&sv102->uni_comment, &sv102->ptr_comment, comment);
 
        /* same as 101 up to here */
 
@@ -1716,250 +1649,277 @@ BOOL make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
        sv102->announce     = announce;
        sv102->ann_delta    =ann_delta;
        sv102->licenses     = licenses;
-       make_buf_unistr2(&(sv102->uni_usr_path), &(sv102->ptr_usr_path), usr_path);
-
-       return True;
+       init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path);
 }
 
 
 /*******************************************************************
reads or writes a SRV_INFO_102 structure.
Reads or writes a SRV_INFO_102 structure.
  ********************************************************************/
-static BOOL srv_io_info_102(char *desc,  SRV_INFO_102 *sv102, prs_struct *ps, int depth)
+
+static BOOL srv_io_info_102(char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth)
 {
-       if (sv102 == NULL) return False;
+       if (sv102 == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_info102");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("platform_id ", ps, depth, &(sv102->platform_id ));
-       prs_uint32("ptr_name    ", ps, depth, &(sv102->ptr_name    ));
-       prs_uint32("ver_major   ", ps, depth, &(sv102->ver_major   ));
-       prs_uint32("ver_minor   ", ps, depth, &(sv102->ver_minor   ));
-       prs_uint32("srv_type    ", ps, depth, &(sv102->srv_type    ));
-       prs_uint32("ptr_comment ", ps, depth, &(sv102->ptr_comment ));
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("platform_id ", ps, depth, &sv102->platform_id))
+               return False;
+       if(!prs_uint32("ptr_name    ", ps, depth, &sv102->ptr_name))
+               return False;
+       if(!prs_uint32("ver_major   ", ps, depth, &sv102->ver_major))
+               return False;
+       if(!prs_uint32("ver_minor   ", ps, depth, &sv102->ver_minor))
+               return False;
+       if(!prs_uint32("srv_type    ", ps, depth, &sv102->srv_type))
+               return False;
+       if(!prs_uint32("ptr_comment ", ps, depth, &sv102->ptr_comment))
+               return False;
 
        /* same as 101 up to here */
 
-       prs_uint32("users       ", ps, depth, &(sv102->users       ));
-       prs_uint32("disc        ", ps, depth, &(sv102->disc        ));
-       prs_uint32("hidden      ", ps, depth, &(sv102->hidden      ));
-       prs_uint32("announce    ", ps, depth, &(sv102->announce    ));
-       prs_uint32("ann_delta   ", ps, depth, &(sv102->ann_delta   ));
-       prs_uint32("licenses    ", ps, depth, &(sv102->licenses    ));
-       prs_uint32("ptr_usr_path", ps, depth, &(sv102->ptr_usr_path));
-
-       smb_io_unistr2("uni_name    ", &(sv102->uni_name    ), True, ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("uni_comment ", &(sv102->uni_comment ), True, ps, depth); 
-       prs_align(ps);
-       smb_io_unistr2("uni_usr_path", &(sv102->uni_usr_path), True, ps, depth); 
-
-       return True;
-}
-
-/*******************************************************************
- reads or writes a SRV_INFO_102 structure.
+       if(!prs_uint32("users       ", ps, depth, &sv102->users))
+               return False;
+       if(!prs_uint32("disc        ", ps, depth, &sv102->disc))
+               return False;
+       if(!prs_uint32("hidden      ", ps, depth, &sv102->hidden))
+               return False;
+       if(!prs_uint32("announce    ", ps, depth, &sv102->announce))
+               return False;
+       if(!prs_uint32("ann_delta   ", ps, depth, &sv102->ann_delta))
+               return False;
+       if(!prs_uint32("licenses    ", ps, depth, &sv102->licenses))
+               return False;
+       if(!prs_uint32("ptr_usr_path", ps, depth, &sv102->ptr_usr_path))
+               return False;
+
+       if(!smb_io_unistr2("uni_name    ", &sv102->uni_name, True, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!smb_io_unistr2("uni_comment ", &sv102->uni_comment, True, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+       if(!smb_io_unistr2("uni_usr_path", &sv102->uni_usr_path, True, ps, depth))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes a SRV_INFO_102 structure.
  ********************************************************************/
-static BOOL srv_io_info_ctr(char *desc,  SRV_INFO_CTR *ctr, prs_struct *ps, int depth)
+
+static BOOL srv_io_info_ctr(char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth)
 {
-       if (ctr == NULL) return False;
+       if (ctr == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_info_ctr");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
-       prs_uint32("ptr_srv_ctr ", ps, depth, &(ctr->ptr_srv_ctr ));
+       if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
+               return False;
+       if(!prs_uint32("ptr_srv_ctr ", ps, depth, &ctr->ptr_srv_ctr))
+               return False;
 
-       if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL)
-       {
-               switch (ctr->switch_value)
-               {
-                       case 101:
-                       {
-                               srv_io_info_101("sv101", &(ctr->srv.sv101), ps, depth); 
-                               break;
-                       }
-                       case 102:
-                       {
-                               srv_io_info_102("sv102", &(ctr->srv.sv102), ps, depth); 
-                               break;
-                       }
-                       default:
-                       {
-                               DEBUG(5,("%s no server info at switch_value %d\n",
-                                                tab_depth(depth), ctr->switch_value));
-                               break;
-                       }
+       if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL) {
+               switch (ctr->switch_value) {
+               case 101:
+                       if(!srv_io_info_101("sv101", &ctr->srv.sv101, ps, depth))
+                               return False;
+                       break;
+               case 102:
+                       if(!srv_io_info_102("sv102", &ctr->srv.sv102, ps, depth))
+                               return False;
+                       break;
+               default:
+                       DEBUG(5,("%s no server info at switch_value %d\n",
+                                        tab_depth(depth), ctr->switch_value));
+                       break;
                }
-               prs_align(ps);
+               if(!prs_align(ps))
+                       return False;
        }
 
        return True;
 }
 
 /*******************************************************************
makes a SRV_Q_NET_SRV_GET_INFO structure.
Inits a SRV_Q_NET_SRV_GET_INFO structure.
  ********************************************************************/
-BOOL make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+
+void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
                                char *server_name, uint32 switch_value)
 {
-       if (srv == NULL) return False;
+       DEBUG(5,("init_srv_q_net_srv_get_info\n"));
 
-       DEBUG(5,("make_srv_q_net_srv_get_info\n"));
-
-       make_buf_unistr2(&(srv->uni_srv_name), &(srv->ptr_srv_name), server_name);
+       init_buf_unistr2(&srv->uni_srv_name, &srv->ptr_srv_name, server_name);
 
        srv->switch_value = switch_value;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL srv_io_q_net_srv_get_info(char *desc,  SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_q_net_srv_get_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_srv_name  ", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth); 
+       if(!prs_uint32("ptr_srv_name  ", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("switch_value  ", ps, depth, &(q_n->switch_value));
+       if(!prs_uint32("switch_value  ", ps, depth, &q_n->switch_value))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
makes a SRV_R_NET_SRV_GET_INFO structure.
Inits a SRV_R_NET_SRV_GET_INFO structure.
  ********************************************************************/
-BOOL make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+
+void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
                                uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status)
 {
-       if (srv == NULL) return False;
-
-       DEBUG(5,("make_srv_r_net_srv_get_info\n"));
+       DEBUG(5,("init_srv_r_net_srv_get_info\n"));
 
        srv->ctr = ctr;
 
-       if (status == 0x0)
-       {
+       if (status == 0x0) {
                srv->ctr->switch_value = switch_value;
                srv->ctr->ptr_srv_ctr  = 1;
-       }
-       else
-       {
+       } else {
                srv->ctr->switch_value = 0;
                srv->ctr->ptr_srv_ctr  = 0;
        }
 
        srv->status = status;
-
-       return True;
 }
 
 /*******************************************************************
reads or writes a structure.
Reads or writes a structure.
  ********************************************************************/
-BOOL srv_io_r_net_srv_get_info(char *desc,  SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth)
+
+BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_r_net_srv_get_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       srv_io_info_ctr("ctr", r_n->ctr, ps, depth); 
+       if(!srv_io_info_ctr("ctr", r_n->ctr, ps, depth))
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_n->status      ));
+       if(!prs_uint32("status      ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
 
-/*******************************************************************
- makes a SRV_Q_NET_REMOTE_TOD structure.
- ********************************************************************/
-BOOL make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name)
-{
-       if (q_t == NULL) return False;
-
-       DEBUG(5,("make_srv_q_net_remote_tod\n"));
-
-       make_buf_unistr2(&(q_t->uni_srv_name), &(q_t->ptr_srv_name), server_name);
-
-       return True;
-}
 
 /*******************************************************************
reads or writes a structure.
Reads or writes a structure.
  ********************************************************************/
-BOOL srv_io_q_net_remote_tod(char *desc,  SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth)
+
+BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL) return False;
+       if (q_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_q_net_remote_tod");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_srv_name  ", ps, depth, &(q_n->ptr_srv_name));
-       smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth); 
+       if(!prs_uint32("ptr_srv_name  ", ps, depth, &q_n->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
reads or writes a TIME_OF_DAY_INFO structure.
Reads or writes a TIME_OF_DAY_INFO structure.
  ********************************************************************/
-static BOOL srv_io_time_of_day_info(char *desc, TIME_OF_DAY_INFO  *tod, prs_struct *ps, int depth)
+
+static BOOL srv_io_time_of_day_info(char *desc, TIME_OF_DAY_INFO *tod, prs_struct *ps, int depth)
 {
-       if (tod == NULL) return False;
+       if (tod == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_time_of_day_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("elapsedt   ", ps, depth, &(tod->elapsedt  ));
-       prs_uint32("msecs      ", ps, depth, &(tod->msecs     ));
-       prs_uint32("hours      ", ps, depth, &(tod->hours     ));
-       prs_uint32("mins       ", ps, depth, &(tod->mins      ));
-       prs_uint32("secs       ", ps, depth, &(tod->secs      ));
-       prs_uint32("hunds      ", ps, depth, &(tod->hunds     ));
-       prs_uint32("timezone   ", ps, depth, &(tod->zone  ));
-       prs_uint32("tintervals ", ps, depth, &(tod->tintervals));
-       prs_uint32("day        ", ps, depth, &(tod->day       ));
-       prs_uint32("month      ", ps, depth, &(tod->month     ));
-       prs_uint32("year       ", ps, depth, &(tod->year      ));
-       prs_uint32("weekday    ", ps, depth, &(tod->weekday   ));
-
-
-       return True;
-}
-
-/*******************************************************************
- makes a TIME_OF_DAY_INFO structure.
+       if(!prs_uint32("elapsedt   ", ps, depth, &tod->elapsedt))
+               return False;
+       if(!prs_uint32("msecs      ", ps, depth, &tod->msecs))
+               return False;
+       if(!prs_uint32("hours      ", ps, depth, &tod->hours))
+               return False;
+       if(!prs_uint32("mins       ", ps, depth, &tod->mins))
+               return False;
+       if(!prs_uint32("secs       ", ps, depth, &tod->secs))
+               return False;
+       if(!prs_uint32("hunds      ", ps, depth, &tod->hunds))
+               return False;
+       if(!prs_uint32("timezone   ", ps, depth, &tod->zone))
+               return False;
+       if(!prs_uint32("tintervals ", ps, depth, &tod->tintervals))
+               return False;
+       if(!prs_uint32("day        ", ps, depth, &tod->day))
+               return False;
+       if(!prs_uint32("month      ", ps, depth, &tod->month))
+               return False;
+       if(!prs_uint32("year       ", ps, depth, &tod->year))
+               return False;
+       if(!prs_uint32("weekday    ", ps, depth, &tod->weekday))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Inits a TIME_OF_DAY_INFO structure.
  ********************************************************************/
-BOOL make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
+
+void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
                            uint32 hours, uint32 mins, uint32 secs, uint32 hunds,
                           uint32 zone, uint32 tintervals, uint32 day,
                           uint32 month, uint32 year, uint32 weekday)
 {
-       if (tod == NULL) return False;
-
-       DEBUG(5,("make_time_of_day_info\n"));
+       DEBUG(5,("init_time_of_day_info\n"));
 
        tod->elapsedt   = elapsedt;
        tod->msecs      = msecs;
@@ -1973,28 +1933,32 @@ BOOL make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
        tod->month      = month;
        tod->year       = year;
        tod->weekday    = weekday;
-
-       return True;
 }
 
 
 /*******************************************************************
reads or writes a structure.
Reads or writes a structure.
  ********************************************************************/
+
 BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth)
 {
-       if (r_n == NULL) return False;
+       if (r_n == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "srv_io_r_net_remote_tod");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
        
-       prs_uint32("ptr_srv_tod ", ps, depth, &(r_n->ptr_srv_tod));
+       if(!prs_uint32("ptr_srv_tod ", ps, depth, &r_n->ptr_srv_tod))
+               return False;
 
-       srv_io_time_of_day_info("tod", r_n->tod, ps, depth); 
+       if(!srv_io_time_of_day_info("tod", r_n->tod, ps, depth))
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_n->status));
+       if(!prs_uint32("status      ", ps, depth, &r_n->status))
+               return False;
 
        return True;
 }
index 91409e2eec5f5f2fa1a7fe7644803a34cb80cef5..7357e3d2f3a2893b2ebca68ca47c3bc2883e69ab 100644 (file)
@@ -3,9 +3,9 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1999,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
- *  Copyright (C) Paul Ashton                  1997-1999.
+ *  Copyright (C) Andrew Tridgell              1992-1997,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Paul Ashton                       1997.
  *  
  *  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
 extern int DEBUGLEVEL;
 
 /*******************************************************************
- make_wks_q_query_info
+ Init
  ********************************************************************/
-BOOL make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+
+void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
                                char *server, uint16 switch_value)  
 {
-       DEBUG(5,("make_wks_q_query_info\n"));
+       DEBUG(5,("init_wks_q_query_info\n"));
 
-       make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
+       init_buf_unistr2(&q_u->uni_srv_name, &q_u->ptr_srv_name, server);
        q_u->switch_value = switch_value;
-
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a WKS_Q_QUERY_INFO structure.
+ Reads or writes a WKS_Q_QUERY_INFO structure.
 ********************************************************************/
+
 BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth)
 {
-       if (q_u == NULL) return False;
+       if (q_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "wks_io_q_query_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       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); 
-       prs_align(ps);
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
-       prs_align(ps);
+       if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
@@ -67,60 +73,72 @@ BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int
 /*******************************************************************
  wks_info_100
  ********************************************************************/
-BOOL make_wks_info_100(WKS_INFO_100 *inf,
+
+void init_wks_info_100(WKS_INFO_100 *inf,
                                uint32 platform_id, uint32 ver_major, uint32 ver_minor,
                                char *my_name, char *domain_name)
 {
-       DEBUG(5,("WKS_INFO_100: %d\n", __LINE__));
+       DEBUG(5,("Init WKS_INFO_100: %d\n", __LINE__));
 
        inf->platform_id = platform_id; /* 0x0000 01f4 - unknown */
        inf->ver_major   = ver_major;   /* os major version */
        inf->ver_minor   = ver_minor;   /* os minor version */
 
-       make_buf_unistr2(&(inf->uni_compname), &(inf->ptr_compname), my_name    );
-       make_buf_unistr2(&(inf->uni_lan_grp ), &(inf->ptr_lan_grp ), domain_name);
-
-       return True;
+       init_buf_unistr2(&inf->uni_compname, &inf->ptr_compname, my_name    );
+       init_buf_unistr2(&inf->uni_lan_grp, &inf->ptr_lan_grp, domain_name);
 }
 
 /*******************************************************************
-reads or writes a WKS_INFO_100 structure.
+ Reads or writes a WKS_INFO_100 structure.
 ********************************************************************/
+
 static BOOL wks_io_wks_info_100(char *desc, WKS_INFO_100 *inf, prs_struct *ps, int depth)
 {
-       if (inf == NULL) return False;
+       if (inf == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "wks_io_wks_info_100");
        depth++;
 
-       prs_align(ps);
-
-       prs_uint32("platform_id ", ps, depth, &(inf->platform_id )); /* 0x0000 01f4 - unknown */
-       prs_uint32("ptr_compname", ps, depth, &(inf->ptr_compname)); /* pointer to computer name */
-       prs_uint32("ptr_lan_grp ", ps, depth, &(inf->ptr_lan_grp )); /* pointer to LAN group name */
-       prs_uint32("ver_major   ", ps, depth, &(inf->ver_major   )); /* 4 - major os version */
-       prs_uint32("ver_minor   ", ps, depth, &(inf->ver_minor   )); /* 0 - minor os version */
-
-       smb_io_unistr2("", &(inf->uni_compname), inf->ptr_compname, ps, depth); 
-       prs_align(ps);
-
-       smb_io_unistr2("", &(inf->uni_lan_grp ), inf->ptr_lan_grp , ps, depth); 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("platform_id ", ps, depth, &inf->platform_id)) /* 0x0000 01f4 - unknown */
+               return False;
+       if(!prs_uint32("ptr_compname", ps, depth, &inf->ptr_compname)) /* pointer to computer name */
+               return False;
+       if(!prs_uint32("ptr_lan_grp ", ps, depth, &inf->ptr_lan_grp)) /* pointer to LAN group name */
+               return False;
+       if(!prs_uint32("ver_major   ", ps, depth, &inf->ver_major)) /* 4 - major os version */
+               return False;
+       if(!prs_uint32("ver_minor   ", ps, depth, &inf->ver_minor)) /* 0 - minor os version */
+               return False;
+
+       if(!smb_io_unistr2("", &inf->uni_compname, inf->ptr_compname, ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_unistr2("", &inf->uni_lan_grp, inf->ptr_lan_grp , ps, depth))
+               return False;
+       if(!prs_align(ps))
+               return False;
 
        return True;
 }
 
 /*******************************************************************
- make_wks_r_query_info
+ Inits WKS_R_QUERY_INFO.
 
  only supports info level 100 at the moment.
 
  ********************************************************************/
-BOOL make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+
+void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
                                uint32 switch_value, WKS_INFO_100 *wks100,
                                int status)  
 {
-       DEBUG(5,("make_wks_r_unknown_0: %d\n", __LINE__));
+       DEBUG(5,("init_wks_r_unknown_0: %d\n", __LINE__));
 
        r_u->switch_value = switch_value;  /* same as in request */
 
@@ -128,30 +146,35 @@ BOOL make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
        r_u->wks100    = wks100;
 
        r_u->status    = status;
-
-       return True;
 }
 
 /*******************************************************************
-reads or writes a structure.
+ Reads or writes a structure.
 ********************************************************************/
-BOOL wks_io_r_query_info(char *desc,  WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
+
+BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
 {
-       if (r_u == NULL) return False;
+       if (r_u == NULL)
+               return False;
 
        prs_debug(ps, depth, desc, "wks_io_r_query_info");
        depth++;
 
-       prs_align(ps);
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint16("switch_value", ps, depth, &(r_u->switch_value)); /* level 100 (0x64) */
-       prs_align(ps);
+       if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value)) /* level 100 (0x64) */
+               return False;
+       if(!prs_align(ps))
+               return False;
 
-       prs_uint32("ptr_1       ", ps, depth, &(r_u->ptr_1       )); /* pointer 1 */
-       wks_io_wks_info_100("inf", r_u->wks100, ps, depth);
+       if(!prs_uint32("ptr_1       ", ps, depth, &r_u->ptr_1)) /* pointer 1 */
+               return False;
+       if(!wks_io_wks_info_100("inf", r_u->wks100, ps, depth))
+               return False;
 
-       prs_uint32("status      ", ps, depth, &(r_u->status));
+       if(!prs_uint32("status      ", ps, depth, &r_u->status))
+               return False;
 
        return True;
 }
-
index 193c7931abac1a83e4cc7dc0405fde7adec5e6e8..e6df9933bff94605ba193c38af206e623585c4b5 100644 (file)
@@ -52,6 +52,44 @@ extern fstring global_sam_name;
 extern DOM_SID global_sam_sid;
 extern DOM_SID global_sid_S_1_5_20;
 
+/*
+ * A list of the rids of well known BUILTIN and Domain users
+ * and groups.
+ */
+
+rid_name builtin_alias_rids[] =
+{  
+    { BUILTIN_ALIAS_RID_ADMINS       , "Administrators" },
+    { BUILTIN_ALIAS_RID_USERS        , "Users" },
+    { BUILTIN_ALIAS_RID_GUESTS       , "Guests" },
+    { BUILTIN_ALIAS_RID_POWER_USERS  , "Power Users" },
+   
+    { BUILTIN_ALIAS_RID_ACCOUNT_OPS  , "Account Operators" },
+    { BUILTIN_ALIAS_RID_SYSTEM_OPS   , "System Operators" },
+    { BUILTIN_ALIAS_RID_PRINT_OPS    , "Print Operators" },
+    { BUILTIN_ALIAS_RID_BACKUP_OPS   , "Backup Operators" },
+    { BUILTIN_ALIAS_RID_REPLICATOR   , "Replicator" },
+    { 0                             , NULL }
+};
+
+/* array lookup of well-known Domain RID users. */
+rid_name domain_user_rids[] =
+{  
+    { DOMAIN_USER_RID_ADMIN         , "Administrator" },
+    { DOMAIN_USER_RID_GUEST         , "Guest" },
+    { 0                             , NULL }
+};
+
+/* array lookup of well-known Domain RID groups. */
+rid_name domain_group_rids[] =
+{  
+    { DOMAIN_GROUP_RID_ADMINS       , "Domain Admins" },
+    { DOMAIN_GROUP_RID_USERS        , "Domain Users" },
+    { DOMAIN_GROUP_RID_GUESTS       , "Domain Guests" },
+    { 0                             , NULL }
+};
+
+
 int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
 {
        int count;
@@ -72,27 +110,17 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
                uint32 status;
 
                uint32 rid;
-               DOM_SID sid;
                uint8  type;
 
                uint8  attr  = mem[count].attr;
                char   *name = mem[count].name;
 
                become_root(True);
-               status = lookup_name(name, &sid, &type);
+               status = lookup_grp_rid(name, &rid, &type);
                unbecome_root(True);
 
-               if (status == 0x0 && !sid_front_equal(&global_sam_sid, &sid))
-               {
-                       fstring sid_str;
-                       sid_to_string(sid_str, &sid);
-                       DEBUG(1,("make_dom_gids: unknown sid %s for groupname %s\n",
-                                 sid_str, name));
-               }
-               else if (status == 0x0)
+               if (status == 0x0)
                {
-                       sid_split_rid(&sid, &rid);
-
                        gids = (DOM_GID *)Realloc( gids, sizeof(DOM_GID) * (count+1) );
 
                        if (gids == NULL)
@@ -110,7 +138,7 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
                }
                else
                {
-                       DEBUG(1,("make_dom_gids: unknown groupname %s\n", name));
+                       DEBUG(1,("make_dom_gids: unknown group name %s\n", name));
                }
        }
 
@@ -140,286 +168,282 @@ int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid)
 
 
 /*******************************************************************
- lookup_builtin_sid
+ lookup_builtin_names
  ********************************************************************/
-uint32 lookup_builtin_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_builtin_names(uint32 rid, char *name, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       status = (status != 0x0) ? lookup_wk_user_sid (sid, name, type) : status;
-       status = (status != 0x0) ? lookup_wk_group_sid(sid, name, type) : status;
-       status = (status != 0x0) ? lookup_wk_alias_sid(sid, name, type) : status;
+       status = (status != 0x0) ? lookup_wk_user_name (rid, name, type) : status;
+       status = (status != 0x0) ? lookup_wk_group_name(rid, name, type) : status;
+       status = (status != 0x0) ? lookup_wk_alias_name(rid, name, type) : status;
 
        return status;
 }
 
 
 /*******************************************************************
- lookup_added_sid - names that have been added to the SAM database by admins.
+ lookup_added_name - names that have been added to the SAM database by admins.
  ********************************************************************/
-uint32 lookup_added_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_added_name(uint32 rid, char *name, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       status = (status != 0x0) ? lookup_user_sid (sid, name, type) : status;
-       status = (status != 0x0) ? lookup_group_sid(sid, name, type) : status;
-       status = (status != 0x0) ? lookup_alias_sid(sid, name, type) : status;
+       status = (status != 0x0) ? lookup_user_name (rid, name, type) : status;
+       status = (status != 0x0) ? lookup_group_name(rid, name, type) : status;
+       status = (status != 0x0) ? lookup_alias_name(rid, name, type) : status;
 
        return status;
 }
 
 
 /*******************************************************************
- lookup_sid
+ lookup_name
  ********************************************************************/
-uint32 lookup_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_name(uint32 rid, char *name, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       status = (status != 0x0) ? lookup_builtin_sid(sid, name, type) : status;
-       status = (status != 0x0) ? lookup_added_sid   (sid, name, type) : status;
+       status = (status != 0x0) ? lookup_builtin_names(rid, name, type) : status;
+       status = (status != 0x0) ? lookup_added_name   (rid, name, type) : status;
 
        return status;
 }
 
 
 /*******************************************************************
- lookup_wk_group_sid
+ lookup_wk_group_name
  ********************************************************************/
-uint32 lookup_wk_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
+uint32 lookup_wk_group_name(uint32 rid, char *group_name, uint8 *type)
 {
-       uint32 rid;
-       DOM_SID tmp;
-       char    *mapped;
+       int i = 0; 
+       (*type) = SID_NAME_WKN_GRP;
 
-       (*type) = SID_NAME_DOM_GRP;
-
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       DEBUG(5,("lookup_wk_group_name: rid: %d", rid));
 
-       if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+       while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
        {
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               i++;
        }
 
-       DEBUG(5,("lookup_wk_group_sid: rid: %d", rid));
-
-       /* look up the well-known domain group rids first */
-       mapped = lookup_wk_group_rid(rid);
-       if(mapped == NULL)
+       if (domain_group_rids[i].rid != 0)
        {
-               DEBUG(5,(" none mapped\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               fstrcpy(group_name, domain_group_rids[i].name);
+               DEBUG(5,(" = %s\n", group_name));
+               return 0x0;
        }
-       fstrcpy(group_name, mapped);
-       DEBUG(5,(" = %s\n", group_name));
-       return 0x0;
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
 }
 
 /*******************************************************************
- lookup_group_sid
+ lookup_group_name
  ********************************************************************/
-uint32 lookup_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
+uint32 lookup_group_name(uint32 rid, char *group_name, uint8 *type)
 {
-       pstring sid_str;
-       uint32 rid;
-       DOM_SID tmp;
-       DOMAIN_GRP *grp = NULL;
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+       DOM_SID sid;
 
-       (*type) = SID_NAME_DOM_GRP;
+       DEBUG(5,("lookup_group_name: rid: 0x%x", rid));
 
-       sid_to_string(sid_str, sid);
-       DEBUG(5,("lookup_group_sid: sid: %s", sid_str));
+       sid_copy      (&sid, &global_sam_sid);
+       sid_append_rid(&sid, rid);
 
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       (*type) = SID_NAME_DOM_GRP;
 
-       if (!sid_equal(&global_sam_sid, &tmp))
+       if (map_group_sid_to_name(&sid, group_name, NULL))
        {
-               DEBUG(5,("not our SID\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               status = 0x0;
        }
 
-       grp = getgrouprid(rid, NULL, NULL);
-
-       if (grp != NULL)
+       if (status == 0x0)
        {
-               fstrcpy(group_name, grp->name);
                DEBUG(5,(" = %s\n", group_name));
-               return 0x0;
+       }
+       else
+       {
+               DEBUG(5,(" none mapped\n"));
        }
 
-       DEBUG(5,(" none mapped\n"));
        return status;
 }
 
 /*******************************************************************
- lookup_wk_alias_sid
+ lookup_wk_alias_name
  ********************************************************************/
-uint32 lookup_wk_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
+uint32 lookup_wk_alias_name(uint32 rid, char *alias_name, uint8 *type)
 {
-       uint32 rid;
-       DOM_SID tmp;
-       char    *mapped;
-
+       int i = 0; 
        (*type) = SID_NAME_ALIAS;
 
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       DEBUG(5,("lookup_wk_alias_name: rid: %d", rid));
 
-       if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+       while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
        {
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               i++;
        }
 
-       DEBUG(5,("lookup_wk_alias_sid: rid: %d", rid));
-
-       /* look up the well-known alias group rids first */
-       mapped = lookup_wk_alias_rid(rid);
-       if(mapped == NULL)
+       if (builtin_alias_rids[i].rid != 0)
        {
-               DEBUG(5,(" none mapped\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               fstrcpy(alias_name, builtin_alias_rids[i].name);
+               DEBUG(5,(" = %s\n", alias_name));
+               return 0x0;
        }
-       fstrcpy(alias_name, mapped);
-       DEBUG(5,(" = %s\n", alias_name));
-       return 0x0;
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
 }
 
 /*******************************************************************
- lookup_alias_sid
+ lookup_alias_name
  ********************************************************************/
-uint32 lookup_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint8 *type)
 {
-       pstring sid_str;
-       uint32 rid;
-       DOM_SID tmp;
-       LOCAL_GRP *als = NULL;
-       uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
        (*type) = SID_NAME_ALIAS;
 
-       sid_to_string(sid_str, sid);
-       DEBUG(5,("lookup_alias_sid: sid: %s", sid_str));
+       DEBUG(2,("lookup_alias_name: rid: %d\n", rid));
+       DEBUG(2,(" NOT IMPLEMENTED\n"));
 
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
 
-       if (!sid_equal(&global_sam_sid, &tmp))
+/*******************************************************************
+ lookup well-known user name
+ ********************************************************************/
+uint32 lookup_wk_user_name(uint32 rid, char *user_name, uint8 *type)
+{
+       int i = 0;
+       (*type) = SID_NAME_USER;
+
+       DEBUG(5,("lookup_wk_user_name: rid: %d", rid));
+
+       /* look up the well-known domain user rids first */
+       while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
        {
-               DEBUG(5,("not our SID\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               i++;
        }
 
-       als = getaliasrid(rid, NULL, NULL);
-
-       if (als != NULL)
+       if (domain_user_rids[i].rid != 0)
        {
-               fstrcpy(alias_name, als->name);
-               DEBUG(5,(" = %s\n", alias_name));
+               fstrcpy(user_name, domain_user_rids[i].name);
+               DEBUG(5,(" = %s\n", user_name));
                return 0x0;
        }
 
        DEBUG(5,(" none mapped\n"));
-       return status;
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
 }
 
 /*******************************************************************
- lookup well-known user name
+ lookup user name
  ********************************************************************/
-uint32 lookup_wk_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
+uint32 lookup_user_name(uint32 rid, char *user_name, uint8 *type)
 {
-       uint32 rid;
-       DOM_SID tmp;
-       char    *mapped;
-
+       struct sam_disp_info *disp_info;
        (*type) = SID_NAME_USER;
 
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       DEBUG(5,("lookup_user_name: rid: %d", rid));
 
-       if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+       /* find the user account */
+       become_root(True);
+       disp_info = getsamdisprid(rid);
+       unbecome_root(True);
+
+       if (disp_info != NULL)
        {
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               fstrcpy(user_name, disp_info->smb_name);
+               DEBUG(5,(" = %s\n", user_name));
+               return 0x0;
        }
 
-       DEBUG(5,("lookup_wk_user_sid: rid: %d", rid));
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
 
-       /* look up the well-known domain user rids first */
-       mapped = lookup_wk_user_rid(rid);
-       if(mapped == NULL)
+/*******************************************************************
+ lookup_group_rid
+ ********************************************************************/
+uint32 lookup_group_rid(char *group_name, uint32 *rid, uint8 *type)
+{
+       DOM_SID sid;
+
+       (*rid) = 0;
+       (*type) = SID_NAME_DOM_GRP;
+
+       DEBUG(5,("lookup_group_rid: name: %s", group_name));
+
+       if (map_group_name_to_sid(group_name, &sid) &&
+           sid_split_rid(&sid, rid) &&
+           sid_equal(&sid, &global_sam_sid))
        {
-               DEBUG(5,(" none mapped\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               DEBUG(5,(" = 0x%x\n", (*rid)));
+               return 0x0;
        }
-       fstrcpy(user_name, mapped);
-       DEBUG(5,(" = %s\n", user_name));
-       return 0x0;
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
 }
 
 /*******************************************************************
- lookup user name
+ lookup_wk_group_rid
  ********************************************************************/
-uint32 lookup_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
+uint32 lookup_wk_group_rid(char *group_name, uint32 *rid, uint8 *type)
 {
-       struct sam_disp_info *disp_info;
-       uint32 rid;
-       DOM_SID tmp;
+       char *grp_name;
+       int i = -1; /* start do loop at -1 */
+       (*rid) = 0;
+       (*type) = SID_NAME_WKN_GRP;
 
-       (*type) = SID_NAME_USER;
+       do /* find, if it exists, a group rid for the group name */
+       {
+               i++;
+               (*rid) = domain_group_rids[i].rid;
+               grp_name = domain_group_rids[i].name;
 
-       sid_copy(&tmp, sid);
-       sid_split_rid(&tmp, &rid);
+       } while (grp_name != NULL && !strequal(grp_name, group_name));
 
-       if (sid_equal(&global_sam_sid, &tmp))
-       {
-               DEBUG(5,("lookup_user_sid in SAM %s: rid: %d",
-                         global_sam_name, rid));
+       return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
 
-               /* find the user account */
-               become_root(True);
-               disp_info = getsamdisprid(rid);
-               unbecome_root(True);
+/*******************************************************************
+ lookup_alias_sid
+ ********************************************************************/
+uint32 lookup_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
+{
+       (*type) = SID_NAME_ALIAS;
 
-               if (disp_info != NULL)
-               {
-                       fstrcpy(user_name, disp_info->nt_name);
-                       DEBUG(5,(" = %s\n", user_name));
-                       return 0x0;
-               }
+       DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
 
-               DEBUG(5,(" none mapped\n"));
+       if (map_alias_name_to_sid(alias_name, sid))
+       {
+               fstring sid_str;
+               sid_to_string(sid_str, sid);
+               DEBUG(5,(" = %s\n", sid_str));
+               return 0x0;
        }
 
+       DEBUG(5,(" none mapped\n"));
        return 0xC0000000 | NT_STATUS_NONE_MAPPED;
 }
 
 /*******************************************************************
- lookup_group_rid
+ lookup_alias_rid
  ********************************************************************/
-uint32 lookup_added_group_name(const char *grp_name, const char *domain,
-                               DOM_SID *sid, uint8 *type)
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
 {
-       DOMAIN_GRP *grp = NULL;
-       (*type) = SID_NAME_DOM_GRP;
-
-       DEBUG(5,("lookup_added_group_name: name: %s", grp_name));
+       DOM_SID sid;
 
-       if (!strequal(domain, global_sam_name))
-       {
-               DEBUG(5,(" not our domain\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
+       (*rid) = 0;
+       (*type) = SID_NAME_ALIAS;
 
-       grp = getgroupntnam(grp_name, NULL, NULL);
+       DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
 
-       if (grp != NULL)
+       if (map_alias_name_to_sid(alias_name, &sid) &&
+           sid_split_rid(&sid, rid) &&
+           sid_equal(&sid, &global_sam_sid))
        {
-               sid_copy(sid, &global_sam_sid);
-               sid_append_rid(sid, grp->rid);
-
-               DEBUG(5,(" = 0x%x\n", grp->rid));
+               DEBUG(5,(" = 0x%x\n", (*rid)));
                return 0x0;
        }
 
@@ -428,41 +452,86 @@ uint32 lookup_added_group_name(const char *grp_name, const char *domain,
 }
 
 /*******************************************************************
- lookup_added_alias_name
+ lookup_wk_alias_sid
  ********************************************************************/
-uint32 lookup_added_alias_name(const char *als_name, const char *domain,
-                               DOM_SID *sid, uint8 *type)
+uint32 lookup_wk_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
 {
-       LOCAL_GRP *als = NULL;
+       char *als_name;
+       int i = 0;
+       uint32 rid;
        (*type) = SID_NAME_ALIAS;
 
-       DEBUG(5,("lookup_added_alias_name: name: %s\\%s", domain, als_name));
-
-       if (!strequal(domain, global_sam_name))
+       do /* find, if it exists, a alias rid for the alias name*/
        {
-               DEBUG(5,(" not our domain\n"));
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
+               rid      = builtin_alias_rids[i].rid;
+               als_name = builtin_alias_rids[i].name;
 
-       als = getaliasntnam(als_name, NULL, NULL);
+               i++;
 
-       if (als != NULL)
+               if (strequal(als_name, alias_name))
+               {
+                       sid_copy(sid, &global_sid_S_1_5_20);
+                       sid_append_rid(sid, rid);
+
+                       return 0x0;
+               }
+                       
+       } while (als_name != NULL);
+
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_wk_alias_rid
+ ********************************************************************/
+uint32 lookup_wk_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
+{
+       char *als_name;
+       int i = -1; /* start do loop at -1 */
+       (*rid) = 0;
+       (*type) = SID_NAME_ALIAS;
+
+       do /* find, if it exists, a alias rid for the alias name*/
        {
-               sid_copy(sid, &global_sam_sid);
-               sid_append_rid(sid, als->rid);
+               i++;
+               (*rid) = builtin_alias_rids[i].rid;
+               als_name = builtin_alias_rids[i].name;
 
-               DEBUG(5,(" = 0x%x\n", als->rid));
-               return 0x0;
+       } while (als_name != NULL && !strequal(als_name, alias_name));
+
+       return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_sid
+ ********************************************************************/
+uint32 lookup_sid(char *name, DOM_SID *sid, uint8 *type)
+{
+       uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+       fstring domain;
+       fstring user;
+       
+       split_domain_name(name, domain, user);
+
+       if (!strequal(domain, global_sam_name))
+       {
+               DEBUG(0,("lookup_sid: remote domain %s not supported\n", domain));
+               return status;
        }
 
-       DEBUG(5,(" none mapped\n"));
-       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+       status = (status != 0x0) ? lookup_wk_alias_sid(user, sid, type) : status;
+       status = (status != 0x0) ? lookup_alias_sid   (user, sid, type) : status;
+#if 0
+       status = (status != 0x0) ? lookup_domain_sid  (user, sid, type) : status;
+#endif
+
+       return status;
 }
 
 /*******************************************************************
  lookup_added_user_rid
  ********************************************************************/
-uint32 lookup_added_user_rids(char *nt_name,
+uint32 lookup_added_user_rids(char *user_name,
                uint32 *usr_rid, uint32 *grp_rid)
 {
        struct sam_passwd *sam_pass;
@@ -471,7 +540,7 @@ uint32 lookup_added_user_rids(char *nt_name,
 
        /* find the user account */
        become_root(True);
-       sam_pass = getsam21pwntnam(nt_name);
+       sam_pass = getsam21pwnam(user_name);
        unbecome_root(True);
 
        if (sam_pass != NULL)
@@ -485,29 +554,22 @@ uint32 lookup_added_user_rids(char *nt_name,
 }
 
 /*******************************************************************
- lookup_added_user_name
+ lookup_added_user_rid
  ********************************************************************/
-static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
-                               DOM_SID *sid, uint8 *type)
+uint32 lookup_added_user_rid(char *user_name, uint32 *rid, uint8 *type)
 {
        struct sam_passwd *sam_pass;
+       (*rid) = 0;
        (*type) = SID_NAME_USER;
 
-       if (!strequal(domain, global_sam_name))
-       {
-               return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
-
        /* find the user account */
        become_root(True);
-       sam_pass = getsam21pwntnam(nt_name);
+       sam_pass = getsam21pwnam(user_name);
        unbecome_root(True);
 
        if (sam_pass != NULL)
        {
-               sid_copy(sid, &global_sam_sid);
-               sid_append_rid(sid, sam_pass->user_rid);
-
+               (*rid) = sam_pass->user_rid;
                return 0x0;
        }
 
@@ -515,52 +577,134 @@ static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
 }
 
 /*******************************************************************
- lookup_grp_name
+ lookup_wk_user_rid
  ********************************************************************/
-static uint32 lookup_grp_name(const char *name, const char *domain,
-                               DOM_SID *sid, uint8 *type)
+uint32 lookup_wk_user_rid(char *user_name, uint32 *rid, uint8 *type)
+{
+       char *usr_name;
+       int i = -1; /* start do loop at -1 */
+       (*rid) = 0;
+       (*type) = SID_NAME_USER;
+
+       do /* find, if it exists, a alias rid for the alias name*/
+       {
+               i++;
+               (*rid) = domain_user_rids[i].rid;
+               usr_name = domain_user_rids[i].name;
+
+       } while (usr_name != NULL && !strequal(usr_name, user_name));
+
+       return (usr_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_added_grp_rid
+ ********************************************************************/
+uint32 lookup_added_grp_rid(char *name, uint32 *rid, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       status = (status != 0x0) ? lookup_wk_group_name     (name, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_builtin_alias_name(name, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_added_group_name  (name, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_added_alias_name  (name, domain, sid, type) : status;
+       status = (status != 0x0) ? lookup_group_rid(name, rid, type) : status;
+       status = (status != 0x0) ? lookup_alias_rid(name, rid, type) : status;
 
        return status;
 }
 
 /*******************************************************************
- lookup_user_name
+ lookup_builtin_grp_rid
  ********************************************************************/
-static uint32 lookup_user_name(const char *name, const char *domain,
-                               DOM_SID *sid, uint8 *type)
+uint32 lookup_builtin_grp_rid(char *name, uint32 *rid, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       status = (status != 0x0) ? lookup_wk_user_name   (name, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_added_user_name(name, domain, sid, type) : status;
+       status = (status != 0x0) ? lookup_wk_group_rid(name, rid, type) : status;
+       status = (status != 0x0) ? lookup_wk_alias_rid(name, rid, type) : status;
 
        return status;
 }
 
 /*******************************************************************
- lookup_name
+ lookup_grp_rid
  ********************************************************************/
-uint32 lookup_name(char *name, DOM_SID *sid, uint8 *type)
+uint32 lookup_grp_rid(char *name, uint32 *rid, uint8 *type)
 {
        uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       fstring domain;
-       fstring user;
-       
-       split_domain_name(name, domain, user);
 
-       status = (status != 0x0) ? lookup_user_name    (user, domain, sid, type) : status;
-       status = (status != 0x0) ? lookup_grp_name     (user, domain, sid, type) : status;
-#if 0
-       status = (status != 0x0) ? lookup_domain_name  (domain, sid, type) : status;
-#endif
+       status = (status != 0x0) ? lookup_builtin_grp_rid(name, rid, type) : status;
+       status = (status != 0x0) ? lookup_added_grp_rid  (name, rid, type) : status;
 
        return status;
 }
 
+/*******************************************************************
+ lookup_user_rid
+ ********************************************************************/
+uint32 lookup_user_rid(char *name, uint32 *rid, uint8 *type)
+{
+       uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+       status = (status != 0x0) ? lookup_wk_user_rid   (name, rid, type) : status;
+       status = (status != 0x0) ? lookup_added_user_rid(name, rid, type) : status;
+
+       return status;
+}
+
+/*******************************************************************
+ lookup_rid
+ ********************************************************************/
+uint32 lookup_rid(char *name, uint32 *rid, uint8 *type)
+{
+       uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+       status = (status != 0x0) ? lookup_user_rid(name, rid, type) : status;
+       status = (status != 0x0) ? lookup_grp_rid (name, rid, type) : status;
+
+       return status;
+}
+
+/*******************************************************************
+ lookup_user_rids
+ ********************************************************************/
+uint32 lookup_user_rids(char *name, uint32 *usr_rid, uint32 *grp_rid)
+{
+       uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+       uint8 type;
+
+       /*
+        * try an ordinary user lookup
+        */
+
+       status = lookup_added_user_rids(name, usr_rid, grp_rid);
+       if (status == 0)
+       {
+               return status;
+       }
+
+       /*
+        * hm.  must be a well-known user, in a well-known group.
+        */
+
+       status = lookup_wk_user_rid(name, usr_rid, &type);
+       if (status != 0 || type != SID_NAME_USER)
+       {
+               return status; /* ok, maybe not! */
+       }
+       if (type != SID_NAME_USER)
+       {
+               return 0xC0000000 | NT_STATUS_NONE_MAPPED; /* users only... */
+       }
+
+       /*
+        * ok, got the user rid: now try the group rid
+        */
+
+       status = lookup_builtin_grp_rid(name, grp_rid, &type);
+       if (type == SID_NAME_DOM_GRP ||
+           type == SID_NAME_ALIAS ||
+           type == SID_NAME_WKN_GRP)
+       {
+               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+       }
+
+       return status;
+}
index fbe83b02c86f19b37b6b0ab2f4c99f06c2267da8..7094d842b41126cfc575dd214ed3d6f7b132bbf0 100644 (file)
 
 extern int DEBUGLEVEL;
 extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
-extern DOM_SID global_member_sid;
 extern fstring global_myworkgroup;
-extern DOM_SID global_sid_S_1_5_20;
+extern pstring global_myname;
 
 /***************************************************************************
-lsa_reply_open_policy2
+ lsa_reply_open_policy2
  ***************************************************************************/
-static void lsa_reply_open_policy2(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy2(prs_struct *rdata)
 {
+       int i;
        LSA_R_OPEN_POL2 r_o;
 
        ZERO_STRUCT(r_o);
 
        /* set up the LSA QUERY INFO response */
 
+       for (i = 4; i < POL_HND_SIZE; i++)
+               r_o.pol.data[i] = i;
        r_o.status = 0x0;
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (!open_policy_hnd(&r_o.pol))
-       {
-               r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       /* store the response in the SMB stream */
+       if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
+               DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_open_pol2("", &r_o, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
 lsa_reply_open_policy
  ***************************************************************************/
-static void lsa_reply_open_policy(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy(prs_struct *rdata)
 {
+       int i;
        LSA_R_OPEN_POL r_o;
 
        ZERO_STRUCT(r_o);
 
        /* set up the LSA QUERY INFO response */
 
+       for (i = 4; i < POL_HND_SIZE; i++)
+               r_o.pol.data[i] = i;
        r_o.status = 0x0;
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (!open_policy_hnd(&r_o.pol))
-       {
-               r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       /* store the response in the SMB stream */
+       if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
+               DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_open_pol("", &r_o, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
-make_dom_query
+Init dom_query
  ***************************************************************************/
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+
+static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
 {
        fstring sid_str;
        int domlen = strlen(dom_name);
 
-       d_q->uni_dom_str_len = (domlen+1) * 2;
        d_q->uni_dom_max_len = domlen * 2;
+       d_q->uni_dom_str_len = domlen * 2;
 
        d_q->buffer_dom_name = domlen  != 0    ? 1 : 0; /* domain buffer pointer */
        d_q->buffer_dom_sid  = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
 
        /* this string is supposed to be character short */
-       make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
-       d_q->uni_domain_name.uni_max_len++;
+       init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
 
        sid_to_string(sid_str, dom_sid);
-       make_dom_sid2(&(d_q->dom_sid), dom_sid);
+       init_dom_sid2(&d_q->dom_sid, dom_sid);
 }
 
 /***************************************************************************
-lsa_reply_query_info
+ lsa_reply_enum_trust_dom
  ***************************************************************************/
+
 static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
                                prs_struct *rdata,
                                uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
@@ -114,7 +119,7 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
        ZERO_STRUCT(r_e);
 
        /* set up the LSA QUERY INFO response */
-       make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
+       init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
              dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
 
        /* store the response in the SMB stream */
@@ -124,63 +129,53 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
 /***************************************************************************
 lsa_reply_query_info
  ***************************************************************************/
-static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
+
+static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
                                char *dom_name, DOM_SID *dom_sid)
 {
        LSA_R_QUERY_INFO r_q;
 
        ZERO_STRUCT(r_q);
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (r_q.status == 0x0 && !open_policy_hnd(&q_q->pol))
-       {
-               r_q.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-       else
-       {
-               /* set up the LSA QUERY INFO response */
+       /* set up the LSA QUERY INFO response */
 
-               r_q.undoc_buffer = 0x1; 
-               r_q.info_class = q_q->info_class;
+       r_q.undoc_buffer = 0x22000000; /* bizarre */
+       r_q.info_class = q_q->info_class;
 
-               make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+       init_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+
+       r_q.status = 0x0;
 
-               r_q.status = 0x0;
-       }
        /* store the response in the SMB stream */
-       lsa_io_r_query("", &r_q, rdata, 0);
-}
+       if(!lsa_io_r_query("", &r_q, rdata, 0)) {
+               DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
+               return False;
+       }
 
+       return True;
+}
 
 /***************************************************************************
-make_dom_ref - adds a domain if it's not already in, returns the index
- ***************************************************************************/
-static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
-                         
+ init_dom_ref - adds a domain if it's not already in, returns the index.
+***************************************************************************/
+
+static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
 {
        int num = 0;
        int len;
 
-       if (dom_name != NULL)
-       {
-               for (num = 0; num < ref->num_ref_doms_1; num++)
-               {
+       if (dom_name != NULL) {
+               for (num = 0; num < ref->num_ref_doms_1; num++) {
                        fstring domname;
-                       unistr2_to_ascii(domname, &ref->ref_dom[num].uni_dom_name, sizeof(domname)-1);
+                       fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
                        if (strequal(domname, dom_name))
-                       {       
                                return num;
-                       }
                }
-
-       }
-       else
-       {
+       } else {
                num = ref->num_ref_doms_1;
        }
 
-       if (num >= MAX_REF_DOMAINS)
-       {
+       if (num >= MAX_REF_DOMAINS) {
                /* index not found, already at maximum domain limit */
                return -1;
        }
@@ -190,95 +185,85 @@ static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
        ref->max_entries = MAX_REF_DOMAINS;
        ref->num_ref_doms_2 = num+1;
 
-       len = dom_name != NULL ? strlen(dom_name) : 0;
+       len = (dom_name != NULL) ? strlen(dom_name) : 0;
+       if(dom_name != NULL && len == 0)
+               len = 1;
 
-       make_uni_hdr(&(ref->hdr_ref_dom[num].hdr_dom_name), len);
+       init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
        ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
 
-       make_unistr2 (&(ref->ref_dom[num].uni_dom_name), dom_name, len);
-       make_dom_sid2(&(ref->ref_dom[num].ref_dom     ), dom_sid );
+       init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
+       init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
 
        return num;
 }
 
 /***************************************************************************
-make_lsa_rid2s
+ init_lsa_rid2s
  ***************************************************************************/
-static void make_lsa_rid2s(DOM_R_REF *ref,
-                               DOM_RID2 *rid2,
+
+static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
                                int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
                                uint32 *mapped_count)
 {
        int i;
        int total = 0;
-       (*mapped_count) = 0;
+       *mapped_count = 0;
 
        SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
-       for (i = 0; i < num_entries; i++)
-       {
-               uint32 status = 0x0;
-               DOM_SID find_sid;
+       for (i = 0; i < num_entries; i++) {
+               BOOL status = False;
+               DOM_SID dom_sid;
                DOM_SID sid;
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
-               fstring find_name;
-               char *dom_name = NULL;
+               pstring full_name;
+               fstring dom_name;
+               fstring user;
                uint8 sid_name_use = SID_NAME_UNKNOWN;
 
-               unistr2_to_ascii(find_name, &name[i], sizeof(find_name)-1);
-               dom_name = strdup(find_name);
+               pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
 
-               if (map_domain_name_to_sid(&sid, &dom_name))
-               {
-                       sid_name_use = SID_NAME_DOMAIN;
-                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
-               }
+               /*
+                * Try and split the name into a DOMAIN and
+                * user component.
+                */
 
-               if (lookup_name(find_name, &sid, &sid_name_use) == 0x0 &&
-                   sid_split_rid(&sid, &rid))
-               {
-                       if (map_domain_sid_to_name(&sid, find_name))
-                       {
-                               dom_idx = make_dom_ref(ref, find_name, &sid);
-                       }
-                       else
-                       {
-                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-                       }
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+               split_domain_name(full_name, dom_name, user);
+
+               /*
+                * We only do anything with this name if we
+                * can map the Domain into a SID we know.
+                */
+
+               if (map_domain_name_to_sid(&dom_sid, dom_name)) {
+                       dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
+
+                       if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid)) 
+                               status = True;
                }
 
-               if (status == 0x0)
-               {
+               if (status)
                        (*mapped_count)++;
-               }
-               else
-               {
+               else {
                        dom_idx = -1;
                        rid = 0xffffffff;
                        sid_name_use = SID_NAME_UNKNOWN;
                }
 
-               make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+               init_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
                total++;
-
-               if (dom_name != NULL)
-               {
-                       free(dom_name);
-               }
        }
 }
 
 /***************************************************************************
-make_reply_lookup_names
+ init_reply_lookup_names
  ***************************************************************************/
-static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
-                               DOM_R_REF *ref, uint32 num_entries,
-                               DOM_RID2 *rid2, uint32 mapped_count)
+
+static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+                DOM_R_REF *ref, uint32 num_entries,
+                DOM_RID2 *rid2, uint32 mapped_count)
 {
        r_l->ptr_dom_ref  = 1;
        r_l->dom_ref      = ref;
@@ -291,84 +276,74 @@ static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
        r_l->mapped_count = mapped_count;
 
        if (mapped_count == 0)
-       {
                r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
        else
-       {
                r_l->status = 0x0;
-       }
 }
 
 /***************************************************************************
-make_lsa_trans_names
+ Init lsa_trans_names.
  ***************************************************************************/
-static void make_lsa_trans_names(DOM_R_REF *ref,
-                               LSA_TRANS_NAME_ENUM *trn,
-                               int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
-                               uint32 *mapped_count)
+
+static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
+                               int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS], uint32 *mapped_count)
 {
+       extern DOM_SID global_sid_S_1_5_0x20; /* BUILTIN sid. */
        int i;
        int total = 0;
-       (*mapped_count) = 0;
+       *mapped_count = 0;
 
        SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
 
-       for (i = 0; i < num_entries; i++)
-       {
-               uint32 status = 0x0;
+       for (i = 0; i < num_entries; i++) {
+               BOOL status = False;
                DOM_SID find_sid = sid[i].sid;
-               DOM_SID tmp_sid  = sid[i].sid;
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
                fstring name;
                fstring dom_name;
                uint8 sid_name_use = 0;
-               
-               memset(dom_name, 0, sizeof(dom_name));
-               memset(name    , 0, sizeof(name    ));
 
-               if (map_domain_sid_to_name(&find_sid, dom_name))
-               {
+               memset(dom_name, '\0', sizeof(dom_name));
+               memset(name, '\0', sizeof(name));
+
+               /*
+                * First, check to see if the SID is one of the well
+                * known ones (this includes our own domain SID).
+                * Next, check if the domain prefix is one of the
+                * well known ones. If so and the domain prefix was
+                * either BUILTIN or our own global sid, then lookup
+                * the RID as a user or group id and translate to
+                * a name.
+                */
+
+               if (map_domain_sid_to_name(&find_sid, dom_name)) {
                        sid_name_use = SID_NAME_DOMAIN;
-                       dom_idx = make_dom_ref(ref, dom_name, &find_sid);
-               }
-               else if (sid_split_rid         (&find_sid, &rid) &&
-                        map_domain_sid_to_name(&find_sid, dom_name))
-               {
+               } else if (sid_split_rid(&find_sid, &rid) && map_domain_sid_to_name(&find_sid, dom_name)) {
                        if (sid_equal(&find_sid, &global_sam_sid) ||
-                           sid_equal(&find_sid, &global_sid_S_1_5_20))
-                       {
-                               /* lkclXXXX REPLACE THIS FUNCTION WITH
-                                  samr_xxxx() routines
-                                */
-                               status = lookup_sid(&tmp_sid, name, &sid_name_use);
+                               sid_equal(&find_sid, &global_sid_S_1_5_0x20)) {
+                               status = lookup_local_rid(rid, name, &sid_name_use);
+                       } else  {
+                               status = lookup_known_rid(&find_sid, rid, name, &sid_name_use);
                        }
-                       else
-                       {
-                               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-                       }
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
                }
 
-               dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+               DEBUG(10,("init_lsa_trans_names: adding domain '%s' sid %s to referenced list.\n",
+                               dom_name, name ));
 
-               if (status == 0x0)
-               {
-                       (*mapped_count)++;
-               }
-               else
-               {
-                       snprintf(name, sizeof(name), "%08x", rid);
-                       sid_name_use = SID_NAME_UNKNOWN;
+               dom_idx = init_dom_ref(ref, dom_name, &find_sid);
 
+               if(!status) {
+                       slprintf(name, sizeof(name)-1, "unix.%08x", rid);
+                       sid_name_use = SID_NAME_UNKNOWN;
                }
-               make_lsa_trans_name(&(trn->name    [total]),
-                                   &(trn->uni_name[total]),
-                                   sid_name_use, name, dom_idx);
+
+               DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to referenced list.\n", dom_name, name ));
+
+               (*mapped_count)++;
+
+               init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
+                                       sid_name_use, name, dom_idx);
                total++;
        }
 
@@ -378,11 +353,12 @@ static void make_lsa_trans_names(DOM_R_REF *ref,
 }
 
 /***************************************************************************
-make_reply_lookup_sids
+ Init_reply_lookup_sids.
  ***************************************************************************/
-static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
-                               DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
-                               uint32 mapped_count)
+
+static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+                DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+                uint32 mapped_count)
 {
        r_l->ptr_dom_ref  = 1;
        r_l->dom_ref      = ref;
@@ -390,20 +366,16 @@ static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
        r_l->mapped_count = mapped_count;
 
        if (mapped_count == 0)
-       {
                r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-       }
        else
-       {
                r_l->status = 0x0;
-       }
 }
 
 /***************************************************************************
 lsa_reply_lookup_sids
  ***************************************************************************/
-static void lsa_reply_lookup_sids(prs_struct *rdata,
-                               DOM_SID2 *sid, int num_entries)
+
+static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
 {
        LSA_R_LOOKUP_SIDS r_l;
        DOM_R_REF ref;
@@ -415,18 +387,24 @@ static void lsa_reply_lookup_sids(prs_struct *rdata,
        ZERO_STRUCT(names);
 
        /* set up the LSA Lookup SIDs response */
-       make_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
-       make_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
+       init_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
+       init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
 
        /* store the response in the SMB stream */
-       lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+       if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
+               DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
 lsa_reply_lookup_names
  ***************************************************************************/
-static void lsa_reply_lookup_names(prs_struct *rdata,
-                               UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
+
+static BOOL lsa_reply_lookup_names(prs_struct *rdata,
+                UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
 {
        LSA_R_LOOKUP_NAMES r_l;
        DOM_R_REF ref;
@@ -435,20 +413,26 @@ static void lsa_reply_lookup_names(prs_struct *rdata,
 
        ZERO_STRUCT(r_l);
        ZERO_STRUCT(ref);
-       ZERO_STRUCT(rids);
+       ZERO_ARRAY(rids);
 
        /* set up the LSA Lookup RIDs response */
-       make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
-       make_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
+       init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+       init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
 
        /* store the response in the SMB stream */
-       lsa_io_r_lookup_names("", &r_l, rdata, 0);
+       if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
+               DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_open_policy
+ api_lsa_open_policy2
  ***************************************************************************/
-static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
+
+static BOOL api_lsa_open_policy2( uint16 vuid, prs_struct *data,
                              prs_struct *rdata )
 {
        LSA_Q_OPEN_POL2 q_o;
@@ -456,18 +440,24 @@ static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_o);
 
        /* grab the server, object attributes and desired access flag...*/
-       lsa_io_q_open_pol2("", &q_o, data, 0);
+       if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
+               DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
+               return False;
+       }
 
        /* lkclXXXX having decoded it, ignore all fields in the open policy! */
 
        /* return a 20 byte policy handle */
-       lsa_reply_open_policy2(rdata);
+       if(!lsa_reply_open_policy2(rdata))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_open_policy
  ***************************************************************************/
-static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_policy( uint16 vuid, prs_struct *data,
                              prs_struct *rdata )
 {
        LSA_Q_OPEN_POL q_o;
@@ -475,18 +465,24 @@ static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_o);
 
        /* grab the server, object attributes and desired access flag...*/
-       lsa_io_q_open_pol("", &q_o, data, 0);
+       if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
+               DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
+               return False;
+       }
 
        /* lkclXXXX having decoded it, ignore all fields in the open policy! */
 
        /* return a 20 byte policy handle */
-       lsa_reply_open_policy(rdata);
+       if(!lsa_reply_open_policy(rdata))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_enum_trust_dom
  ***************************************************************************/
-static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_enum_trust_dom( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        LSA_Q_ENUM_TRUST_DOM q_e;
@@ -498,12 +494,14 @@ static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  return status is always 0x0 */
        lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
+
+       return True;
 }
 
 /***************************************************************************
 api_lsa_query_info
  ***************************************************************************/
-static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_query_info( uint16 vuid, prs_struct *data,
                                 prs_struct *rdata )
 {
        LSA_Q_QUERY_INFO q_i;
@@ -514,119 +512,118 @@ static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
        ZERO_STRUCT(q_i);
 
        /* grab the info class and policy handle */
-       lsa_io_q_query("", &q_i, data, 0);
-
-       switch (q_i.info_class)
-       {
-               case 0x03:
-               {
-                       fstrcpy(name, global_myworkgroup);
-                       sid = &global_member_sid;
-                       break;
-               }
-               case 0x05:
-               {
-                       fstrcpy(name, global_sam_name);
-                       sid = &global_sam_sid;
-                       break;
-               }
-               default:
-               {
-                       DEBUG(5,("unknown info level in Lsa Query: %d\n",
-                                 q_i.info_class));
-                       break;
-               }
+       if(!lsa_io_q_query("", &q_i, data, 0)) {
+               DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
+               return False;
+       }
+
+       switch (q_i.info_class) {
+       case 0x03:
+               fstrcpy(name, global_myworkgroup);
+               sid = &global_sam_sid;
+               break;
+       case 0x05:
+               fstrcpy(name, global_myname);
+               sid = &global_sam_sid;
+               break;
+       default:
+               DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
+               break;
        }
 
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_query_info(&q_i, rdata, name, sid);
+       if(!lsa_reply_query_info(&q_i, rdata, name, sid))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_lookup_sids
+ api_lsa_lookup_sids
  ***************************************************************************/
-static void api_lsa_lookup_sids( rpcsrv_struct *p, prs_struct *data,
-                                 prs_struct *rdata )
+
+static BOOL api_lsa_lookup_sids( uint16 vuid, prs_struct *data, prs_struct *rdata )
 {
        LSA_Q_LOOKUP_SIDS q_l;
        ZERO_STRUCT(q_l);
 
        /* grab the info class and policy handle */
-       lsa_io_q_lookup_sids("", &q_l, data, 0);
+       if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
+               DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
+               return False;
+       }
 
        /* construct reply.  return status is always 0x0 */
-       lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries);
+       if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries))
+               return False;
+
+       return True;
 }
 
 /***************************************************************************
-api_lsa_lookup_names
+ api_lsa_lookup_names
  ***************************************************************************/
-static void api_lsa_lookup_names( rpcsrv_struct *p, prs_struct *data,
-                                  prs_struct *rdata )
+
+static BOOL api_lsa_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata )
 {
        LSA_Q_LOOKUP_NAMES q_l;
        ZERO_STRUCT(q_l);
 
        /* grab the info class and policy handle */
-       lsa_io_q_lookup_names("", &q_l, data, 0);
+       if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
+               DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
+               return False;
+       }
 
        SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
 
-       lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
+       return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
 }
 
 /***************************************************************************
  api_lsa_close
  ***************************************************************************/
-static void api_lsa_close( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_close( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata)
 {
        LSA_R_CLOSE r_c;
-       LSA_Q_CLOSE q_c;
-
-       lsa_io_q_close("", &q_c, data, 0);
 
        ZERO_STRUCT(r_c);
 
-       r_c.status = 0x0;
-
-       /* find the connection policy handle. */
-       if (r_c.status == 0x0 && (find_policy_by_hnd(&(q_c.pol)) == -1))
-       {
-               r_c.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       if (r_c.status == 0x0)
-       {
-               close_policy_hnd(&(q_c.pol));
+       /* store the response in the SMB stream */
+       if (!lsa_io_r_close("", &r_c, rdata, 0)) {
+               DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
+               return False;
        }
 
-       /* store the response in the SMB stream */
-       lsa_io_r_close("", &r_c, rdata, 0);
+       return True;
 }
 
 /***************************************************************************
  api_lsa_open_secret
  ***************************************************************************/
-static void api_lsa_open_secret( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_secret( uint16 vuid, prs_struct *data,
                                   prs_struct *rdata)
 {
        /* XXXX this is NOT good */
-       char *q = mem_data(&(rdata->data), rdata->offset);
-
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0);
-       q += 4;
-       SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND);
-       q += 4;
-       
-       rdata->offset += 24;
+       size_t i;
+       uint32 dummy = 0;
+
+       for(i =0; i < 4; i++) {
+               if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+                       DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
+                               (int)i ));
+                       return False;
+               }
+       }
+
+       dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+               DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
+               return False;
+       }
+
+       return True;
 }
 
 /***************************************************************************
@@ -648,7 +645,7 @@ static struct api_struct api_lsa_cmds[] =
 /***************************************************************************
  api_ntLsarpcTNP
  ***************************************************************************/
-BOOL api_ntlsa_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
 }
index b895fb31c0fee70656b9fd5530a3eec369f0e0ff..24aec701f0b3cb0c6d7e415a8ab3d27da17e6141 100644 (file)
@@ -31,11 +31,6 @@ extern int DEBUGLEVEL;
 #define MAX_OPEN_POLS 64
 #endif
 
-#define POL_NO_INFO 0
-#define POL_REG_INFO 1
-#define POL_SAMR_INFO 2
-#define POL_CLI_INFO 3
-
 struct reg_info
 {
     /* for use by \PIPE\winreg */
@@ -50,27 +45,17 @@ struct samr_info
     uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
 };
 
-struct con_info
-{
-       struct cli_connection *con;
-       void (*free)(struct cli_connection*);
-};
-
 static struct policy
 {
        struct policy *next, *prev;
        int pnum;
        BOOL open;
        POLICY_HND pol_hnd;
-       int type;
 
        union {
-               struct samr_info *samr;
-               struct reg_info *reg;
-               struct con_info *con;
-
+               struct samr_info samr;
+               struct reg_info reg;
        } dev;
-
 } *Policy;
 
 static struct bitmap *bmap;
@@ -100,17 +85,18 @@ static void create_pol_hnd(POLICY_HND *hnd)
 /****************************************************************************
   initialise policy handle states...
 ****************************************************************************/
-BOOL init_policy_hnd(int num_pol_hnds)
+void init_lsa_policy_hnd(void)
 {
-       bmap = bitmap_allocate(num_pol_hnds);
-       
-       return bmap != NULL;
+       bmap = bitmap_allocate(MAX_OPEN_POLS);
+       if (!bmap) {
+               exit_server("out of memory in init_lsa_policy_hnd\n");
+       }
 }
 
 /****************************************************************************
   find first available policy slot.  creates a policy handle for you.
 ****************************************************************************/
-BOOL register_policy_hnd(POLICY_HND *hnd)
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd)
 {
        int i;
        struct policy *p;
@@ -132,8 +118,8 @@ BOOL register_policy_hnd(POLICY_HND *hnd)
 
        p->open = True;                         
        p->pnum = i;
-       p->type = POL_NO_INFO;
 
+       create_pol_hnd(hnd);
        memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
 
        bitmap_set(bmap, i);
@@ -146,33 +132,23 @@ BOOL register_policy_hnd(POLICY_HND *hnd)
        return True;
 }
 
-/****************************************************************************
-  find first available policy slot.  creates a policy handle for you.
-****************************************************************************/
-BOOL open_policy_hnd(POLICY_HND *hnd)
-{
-       create_pol_hnd(hnd);
-       return register_policy_hnd(hnd);
-}
-
 /****************************************************************************
   find policy by handle
 ****************************************************************************/
-static struct policy *find_policy(const POLICY_HND *hnd)
+static struct policy *find_lsa_policy(POLICY_HND *hnd)
 {
        struct policy *p;
 
        for (p=Policy;p;p=p->next) {
                if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
                        DEBUG(4,("Found policy hnd[%x] ", p->pnum));
-                       dump_data(4, (const char *)hnd->data,
-                       sizeof(hnd->data));
+                       dump_data(4, (char *)hnd->data, sizeof(hnd->data));
                        return p;
                }
        }
 
        DEBUG(4,("Policy not found: "));
-       dump_data(4, (const char *)hnd->data, sizeof(hnd->data));
+       dump_data(4, (char *)hnd->data, sizeof(hnd->data));
 
        return NULL;
 }
@@ -180,9 +156,9 @@ static struct policy *find_policy(const POLICY_HND *hnd)
 /****************************************************************************
   find policy index by handle
 ****************************************************************************/
-int find_policy_by_hnd(const POLICY_HND *hnd)
+int find_lsa_policy_by_hnd(POLICY_HND *hnd)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
        return p?p->pnum:-1;
 }
@@ -190,24 +166,15 @@ int find_policy_by_hnd(const POLICY_HND *hnd)
 /****************************************************************************
   set samr rid
 ****************************************************************************/
-BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
-       if (p && p->open)
-       {
+       if (p && p->open) {
                DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
                         rid, p->pnum));
 
-               if (p->dev.samr == NULL)
-               {
-                       p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
-               }
-               if (p->dev.samr == NULL)
-               {
-                       return False;
-               }
-               p->dev.samr->rid = rid;
+               p->dev.samr.rid = rid;
                return True;
        }
 
@@ -219,25 +186,15 @@ BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
 /****************************************************************************
   set samr pol status.  absolutely no idea what this is.
 ****************************************************************************/
-BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
-       if (p && p->open)
-       {
+       if (p && p->open) {
                DEBUG(3,("Setting policy status=%x pnum=%x\n",
                          pol_status, p->pnum));
 
-               if (p->dev.samr == NULL)
-               {
-                       p->type = POL_SAMR_INFO;
-                       p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
-               }
-               if (p->dev.samr == NULL)
-               {
-                       return False;
-               }
-               p->dev.samr->status = pol_status;
+               p->dev.samr.status = pol_status;
                return True;
        } 
 
@@ -249,25 +206,16 @@ BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
 /****************************************************************************
   set samr sid
 ****************************************************************************/
-BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
 {
-       pstring sidstr;
-       struct policy *p = find_policy(hnd);
+       fstring sidstr;
+       struct policy *p = find_lsa_policy(hnd);
 
        if (p && p->open) {
                DEBUG(3,("Setting policy sid=%s pnum=%x\n",
                         sid_to_string(sidstr, sid), p->pnum));
 
-               if (p->dev.samr == NULL)
-               {
-                       p->type = POL_SAMR_INFO;
-                       p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
-               }
-               if (p->dev.samr == NULL)
-               {
-                       return False;
-               }
-               memcpy(&p->dev.samr->sid, sid, sizeof(*sid));
+               memcpy(&p->dev.samr.sid, sid, sizeof(*sid));
                return True;
        }
 
@@ -279,14 +227,14 @@ BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
 /****************************************************************************
   get samr sid
 ****************************************************************************/
-BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
        if (p != NULL && p->open)
        {
-               pstring sidstr;
-               memcpy(sid, &p->dev.samr->sid, sizeof(*sid));
+               fstring sidstr;
+               memcpy(sid, &p->dev.samr.sid, sizeof(*sid));
                DEBUG(3,("Getting policy sid=%s pnum=%x\n",
                         sid_to_string(sidstr, sid), p->pnum));
 
@@ -300,12 +248,12 @@ BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
 /****************************************************************************
   get samr rid
 ****************************************************************************/
-uint32 get_policy_samr_rid(POLICY_HND *hnd)
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
        if (p && p->open) {
-               uint32 rid = p->dev.samr->rid;
+               uint32 rid = p->dev.samr.rid;
                DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
                          rid, p->pnum));
 
@@ -319,116 +267,30 @@ uint32 get_policy_samr_rid(POLICY_HND *hnd)
 /****************************************************************************
   set reg name 
 ****************************************************************************/
-BOOL set_policy_reg_name(POLICY_HND *hnd, fstring name)
-{
-       struct policy *p = find_policy(hnd);
-
-       if (p && p->open)
-       {
-               DEBUG(3,("Getting policy pnum=%x\n",
-                        p->pnum));
-
-               if (p->dev.reg == NULL)
-               {
-                       p->type = POL_REG_INFO;
-                       p->dev.reg = (struct reg_info*)malloc(sizeof(*p->dev.reg));
-               }
-               if (p->dev.reg == NULL)
-               {
-                       return False;
-               }
-               fstrcpy(p->dev.reg->name, name);
-               return True;
-       }
-
-       DEBUG(3,("Error setting policy name=%s\n", name));
-       return False;
-}
-
-/****************************************************************************
-  set reg name 
-****************************************************************************/
-BOOL get_policy_reg_name(POLICY_HND *hnd, fstring name)
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
-       if (p && p->open)
-       {
+       if (p && p->open) {
                DEBUG(3,("Setting policy pnum=%x name=%s\n",
                         p->pnum, name));
 
-               fstrcpy(name, p->dev.reg->name);
-               DEBUG(5,("getting policy reg name=%s\n", name));
-               return True;
-       }
-
-       DEBUG(3,("Error getting policy reg name\n"));
-       return False;
-}
-
-/****************************************************************************
-  set con state
-****************************************************************************/
-BOOL set_policy_con(POLICY_HND *hnd, struct cli_connection *con,
-                               void (*free_fn)(struct cli_connection *))
-{
-       struct policy *p = find_policy(hnd);
-
-       if (p && p->open)
-       {
-               DEBUG(3,("Setting policy con state pnum=%x\n", p->pnum));
-
-               if (p->dev.con == NULL)
-               {
-                       p->type = POL_CLI_INFO;
-                       p->dev.con = (struct con_info*)malloc(sizeof(*p->dev.con));
-               }
-               if (p->dev.con == NULL)
-               {
-                       return False;
-               }
-               p->dev.con->con  = con;
-               p->dev.con->free = free_fn;
+               fstrcpy(p->dev.reg.name, name);
                return True;
        }
 
-       DEBUG(3,("Error setting policy con state\n"));
-
-       return False;
-}
-
-/****************************************************************************
-  get con state
-****************************************************************************/
-BOOL get_policy_con(const POLICY_HND *hnd, struct cli_connection **con)
-{
-       struct policy *p = find_policy(hnd);
-
-       if (p != NULL && p->open)
-       {
-               DEBUG(3,("Getting con state pnum=%x\n", p->pnum));
-
-               if (con != NULL)
-               {
-                       (*con ) = p->dev.con->con;
-               }
-
-               return True;
-       }
-
-       DEBUG(3,("Error getting policy\n"));
+       DEBUG(3,("Error setting policy name=%s\n", name));
        return False;
 }
 
 /****************************************************************************
   close an lsa policy
 ****************************************************************************/
-BOOL close_policy_hnd(POLICY_HND *hnd)
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd)
 {
-       struct policy *p = find_policy(hnd);
+       struct policy *p = find_lsa_policy(hnd);
 
-       if (!p)
-       {
+       if (!p) {
                DEBUG(3,("Error closing policy\n"));
                return False;
        }
@@ -440,33 +302,8 @@ BOOL close_policy_hnd(POLICY_HND *hnd)
        bitmap_clear(bmap, p->pnum);
 
        ZERO_STRUCTP(p);
-       ZERO_STRUCTP(hnd);
-
-       switch (p->type)
-       {
-               case POL_REG_INFO:
-               {
-                       free(p->dev.reg);
-                       break;
-               }
-               case POL_SAMR_INFO:
-               {
-                       free(p->dev.samr);
-                       break;
-               }
-               case POL_CLI_INFO:
-               {
-                       if (p->dev.con->free != NULL)
-                       {
-                               p->dev.con->free(p->dev.con->con);
-                       }
-                       free(p->dev.con);
-                       break;
-               }
-       }
 
        free(p);
 
        return True;
 }
-
index 9721b3bf003e2585dd02377d583187edb74dcdb1..c0233d80c6e2e4f7efa1d44b3e29e31c4e0a85f9 100644 (file)
@@ -1,3 +1,4 @@
+
 /* 
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
 
 extern int DEBUGLEVEL;
 
+extern BOOL sam_logon_in_ssb;
+extern pstring samlogon_user;
 extern pstring global_myname;
 extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
 
 /*************************************************************************
make_net_r_req_chal:
init_net_r_req_chal:
  *************************************************************************/
-static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
+
+static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
                                 DOM_CHAL *srv_chal, int status)
 {
-       DEBUG(6,("make_net_r_req_chal: %d\n", __LINE__));
+       DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
        memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
        r_c->status = status;
 }
@@ -46,7 +49,8 @@ static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
 /*************************************************************************
  net_reply_req_chal:
  *************************************************************************/
-static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
+
+static BOOL net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
                                        DOM_CHAL *srv_chal, uint32 srv_time)
 {
        NET_R_REQ_CHAL r_c;
@@ -54,19 +58,24 @@ static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
        DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
 
        /* set up the LSA REQUEST CHALLENGE response */
-       make_net_r_req_chal(&r_c, srv_chal, srv_time);
+       init_net_r_req_chal(&r_c, srv_chal, srv_time);
 
        /* store the response in the SMB stream */
-       net_io_r_req_chal("", &r_c, rdata, 0);
+       if(!net_io_r_req_chal("", &r_c, rdata, 0)) {
+               DEBUG(0,("net_reply_req_chal: Failed to marshall NET_R_REQ_CHAL.\n"));
+               return False;
+       }
 
        DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
 
+       return True;
 }
 
 /*************************************************************************
  net_reply_logon_ctrl2:
  *************************************************************************/
-static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
+
+static BOOL net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
                        uint32 flags, uint32 pdc_status, uint32 logon_attempts,
                        uint32 tc_status, char *trust_domain_name)
 {
@@ -75,80 +84,63 @@ static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
        DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
 
        /* set up the Logon Control2 response */
-       make_r_logon_ctrl2(&r_l, q_l->query_level,
+       init_r_logon_ctrl2(&r_l, q_l->query_level,
                           flags, pdc_status, logon_attempts,
                           tc_status, trust_domain_name);
 
        /* store the response in the SMB stream */
-       net_io_r_logon_ctrl2("", &r_l, rdata, 0);
+       if(!net_io_r_logon_ctrl2("", &r_l, rdata, 0)) {
+               DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
+               return False;
+       }
 
        DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
 
+       return True;
 }
 
 /*************************************************************************
  net_reply_trust_dom_list:
  *************************************************************************/
-static void net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
-                       uint32 num_trust_domains, char **trust_domain_name)
+
+static BOOL net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
+                       uint32 num_trust_domains, char *trust_domain_name)
 {
        NET_R_TRUST_DOM_LIST r_t;
 
        DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
 
        /* set up the Trusted Domain List response */
-       make_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
+       init_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
 
        /* store the response in the SMB stream */
-       net_io_r_trust_dom("", &r_t, rdata, 0);
+       if(!net_io_r_trust_dom("", &r_t, rdata, 0)) {
+               DEBUG(0,("net_reply_trust_dom_list: Failed to marshall NET_R_TRUST_DOM_LIST.\n"));
+               return False;
+       }
 
-       DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
+       DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
 
+       return True;
 }
 
-
 /*************************************************************************
make_net_r_auth:
init_net_r_auth_2:
  *************************************************************************/
-static void make_net_r_auth(NET_R_AUTH *r_a,
-                              DOM_CHAL *resp_cred, int status)
-{
-       memcpy(  r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
-       r_a->status = status;
-}
 
-/*************************************************************************
- net_reply_auth:
- *************************************************************************/
-static void net_reply_auth(NET_Q_AUTH *q_a, prs_struct *rdata,
-                               DOM_CHAL *resp_cred, int status)
-{
-       NET_R_AUTH r_a;
-
-       /* set up the LSA AUTH 2 response */
-
-       make_net_r_auth(&r_a, resp_cred, status);
-
-       /* store the response in the SMB stream */
-       net_io_r_auth("", &r_a, rdata, 0);
-
-}
-
-/*************************************************************************
- make_net_r_auth_2:
- *************************************************************************/
-static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
+static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
                               DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
 {
-       memcpy(  r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
-       memcpy(&(r_a->srv_flgs)    , flgs           , sizeof(r_a->srv_flgs));
+       memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
+       memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
        r_a->status = status;
 }
 
-/*************************************************************************
+/************************************************************************
  net_reply_auth_2:
  *************************************************************************/
-static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
+
+static BOOL net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
                                DOM_CHAL *resp_cred, int status)
 {
        NET_R_AUTH_2 r_a;
@@ -158,31 +150,37 @@ static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
 
        /* set up the LSA AUTH 2 response */
 
-       make_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
+       init_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
 
        /* store the response in the SMB stream */
-       net_io_r_auth_2("", &r_a, rdata, 0);
+       if(!net_io_r_auth_2("", &r_a, rdata, 0)) {
+               DEBUG(0,("net_reply_auth_2: Failed to marshall NET_R_AUTH_2.\n"));
+               return False;
+       }
 
+       return True;
 }
 
 /***********************************************************************************
make_net_r_srv_pwset:
init_net_r_srv_pwset:
  ***********************************************************************************/
-static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
+
+static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
                              DOM_CRED *srv_cred, int status)  
 {
-       DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+       DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
 
-       memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
+       memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred));
        r_s->status = status;
 
-       DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+       DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
 }
 
 /*************************************************************************
  net_reply_srv_pwset:
  *************************************************************************/
-static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
+
+static BOOL net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
                                DOM_CRED *srv_cred, int status)
 {
        NET_R_SRV_PWSET r_s;
@@ -190,19 +188,24 @@ static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
        DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
 
        /* set up the LSA Server Password Set response */
-       make_net_r_srv_pwset(&r_s, srv_cred, status);
+       init_net_r_srv_pwset(&r_s, srv_cred, status);
 
        /* store the response in the SMB stream */
-       net_io_r_srv_pwset("", &r_s, rdata, 0);
+       if(!net_io_r_srv_pwset("", &r_s, rdata, 0)) {
+               DEBUG(0,("net_reply_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n"));
+               return False;
+       }
 
        DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
 
+       return True;
 }
 
 /*************************************************************************
  net_reply_sam_logon:
  *************************************************************************/
-static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
+
+static BOOL net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
                                DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
                                uint32 status)
 {
@@ -210,32 +213,33 @@ static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
 
        /* XXXX maybe we want to say 'no', reject the client's credentials */
        r_s.buffer_creds = 1; /* yes, we have valid server credentials */
-       memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+       memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
 
        /* store the user information, if there is any. */
        r_s.user = user_info;
        if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
-       {
                r_s.switch_value = 3; /* indicates type of validation user info */
-       }
        else
-       {
                r_s.switch_value = 0; /* indicates no info */
-       }
 
        r_s.status = status;
        r_s.auth_resp = 1; /* authoritative response */
 
        /* store the response in the SMB stream */
-       net_io_r_sam_logon("", &r_s, rdata, 0);
+       if(!net_io_r_sam_logon("", &r_s, rdata, 0)) {
+               DEBUG(0,("net_reply_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n"));
+               return False;
+       }
 
+       return True;
 }
 
 
 /*************************************************************************
  net_reply_sam_logoff:
  *************************************************************************/
-static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
+
+static BOOL net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
                                DOM_CRED *srv_cred, 
                                uint32 status)
 {
@@ -243,63 +247,23 @@ static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
 
        /* XXXX maybe we want to say 'no', reject the client's credentials */
        r_s.buffer_creds = 1; /* yes, we have valid server credentials */
-       memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+       memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
 
        r_s.status = status;
 
        /* store the response in the SMB stream */
-       net_io_r_sam_logoff("", &r_s, rdata, 0);
-
-}
-
-/*************************************************************************
- net_reply_sam_sync:
- *************************************************************************/
-static void net_reply_sam_sync(NET_Q_SAM_SYNC *q_s, prs_struct *rdata,
-                               uint8 sess_key[16],
-                               DOM_CRED *srv_creds, uint32 status)
-{
-       NET_R_SAM_SYNC r_s;
-       int i = 0;
-       struct sam_passwd *pwd;
-       void *vp;
-
-       memcpy(&(r_s.srv_creds), srv_creds, sizeof(r_s.srv_creds));
-       r_s.sync_context = 1;
-       r_s.ptr_deltas = 0;
-
-       if ((status == 0x0) && ((vp = startsmbpwent(False)) != NULL))
-       {
-               /* Give the poor BDC some accounts */
-
-               while (((pwd = getsam21pwent(vp)) != NULL) && (i < MAX_SAM_DELTAS))
-               {
-                       make_sam_delta_hdr(&r_s.hdr_deltas[i], 5, pwd->user_rid);
-                       make_sam_account_info(&r_s.deltas[i].account_info,
-                                pwd->nt_name, pwd->full_name, pwd->user_rid,
-                                pwd->group_rid, pwd->home_dir, pwd->dir_drive,
-                                pwd->logon_script, pwd->acct_desc,
-                                pwd->acct_ctrl, pwd->profile_path);
-
-                       i++;
-               }
-
-               endsmbpwent(vp);
-
-               r_s.ptr_deltas = r_s.ptr_deltas2 = 1;
-               r_s.num_deltas = r_s.num_deltas2 = i;
+       if(!net_io_r_sam_logoff("", &r_s, rdata, 0)) {
+               DEBUG(0,("net_reply_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n"));
+               return False;
        }
 
-       r_s.status = status;
-
-       /* store the response in the SMB stream */
-       net_io_r_sam_sync("", sess_key, &r_s, rdata, 0);
-
+       return True;
 }
 
 /******************************************************************
  gets a machine password entry.  checks access rights of the host.
  ******************************************************************/
+
 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
 {
        struct smb_passwd *smb_pass;
@@ -334,13 +298,6 @@ static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
 
                return True;
        }
-       if (strequal(mach_name, global_myname))
-       {
-               DEBUG(0,("get_md4pw: *** LOOPBACK DETECTED - USING NULL KEY ***\n"));
-               memset(md4pw, 0, 16);
-               return True;
-       }
-
        DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
        return False;
 }
@@ -348,9 +305,8 @@ static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
 /*************************************************************************
  api_net_req_chal:
  *************************************************************************/
-static void api_net_req_chal( rpcsrv_struct *p,
-                              prs_struct *data,
-                              prs_struct *rdata)
+
+static BOOL api_net_req_chal( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        NET_Q_REQ_CHAL q_r;
        uint32 status = 0x0;
@@ -358,93 +314,60 @@ static void api_net_req_chal( rpcsrv_struct *p,
        fstring mach_acct;
        fstring mach_name;
 
-       DEBUG(5,("api_net_req_chal(%d)\n", __LINE__));
+       user_struct *vuser;
+
+       DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
+
+       if ((vuser = get_valid_user_struct(vuid)) == NULL)
+               return False;
 
        /* grab the challenge... */
-       net_io_q_req_chal("", &q_r, data, 0);
+       if(!net_io_q_req_chal("", &q_r, data, 0)) {
+               DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n"));
+               return False;
+       }
 
-       unistr2_to_ascii(mach_acct, &q_r.uni_logon_clnt, sizeof(mach_acct)-1);
+       fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
+                                   q_r.uni_logon_clnt.uni_str_len));
 
        fstrcpy(mach_name, mach_acct);
        strlower(mach_name);
 
        fstrcat(mach_acct, "$");
 
-       if (get_md4pw((char *)p->dc.md4pw, mach_name, mach_acct))
-       {
+       if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct)) {
                /* copy the client credentials */
-               memcpy(p->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
-               memcpy(p->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+               memcpy(vuser->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+               memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
 
                /* create a server challenge for the client */
                /* Set these to random values. */
-                generate_random_buffer(p->dc.srv_chal.data, 8, False);
+                generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
 
-               memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
+               memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
 
-               bzero(p->dc.sess_key, sizeof(p->dc.sess_key));
+               memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
 
                /* from client / server challenges and md4 password, generate sess key */
-               cred_session_key(&(p->dc.clnt_chal), &(p->dc.srv_chal),
-                                (char *)p->dc.md4pw, p->dc.sess_key);
-       }
-       else
-       {
+               cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
+                                (char *)vuser->dc.md4pw, vuser->dc.sess_key);
+       } else {
                /* lkclXXXX take a guess at a good error message to return :-) */
                status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
        }
 
        /* construct reply. */
-       net_reply_req_chal(&q_r, rdata,
-                                       &(p->dc.srv_chal), status);
-
-}
-
-/*************************************************************************
- api_net_auth:
- *************************************************************************/
-static void api_net_auth( rpcsrv_struct *p,
-                            prs_struct *data,
-                            prs_struct *rdata)
-{
-       NET_Q_AUTH q_a;
-       uint32 status = 0x0;
-
-       DOM_CHAL srv_cred;
-       UTIME srv_time;
-
-       srv_time.time = 0;
-
-       /* grab the challenge... */
-       net_io_q_auth("", &q_a, data, 0);
-
-       /* check that the client credentials are valid */
-       if (cred_assert(&(q_a.clnt_chal), p->dc.sess_key,
-                    &(p->dc.clnt_cred.challenge), srv_time))
-       {
-
-               /* create server challenge for inclusion in the reply */
-               cred_create(p->dc.sess_key, &(p->dc.srv_cred.challenge), srv_time, &srv_cred);
-
-               /* copy the received client credentials for use next time */
-               memcpy(p->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
-               memcpy(p->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
-       }
-       else
-       {
-               status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
-       }
+       if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
+               return False;
 
-       /* construct reply. */
-       net_reply_auth(&q_a, rdata, &srv_cred, status);
+       return True;
 }
 
 /*************************************************************************
  api_net_auth_2:
  *************************************************************************/
-static void api_net_auth_2( rpcsrv_struct *p,
-                            prs_struct *data,
-                            prs_struct *rdata)
+
+static BOOL api_net_auth_2( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        NET_Q_AUTH_2 q_a;
        uint32 status = 0x0;
@@ -452,38 +375,46 @@ static void api_net_auth_2( rpcsrv_struct *p,
        DOM_CHAL srv_cred;
        UTIME srv_time;
 
+       user_struct *vuser;
+
+       if ((vuser = get_valid_user_struct(vuid)) == NULL)
+               return False;
+
        srv_time.time = 0;
 
        /* grab the challenge... */
-       net_io_q_auth_2("", &q_a, data, 0);
+       if(!net_io_q_auth_2("", &q_a, data, 0)) {
+               DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n"));
+               return False;
+       }
 
        /* check that the client credentials are valid */
-       if (cred_assert(&(q_a.clnt_chal), p->dc.sess_key,
-                    &(p->dc.clnt_cred.challenge), srv_time))
-       {
+       if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
+                    &(vuser->dc.clnt_cred.challenge), srv_time)) {
 
                /* create server challenge for inclusion in the reply */
-               cred_create(p->dc.sess_key, &(p->dc.srv_cred.challenge), srv_time, &srv_cred);
+               cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
 
                /* copy the received client credentials for use next time */
-               memcpy(p->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
-               memcpy(p->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
-       }
-       else
-       {
+               memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
+               memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
+       } else {
                status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
        }
 
        /* construct reply. */
-       net_reply_auth_2(&q_a, rdata, &srv_cred, status);
+       if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
+               return False;
+
+       return True;
 }
 
+
 /*************************************************************************
  api_net_srv_pwset:
  *************************************************************************/
-static void api_net_srv_pwset( rpcsrv_struct *p,
-                               prs_struct *data,
-                               prs_struct *rdata)
+
+static BOOL api_net_srv_pwset( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        NET_Q_SRV_PWSET q_a;
        uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
@@ -491,20 +422,27 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
        pstring mach_acct;
        struct smb_passwd *smb_pass;
        BOOL ret;
+       user_struct *vuser;
+
+       if ((vuser = get_valid_user_struct(vuid)) == NULL)
+               return False;
 
        /* grab the challenge and encrypted password ... */
-       net_io_q_srv_pwset("", &q_a, data, 0);
+       if(!net_io_q_srv_pwset("", &q_a, data, 0)) {
+               DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n"));
+               return False;
+       }
 
        /* checks and updates credentials.  creates reply credentials */
-       if (deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred), 
+       if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
                            &(q_a.clnt_id.cred), &srv_cred))
        {
-               memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred), sizeof(p->dc.clnt_cred));
+               memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
 
                DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
 
-               unistr2_to_ascii(mach_acct, &q_a.clnt_id.login.uni_acct_name,
-                                sizeof(mach_acct)-1);
+               pstrcpy(mach_acct, dos_unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
+                                           q_a.clnt_id.login.uni_acct_name.uni_str_len));
 
                DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
 
@@ -512,19 +450,16 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
                smb_pass = getsmbpwnam(mach_acct);
                unbecome_root(True);
 
-               if (smb_pass != NULL)
-               {
+               if (smb_pass != NULL) {
                        unsigned char pwd[16];
                        int i;
 
                        DEBUG(100,("Server password set : new given value was :\n"));
                        for(i = 0; i < 16; i++)
-                       {
                                DEBUG(100,("%02X ", q_a.pwd[i]));
-                       }
                        DEBUG(100,("\n"));
 
-                       cred_hash3( pwd, q_a.pwd, p->dc.sess_key, 0);
+                       cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
 
                        /* lies!  nt and lm passwords are _not_ the same: don't care */
                        smb_pass->smb_passwd    = pwd;
@@ -535,8 +470,7 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
                        ret = mod_smbpwd_entry(smb_pass,False);
                        unbecome_root(True);
 
-                       if (ret)
-                       {
+                       if (ret) {
                                /* hooray! */
                                status = 0x0;
                        }
@@ -544,83 +478,63 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
 
                DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
 
-       }
-       else
-       {
+       } else {
                /* lkclXXXX take a guess at a sensible error code to return... */
                status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
        }
 
        /* Construct reply. */
-       net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
+       if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
+               return False;
+
+       return True;
 }
 
 
 /*************************************************************************
  api_net_sam_logoff:
  *************************************************************************/
-static void api_net_sam_logoff( rpcsrv_struct *p,
-                                prs_struct *data,
-                                prs_struct *rdata)
+
+static BOOL api_net_sam_logoff( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        NET_Q_SAM_LOGOFF q_l;
        NET_ID_INFO_CTR ctr;    
 
        DOM_CRED srv_cred;
 
+       user_struct *vuser;
+
+       if ((vuser = get_valid_user_struct(vuid)) == NULL)
+               return False;
+
        /* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
           dynamically allocate it inside net_io_q_sam_logon, at some point */
        q_l.sam_id.ctr = &ctr;
 
        /* grab the challenge... */
-       net_io_q_sam_logoff("", &q_l, data, 0);
+       if(!net_io_q_sam_logoff("", &q_l, data, 0)) {
+               DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n"));
+               return False;
+       }
 
        /* checks and updates credentials.  creates reply credentials */
-       deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred)
-                       &(q_l.sam_id.client.cred), &srv_cred);
-       memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred), sizeof(p->dc.clnt_cred));
+       deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred
+                       &q_l.sam_id.client.cred, &srv_cred);
+       memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
 
        /* construct reply.  always indicate success */
-       net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0);
-}
-
-/*************************************************************************
- api_net_sam_sync:
- *************************************************************************/
-static void api_net_sam_sync( rpcsrv_struct *p,
-                              prs_struct *data,
-                              prs_struct *rdata)
-{
-       NET_Q_SAM_SYNC q_s;
-       DOM_CRED srv_creds;
-       uint32 status = 0x0;
-
-       /* grab the challenge... */
-       net_io_q_sam_sync("", &q_s, data, 0);
-
-       /* checks and updates credentials.  creates reply credentials */
-       if (deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred), 
-                       &(q_s.cli_creds), &srv_creds))
-       {
-               memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred),
-                      sizeof(p->dc.clnt_cred));
-       }
-       else
-       {
-               status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
-       }
+       if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
+               return False;
 
-       /* construct reply. */
-       net_reply_sam_sync(&q_s, rdata, p->dc.sess_key, &srv_creds, status);
+       return True;
 }
 
-
 /*************************************************************************
  net_login_interactive:
  *************************************************************************/
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
-                               struct sam_passwd *smb_pass,
-                               struct dcinfo *dc)
+
+static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass,
+                               user_struct *vuser)
 {
        uint32 status = 0x0;
 
@@ -629,14 +543,14 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
        unsigned char key[16];
 
        memset(key, 0, 16);
-       memcpy(key, dc->sess_key, 8);
+       memcpy(key, vuser->dc.sess_key, 8);
 
        memcpy(lm_pwd, id1->lm_owf.data, 16);
        memcpy(nt_pwd, id1->nt_owf.data, 16);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("key:"));
-       dump_data(100, key, 16);
+       dump_data(100, (char *)key, 16);
 
        DEBUG(100,("lm owf password:"));
        dump_data(100, lm_pwd, 16);
@@ -645,8 +559,8 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
        dump_data(100, nt_pwd, 16);
 #endif
 
-       SamOEMhash((uchar *)lm_pwd, key, 0);
-       SamOEMhash((uchar *)nt_pwd, key, 0);
+       SamOEMhash((uchar *)lm_pwd, key, False);
+       SamOEMhash((uchar *)nt_pwd, key, False);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("decrypt of lm owf password:"));
@@ -656,14 +570,7 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
        dump_data(100, nt_pwd, 16);
 #endif
 
-       if (smb_pass->smb_nt_passwd == NULL)
-       {
-               DEBUG(5,("warning: NETLOGON user %s only has an LM password\n",
-                         smb_pass->unix_name));
-       }
-
        if (memcmp(smb_pass->smb_passwd   , lm_pwd, 16) != 0 ||
-           smb_pass->smb_nt_passwd == NULL ||
            memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
        {
                status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
@@ -675,52 +582,45 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
 /*************************************************************************
  net_login_network:
  *************************************************************************/
-static uint32 net_login_network(NET_ID_INFO_2 *id2,
-                               struct sam_passwd *sam_pass,
-                               struct dcinfo *dc,
-                               char sess_key[16])
-{
-       fstring user;
-       fstring domain;
-
-       int nt_pw_len = id2->hdr_nt_chal_resp.str_str_len;
-       int lm_pw_len = id2->hdr_lm_chal_resp.str_str_len;
 
-       unistr2_to_ascii(user  , &id2->uni_user_name, sizeof(user)-1);
-       unistr2_to_ascii(domain, &id2->uni_domain_name, sizeof(domain)-1);
+static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
+{
+       DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
+               id2->hdr_lm_chal_resp.str_str_len, 
+               id2->hdr_nt_chal_resp.str_str_len));
 
-       DEBUG(5,("net_login_network: lm_len:%d nt_len:%d user:%s domain:%s\n",
-               lm_pw_len, nt_pw_len, user, domain));
+       /* JRA. Check the NT password first if it exists - this is a higher quality 
+           password, if it exists and it doesn't match - fail. */
 
-       if (pass_check_smb(pwdb_sam_to_smb(sam_pass),
-                           domain,
-                           id2->lm_chal, 
-                           (uchar *)id2->lm_chal_resp.buffer, lm_pw_len, 
-                           (uchar *)id2->nt_chal_resp.buffer, nt_pw_len,
-                           NULL, sess_key)) 
+       if (id2->hdr_nt_chal_resp.str_str_len == 24 && 
+               smb_pass->smb_nt_passwd != NULL)
        {
-               unsigned char key[16];
-
-               memset(key, 0, 16);
-               memcpy(key, dc->sess_key, 8);
-
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("key:"));
-               dump_data(100, key, 16);
-
-               DEBUG(100,("user sess key:"));
-               dump_data(100, sess_key, 16);
-#endif
+               if(smb_password_check((char *)id2->nt_chal_resp.buffer,
+                                  smb_pass->smb_nt_passwd,
+                           id2->lm_chal)) 
+                       return 0x0;
+               else
+                       return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+       }
 
-               SamOEMhash((uchar *)sess_key, key, 0);
+       /* lkclXXXX this is not a good place to put disabling of LM hashes in.
+          if that is to be done, first move this entire function into a
+          library routine that calls the two smb_password_check() functions.
+          if disabling LM hashes (which nt can do for security reasons) then
+          an attempt should be made to disable them everywhere (which nt does
+          not do, for various security-hole reasons).
+        */
+
+       if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
+               smb_password_check((char *)id2->lm_chal_resp.buffer,
+                                  smb_pass->smb_passwd,
+                                  id2->lm_chal))
+       {
+               return 0x0;
+       }
 
-#ifdef DEBUG_PASSWORD
-               DEBUG(100,("encrypt of user session key:"));
-               dump_data(100, sess_key, 16);
-#endif
 
-                  return 0x0;
-       }
+       /* oops! neither password check succeeded */
 
        return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
 }
@@ -728,242 +628,242 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
 /*************************************************************************
  api_net_sam_logon:
  *************************************************************************/
-static uint32 reply_net_sam_logon(NET_Q_SAM_LOGON *q_l,
-                               struct dcinfo *dc,
-                               DOM_CRED *srv_cred, NET_USER_INFO_3 *usr_info)
-{
-       struct sam_passwd *sam_pass = NULL;
-       UNISTR2 *uni_samusr = NULL;
-       UNISTR2 *uni_domain = NULL;
-       fstring nt_username;
-       char *enc_user_sess_key = NULL;
-       char sess_key[16];
-
-       NTTIME logon_time           ;
-       NTTIME logoff_time          ;
-       NTTIME kickoff_time         ;
-       NTTIME pass_last_set_time   ;
-       NTTIME pass_can_change_time ;
-       NTTIME pass_must_change_time;
-
-       fstring nt_name     ;
-       fstring full_name   ;
-       fstring logon_script;
-       fstring profile_path;
-       fstring home_dir    ;
-       fstring dir_drive   ;
-
-       uint32 user_rid ;
-       uint32 group_rid;
-
-       int num_gids = 0;
-       DOMAIN_GRP *grp_mem = NULL;
-       DOM_GID *gids = NULL;
-
-       /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(dc->sess_key, &(dc->clnt_cred), 
-                            &(q_l->sam_id.client.cred), srv_cred))
-       {
-               return 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       
-       memcpy(&(dc->srv_cred), &(dc->clnt_cred), sizeof(dc->clnt_cred));
-
-       /* find the username */
-
-       switch (q_l->sam_id.logon_level)
-       {
-               case INTERACTIVE_LOGON_TYPE:
-               {
-                       uni_samusr = &(q_l->sam_id.ctr->auth.id1.uni_user_name);
-                       uni_domain        = &(q_l->sam_id.ctr->auth.id1.uni_domain_name);
-
-                       DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", global_sam_name));
-                       break;
-               }
-               case NET_LOGON_TYPE:
-               {
-                       uni_samusr = &(q_l->sam_id.ctr->auth.id2.uni_user_name);
-                       uni_domain        = &(q_l->sam_id.ctr->auth.id2.uni_domain_name);
-
-                       DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", global_sam_name));
-                       break;
-               }
-               default:
-               {
-                       DEBUG(2,("SAM Logon: unsupported switch value\n"));
-                       return 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-               }
-       } 
-
-       /* check username exists */
-
-       unistr2_to_ascii(nt_username, uni_samusr,
-                        sizeof(nt_username)-1);
 
-       DEBUG(3,("User:[%s]\n", nt_username));
-
-       become_root(True);
-       sam_pass = getsam21pwntnam(nt_username);
-       unbecome_root(True);
-
-       if (sam_pass == NULL)
-       {
-               return 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-       }
-       else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
-                IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
-       {
-               return 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
-       }
+static BOOL api_net_sam_logon( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+  NET_Q_SAM_LOGON q_l;
+  NET_ID_INFO_CTR ctr; 
+  NET_USER_INFO_3 usr_info;
+  uint32 status = 0x0;
+  DOM_CRED srv_cred;
+  struct smb_passwd *smb_pass = NULL;
+  UNISTR2 *uni_samlogon_user = NULL;
+  fstring nt_username;
+
+  user_struct *vuser = NULL;
+
+  if ((vuser = get_valid_user_struct(vuid)) == NULL)
+    return False;
+
+  memset(&q_l, '\0', sizeof(q_l));
+  memset(&ctr, '\0', sizeof(ctr));
+  memset(&usr_info, '\0', sizeof(usr_info));
+
+  q_l.sam_id.ctr = &ctr;
+
+  if(!net_io_q_sam_logon("", &q_l, data, 0)) {
+    DEBUG(0,("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
+    return False;
+  }
+
+  /* checks and updates credentials.  creates reply credentials */
+  if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred), 
+                       &(q_l.sam_id.client.cred), &srv_cred))
+    status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+  else
+    memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
+
+  /* find the username */
+
+  if (status == 0) {
+    switch (q_l.sam_id.logon_level) {
+      case INTERACTIVE_LOGON_TYPE:
+        uni_samlogon_user = &q_l.sam_id.ctr->auth.id1.uni_user_name;
+
+        DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
+        break;
+      case NET_LOGON_TYPE:
+        uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
+
+        DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
+        break;
+      default:
+        DEBUG(2,("SAM Logon: unsupported switch value\n"));
+        status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+        break;
+    } /* end switch */
+  } /* end if status == 0 */
+
+  /* check username exists */
+
+  if (status == 0) {
+    pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
+            uni_samlogon_user->uni_str_len));
+
+    DEBUG(3,("User:[%s]\n", nt_username));
 
-       logon_time            = sam_pass->logon_time;
-       logoff_time           = sam_pass->logoff_time;
-       kickoff_time          = sam_pass->kickoff_time;
-       pass_last_set_time    = sam_pass->pass_last_set_time;
-       pass_can_change_time  = sam_pass->pass_can_change_time;
-       pass_must_change_time = sam_pass->pass_must_change_time;
+    /*
+     * Convert to a UNIX username.
+     */
+    map_username(nt_username);
 
-       fstrcpy(nt_name     , sam_pass->nt_name);
-       fstrcpy(full_name   , sam_pass->full_name);
-       fstrcpy(logon_script, sam_pass->logon_script);
-       fstrcpy(profile_path, sam_pass->profile_path);
-       fstrcpy(home_dir    , sam_pass->home_dir);
-       fstrcpy(dir_drive   , sam_pass->dir_drive);
+    /*
+     * Do any case conversions.
+     */
+    (void)Get_Pwnam(nt_username, True);
+
+    become_root(True);
+    smb_pass = getsmbpwnam(nt_username);
+    unbecome_root(True);
+
+    if (smb_pass == NULL)
+      status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+    else if (smb_pass->acct_ctrl & ACB_PWNOTREQ)
+      status = 0;
+    else if (smb_pass->acct_ctrl & ACB_DISABLED)
+      status =  0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
+  }
+
+  /* Validate password - if required. */
+
+  if ((status == 0) && !(smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
+    switch (q_l.sam_id.logon_level) {
+      case INTERACTIVE_LOGON_TYPE:
+        /* interactive login. */
+        status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, smb_pass, vuser);
+        break;
+      case NET_LOGON_TYPE:
+        /* network login.  lm challenge and 24 byte responses */
+        status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass);
+        break;
+    }
+  }
+       
+  /* lkclXXXX this is the point at which, if the login was
+     successful, that the SAM Local Security Authority should
+     record that the user is logged in to the domain.
+   */
 
-       user_rid  = sam_pass->user_rid;
-       group_rid = sam_pass->group_rid;
+  /* return the profile plus other bits :-) */
 
-       /* validate password - if required */
+  if (status == 0) {
+    DOM_GID *gids = NULL;
+    int num_gids = 0;
+    NTTIME dummy_time;
+    pstring logon_script;
+    pstring profile_path;
+    pstring home_dir;
+    pstring home_drive;
+    pstring my_name;
+    pstring my_workgroup;
+    pstring domain_groups;
+    uint32 r_uid;
+    uint32 r_gid;
 
-       if (!(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
-       {
-               uint32 status = 0x0;
-               switch (q_l->sam_id.logon_level)
-               {
-                       case INTERACTIVE_LOGON_TYPE:
-                       {
-                               /* interactive login. */
-                               status = net_login_interactive(&q_l->sam_id.ctr->auth.id1, sam_pass, dc);
-                               break;
-                       }
-                       case NET_LOGON_TYPE:
-                       {
-                               /* network login.  lm challenge and 24 byte responses */
-                               status = net_login_network(&q_l->sam_id.ctr->auth.id2, sam_pass, dc, sess_key);
-                               enc_user_sess_key = sess_key;
-                               break;
-                       }
-               }
-               if (status != 0x0)
-               {
-                       return status;
-               }
-       }
+    /* set up pointer indicating user/password failed to be found */
+    usr_info.ptr_user_info = 0;
 
-       /* lkclXXXX this is the point at which, if the login was
-       successful, that the SAM Local Security Authority should
-       record that the user is logged in to the domain.
-       */
+    dummy_time.low  = 0xffffffff;
+    dummy_time.high = 0x7fffffff;
 
-       /* return the profile plus other bits :-) */
+    /* XXXX hack to get standard_sub_basic() to use sam logon username */
+    /* possibly a better way would be to do a become_user() call */
+    sam_logon_in_ssb = True;
+    pstrcpy(samlogon_user, nt_username);
 
-       /* set up pointer indicating user/password failed to be found */
-       usr_info->ptr_user_info = 0;
+    pstrcpy(logon_script, lp_logon_script());
+    pstrcpy(profile_path, lp_logon_path());
 
-       if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
-       {
-               return 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
-       }
+    pstrcpy(my_workgroup, lp_workgroup());
 
-       num_gids = make_dom_gids(grp_mem, num_gids, &gids);
-
-       make_net_user_info3(usr_info,
-               &logon_time,
-               &logoff_time,
-               &kickoff_time,
-               &pass_last_set_time,
-               &pass_can_change_time,
-               &pass_must_change_time,
-
-               nt_name         , /* user_name */
-               full_name       , /* full_name */
-               logon_script    , /* logon_script */
-               profile_path    , /* profile_path */
-               home_dir        , /* home_dir */
-               dir_drive       , /* dir_drive */
-
-               0, /* logon_count */
-               0, /* bad_pw_count */
-
-               user_rid   , /* RID user_id */
-               group_rid  , /* RID group_id */
-               num_gids,    /* uint32 num_groups */
-               gids    , /* DOM_GID *gids */
-               0x20    , /* uint32 user_flgs (?) */
-
-               enc_user_sess_key, /* char sess_key[16] */
-
-               global_myname  , /* char *logon_srv */
-               global_sam_name, /* char *logon_dom */
-               &global_sam_sid, /* DOM_SID *dom_sid */
-               NULL); /* char *other_sids */
-
-       /* Free any allocated groups array. */
-       if (gids)
-       {
-               free((char *)gids);
-       }
+    pstrcpy(home_drive, lp_logon_drive());
+    pstrcpy(home_dir, lp_logon_home());
 
-       return 0x0;
-}
+    pstrcpy(my_name, global_myname);
+    strupper(my_name);
 
-/*************************************************************************
- api_net_sam_logon:
- *************************************************************************/
-static void api_net_sam_logon( rpcsrv_struct *p,
-                               prs_struct *data,
-                               prs_struct *rdata)
-{
-       NET_Q_SAM_LOGON q_l;
-       NET_ID_INFO_CTR ctr;    
-       NET_USER_INFO_3 usr_info;
-       uint32 status = 0x0;
-       DOM_CRED srv_cred;
+    /*
+     * This is the point at which we get the group
+     * database - we should be getting the gid_t list
+     * from /etc/group and then turning the uids into
+     * rids and then into machine sids for this user.
+     * JRA.
+     */
 
-       q_l.sam_id.ctr = &ctr;
-       net_io_q_sam_logon("", &q_l, data, 0);
+    get_domain_user_groups(domain_groups, nt_username);
 
-       status = reply_net_sam_logon(&q_l, &p->dc, &srv_cred, &usr_info);
-       net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
+    /*
+     * make_dom_gids allocates the gids array. JRA.
+     */
+    gids = NULL;
+    num_gids = make_dom_gids(domain_groups, &gids);
+
+    sam_logon_in_ssb = False;
+
+    if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
+      init_net_user_info3(&usr_info,
+                          &dummy_time, /* logon_time */
+                          &dummy_time, /* logoff_time */
+                          &dummy_time, /* kickoff_time */
+                          &dummy_time, /* pass_last_set_time */
+                          &dummy_time, /* pass_can_change_time */
+                          &dummy_time, /* pass_must_change_time */
+
+                          nt_username   , /* user_name */
+                          vuser->real_name, /* full_name */
+                          logon_script    , /* logon_script */
+                          profile_path    , /* profile_path */
+                          home_dir        , /* home_dir */
+                          home_drive      , /* dir_drive */
+
+                          0, /* logon_count */
+                          0, /* bad_pw_count */
+
+                          r_uid   , /* RID user_id */
+                          r_gid   , /* RID group_id */
+                          num_gids,    /* uint32 num_groups */
+                          gids    , /* DOM_GID *gids */
+                          0x20    , /* uint32 user_flgs (?) */
+
+                          NULL, /* char sess_key[16] */
+
+                          my_name     , /* char *logon_srv */
+                          my_workgroup, /* char *logon_dom */
+
+                          &global_sam_sid,     /* DOM_SID *dom_sid */
+                          NULL); /* char *other_sids */
+    else
+      status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+
+    /* Free any allocated groups array. */
+    if(gids)
+      free((char *)gids);
+  }
+
+  if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
+    return False;
+
+  return True;
 }
 
 
 /*************************************************************************
  api_net_trust_dom_list:
  *************************************************************************/
-static void api_net_trust_dom_list( rpcsrv_struct *p,
-                                    prs_struct *data,
-                                    prs_struct *rdata)
+
+static BOOL api_net_trust_dom_list( uint16 vuid,
+                                 prs_struct *data,
+                                 prs_struct *rdata)
 {
        NET_Q_TRUST_DOM_LIST q_t;
-       char **doms = NULL;
-       uint32 num_doms = 0;
 
-       enumtrustdoms(&doms, &num_doms);
+       char *trusted_domain = "test_domain";
 
        DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
 
        /* grab the lsa trusted domain list query... */
-       net_io_q_trust_dom("", &q_t, data, 0);
+       if(!net_io_q_trust_dom("", &q_t, data, 0)) {
+               DEBUG(0,("api_net_trust_dom_list: Failed to unmarshall NET_Q_TRUST_DOM_LIST.\n"));
+               return False;
+       }
 
        /* construct reply. */
-       net_reply_trust_dom_list(&q_t, rdata,
-                               num_doms, doms);
-
-       free_char_array(num_doms, doms);
+       if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
+               return False;
 
        DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
+
+       return True;
 }
 
 
@@ -976,7 +876,8 @@ static void api_net_trust_dom_list( rpcsrv_struct *p,
 /*************************************************************************
  api_net_logon_ctrl2:
  *************************************************************************/
-static void api_net_logon_ctrl2( rpcsrv_struct *p,
+
+static BOOL api_net_logon_ctrl2( uint16 vuid,
                                  prs_struct *data,
                                  prs_struct *rdata)
 {
@@ -992,14 +893,20 @@ static void api_net_logon_ctrl2( rpcsrv_struct *p,
        DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
 
        /* grab the lsa netlogon ctrl2 query... */
-       net_io_q_logon_ctrl2("", &q_l, data, 0);
+       if(!net_io_q_logon_ctrl2("", &q_l, data, 0)) {
+               DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n"));
+               return False;
+       }
 
        /* construct reply. */
-       net_reply_logon_ctrl2(&q_l, rdata,
+       if(!net_reply_logon_ctrl2(&q_l, rdata,
                                flags, pdc_connection_status, logon_attempts,
-                               tc_status, trusted_domain);
+                               tc_status, trusted_domain))
+               return False;
 
        DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+
+       return True;
 }
 
 /*******************************************************************
@@ -1008,21 +915,20 @@ static void api_net_logon_ctrl2( rpcsrv_struct *p,
 static struct api_struct api_net_cmds [] =
 {
        { "NET_REQCHAL"       , NET_REQCHAL       , api_net_req_chal       }, 
-       { "NET_AUTH"          , NET_AUTH          , api_net_auth           },
        { "NET_AUTH2"         , NET_AUTH2         , api_net_auth_2         }, 
        { "NET_SRVPWSET"      , NET_SRVPWSET      , api_net_srv_pwset      }, 
        { "NET_SAMLOGON"      , NET_SAMLOGON      , api_net_sam_logon      }, 
        { "NET_SAMLOGOFF"     , NET_SAMLOGOFF     , api_net_sam_logoff     }, 
        { "NET_LOGON_CTRL2"   , NET_LOGON_CTRL2   , api_net_logon_ctrl2    }, 
        { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
-       { "NET_SAM_SYNC"      , NET_SAM_SYNC      , api_net_sam_sync       },
-        {  NULL               , 0                 , NULL                   }
+    {  NULL               , 0                 , NULL                   }
 };
 
 /*******************************************************************
  receives a netlogon pipe and responds.
  ********************************************************************/
-BOOL api_netlog_rpc(rpcsrv_struct *p, prs_struct *data)
+
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);
 }
index d15cc1248c609b77df89c5e32bf4212af2377f77..236558ba7055944dff6b287568f0802cb9276372 100644 (file)
@@ -1,4 +1,3 @@
-
 /* 
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
@@ -6,6 +5,7 @@
  *  Copyright (C) Andrew Tridgell              1992-1998
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  Copyright (C) Paul Ashton                  1997-1998.
+ *  Copyright (C) Jeremy Allison                    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
 
 extern int DEBUGLEVEL;
 
-static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
+static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
 {
     unsigned char *hash = p->ntlmssp_hash;
     unsigned char index_i = hash[256];
     unsigned char index_j = hash[257];
     int ind;
 
-    for( ind = 0; ind < len; ind++)
-    {
+    for( ind = 0; ind < len; ind++) {
         unsigned char tc;
         unsigned char t;
 
@@ -71,250 +70,332 @@ static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
 }
 
 /*******************************************************************
- frees all temporary data used in construction of pdu
+ Generate the next PDU to be returned from the data in p->rdata. 
+ We cheat here as this function doesn't handle the special auth
+ footers of the authenticated bind response reply.
  ********************************************************************/
-void rpcsrv_free_temp(rpcsrv_struct *l)
+
+BOOL create_next_pdu(pipes_struct *p)
 {
-       mem_free_data(l->rhdr .data);
-       mem_free_data(l->rfault .data);
-       mem_free_data(l->rdata_i.data);         
-       mem_free_data(l->rauth  .data);
-       mem_free_data(l->rverf  .data);
-       mem_free_data(l->rntlm  .data);         
-}
+       RPC_HDR_RESP hdr_resp;
+       BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
+       BOOL auth_seal   = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
+       uint32 data_len;
+       uint32 data_space_available;
+       uint32 data_len_left;
+       prs_struct outgoing_pdu;
+       char *data;
+       char *data_from;
+       uint32 data_pos;
 
-/*******************************************************************
- turns a DCE/RPC request into a DCE/RPC reply
+       memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
 
- this is where the data really should be split up into an array of
- headers and data sections.
+       /* Change the incoming request header to a response. */
+       p->hdr.pkt_type = RPC_RESPONSE;
 
- ********************************************************************/
-BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start)
-{
-       char *data;
-       BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
-       BOOL auth_seal   = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
-       uint32 data_len;
-       uint32 auth_len;
-       uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0);
+       /* Set up rpc header flags. */
+       if (p->data_sent_length == 0)
+               p->hdr.flags = RPC_FLG_FIRST;
+       else
+               p->hdr.flags = 0;
 
-       DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
-                 data_start, data_end, l->hdr_ba.bba.max_tsize));
+       /*
+        * Work out how much we can fit in a sigle PDU.
+        */
 
-       auth_len = l->hdr.auth_len;
+       data_space_available = sizeof(p->current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+       if(p->ntlmssp_auth_validated)
+               data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
 
-       if (l->ntlmssp_auth)
-       {
-               DEBUG(10,("create_rpc_reply: auth\n"));
-               if (auth_len != 16)
-               {
-                       return False;
-               }
-       }
+       /*
+        * The amount we send is the minimum of the available
+        * space and the amount left to send.
+        */
 
-       prs_init(&l->rhdr , 0x18, 4, 0, False);
-       prs_init(&l->rauth, 1024, 4, 0, False);
-       prs_init(&l->rverf, 0x10, 4, 0, False);
+       data_len_left = prs_offset(&p->rdata) - p->data_sent_length;
 
-       l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+       /*
+        * Ensure there really is data left to send.
+        */
 
-       /* set up rpc header (fragmentation issues) */
-       if (data_start == 0)
-       {
-               l->hdr.flags = RPC_FLG_FIRST;
-       }
-       else
-       {
-               l->hdr.flags = 0;
+       if(!data_len_left) {
+               DEBUG(0,("create_next_pdu: no data left to send !\n"));
+               return False;
        }
 
-       l->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+       data_len = MIN(data_len_left, data_space_available);
 
-       if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
-       {
-               l->hdr.flags |= RPC_FLG_LAST;
-               l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18;
-       }
-       else
-       {
-               l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
-       }
+       /*
+        * Set up the alloc hint. This should be the data left to
+        * send.
+        */
 
-       if (l->ntlmssp_auth)
-       {
-               l->hdr_resp.alloc_hint -= auth_len + 8;
+       hdr_resp.alloc_hint = data_len_left;
+
+       /*
+        * Set up the header lengths.
+        */
+
+       if (p->ntlmssp_auth_validated) {
+               p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
+                                       RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
+               p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
+       } else {
+               p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
+               p->hdr.auth_len = 0;
        }
 
-       if (l->ntlmssp_auth)
-       {
-               data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+       /*
+        * Work out if this PDU will be the last.
+        */
+
+       if(p->data_sent_length + data_len >= prs_offset(&p->rdata))
+               p->hdr.flags |= RPC_FLG_LAST;
+
+       /*
+        * Init the parse struct to point at the outgoing
+        * data.
+        */
+
+       prs_init( &outgoing_pdu, 0, 4, MARSHALL);
+       prs_give_memory( &outgoing_pdu, (char *)p->current_pdu, sizeof(p->current_pdu), False);
+
+       /* Store the header in the data stream. */
+       if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
+               DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
+               return False;
        }
-       else
-       {
-               data_len = l->hdr.frag_len - 0x18;
+
+       if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
+               DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
+               return False;
        }
 
-       l->rhdr.data->offset.start = 0;
-       l->rhdr.data->offset.end   = 0x18;
+       /* Store the current offset. */
+       data_pos = prs_offset(&outgoing_pdu);
 
-       /* store the header in the data stream */
-       smb_io_rpc_hdr     ("hdr" , &(l->hdr     ), &(l->rhdr), 0);
-       smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0);
+       /* Copy the data into the PDU. */
+       data_from = prs_data_p(&p->rdata) + p->data_sent_length;
+
+       if(!prs_append_data(&outgoing_pdu, data_from, data_len)) {
+               DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+               return False;
+       }
 
-       /* don't use rdata: use rdata_i instead, which moves... */
-       /* make a pointer to the rdata data, NOT A COPY */
+       /*
+        * Set data to point to where we copied the data into.
+        */
 
-       l->rdata_i.data = NULL;
-       prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io);
-       data = mem_data(&(l->rdata.data), data_start);
-       mem_create(l->rdata_i.data, data, 0, data_len, 0, False); 
-       l->rdata_i.offset = data_len;
+       data = prs_data_p(&outgoing_pdu) + data_pos;
 
-       if (auth_len > 0)
-       {
+       if (p->hdr.auth_len > 0) {
                uint32 crc32 = 0;
 
-               DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
-                        BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+               DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
+                        BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len));
 
-               if (auth_seal)
-               {
-                       crc32 = crc32_calc_buffer(data_len, data);
-                       NTLMSSPcalc_p(l, (uchar*)data, data_len);
+               if (auth_seal) {
+                       crc32 = crc32_calc_buffer(data, data_len);
+                       NTLMSSPcalc_p(p, (uchar*)data, data_len);
                }
 
-               if (auth_seal || auth_verify)
-               {
-                       make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
-                       smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0);
+               if (auth_seal || auth_verify) {
+                       RPC_HDR_AUTH auth_info;
+
+                       init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 
+                                       (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
+                       if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
+                               DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+                               return False;
+                       }
                }
 
-               if (auth_verify)
-               {
-                       char *auth_data;
-                       l->ntlmssp_seq_num++;
-                       make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++);
-                       smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0);
-                       auth_data = mem_data(&l->rverf.data, 4);
-                       NTLMSSPcalc_p(l, (uchar*)auth_data, 12);
+               if (auth_verify) {
+                       RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+                       char *auth_data = prs_data_p(&outgoing_pdu);
+
+                       p->ntlmssp_seq_num++;
+                       init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
+                                       crc32, p->ntlmssp_seq_num++);
+                       auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
+                       if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
+                               DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
+                               return False;
+                       }
+                       NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
                }
        }
 
-       /* set up the data chain */
-       if (l->ntlmssp_auth)
-       {
-               prs_link(NULL       , &l->rhdr   , &l->rdata_i);
-               prs_link(&l->rhdr   , &l->rdata_i, &l->rauth  );
-               prs_link(&l->rdata_i, &l->rauth  , &l->rverf  );
-               prs_link(&l->rauth  , &l->rverf  , NULL       );
-       }
-       else
-       {
-               prs_link(NULL    , &l->rhdr   , &l->rdata_i);
-               prs_link(&l->rhdr, &l->rdata_i, NULL       );
-       }
+       /*
+        * Setup the counts for this PDU.
+        */
 
-       return l->rhdr.data != NULL && l->rhdr.offset == 0x18;
+       p->data_sent_length += data_len;
+       p->current_pdu_len = p->hdr.frag_len;
+       p->current_pdu_sent = 0;
+
+       return True;
 }
 
-static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
+/*******************************************************************
+ Process an NTLMSSP authentication response.
+ If this function succeeds, the user has been authenticated
+ and their domain, name and calling workstation stored in
+ the pipe struct.
+ The initial challenge is stored in p->challenge.
+ *******************************************************************/
+
+static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
 {
-       uchar *pwd = NULL;
-       uchar null_pwd[16];
        uchar lm_owf[24];
-       uchar nt_owf[128];
-       size_t lm_owf_len;
-       size_t nt_owf_len;
-       size_t usr_len;
-       size_t dom_len;
-       size_t wks_len;
-       BOOL anonymous = False;
+       uchar nt_owf[24];
+       fstring user_name;
+       fstring unix_user_name;
+       fstring domain;
+       fstring wks;
+       BOOL guest_user = False;
+       struct smb_passwd *smb_pass = NULL;
+       struct passwd *pass = NULL;
+       uchar null_smb_passwd[16];
+       uchar *smb_passwd_ptr = NULL;
+       
+       DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
 
-       memset(null_pwd, 0, sizeof(null_pwd));
+       memset(p->user_name, '\0', sizeof(p->user_name));
+       memset(p->unix_user_name, '\0', sizeof(p->unix_user_name));
+       memset(p->domain, '\0', sizeof(p->domain));
+       memset(p->wks, '\0', sizeof(p->wks));
 
-       DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
+       /* 
+        * Setup an empty password for a guest user.
+        */
 
-       lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
-       nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
-       usr_len    = l->ntlmssp_resp.hdr_usr    .str_str_len;
-       dom_len    = l->ntlmssp_resp.hdr_domain .str_str_len;
-       wks_len    = l->ntlmssp_resp.hdr_wks    .str_str_len;
+       memset(null_smb_passwd,0,16);
 
-       if (lm_owf_len == 0 && nt_owf_len == 0 &&
-           usr_len == 0 && dom_len == 0 && wks_len == 0)
-       {
-               anonymous = True;
-       }
-       else
-       {
-               if (lm_owf_len == 0) return False;
-               if (nt_owf_len == 0) return False;
-               if (l->ntlmssp_resp.hdr_usr    .str_str_len == 0) return False;
-               if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
-               if (l->ntlmssp_resp.hdr_wks    .str_str_len == 0) return False;
+       /*
+        * We always negotiate UNICODE.
+        */
+
+       if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
+               fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2));
+               fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2));
+               fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2));
+       } else {
+               fstrcpy(user_name, ntlmssp_resp->user);
+               fstrcpy(domain, ntlmssp_resp->domain);
+               fstrcpy(wks, ntlmssp_resp->wks);
        }
 
-       if (lm_owf_len > sizeof(lm_owf)) return False;
-       if (nt_owf_len > sizeof(nt_owf)) return False;
+       DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
 
-       memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
-       memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
+       memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
+       memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("lm, nt owfs, chal\n"));
-       dump_data(100, lm_owf, sizeof(lm_owf));
-       dump_data(100, nt_owf, sizeof(nt_owf));
-       dump_data(100, l->ntlmssp_chal.challenge, 8);
+       dump_data(100, (char *)lm_owf, sizeof(lm_owf));
+       dump_data(100, (char *)nt_owf, sizeof(nt_owf));
+       dump_data(100, (char *)p->challenge, 8);
 #endif
 
-       memset(l->user_name, 0, sizeof(l->user_name));
-       memset(l->domain   , 0, sizeof(l->domain   ));
-       memset(l->wks      , 0, sizeof(l->wks      ));
+       /*
+        * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
+        */
+
+       if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) && 
+       (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) {
+
+               guest_user = True;
+
+        fstrcpy(unix_user_name, lp_guestaccount(-1));
+               DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name));
+
+               smb_passwd_ptr = null_smb_passwd;
+
+       } else {
+
+               /*
+                * Pass the user through the NT -> unix user mapping
+                * function.
+                */
+
+               fstrcpy(unix_user_name, user_name);
+               (void)map_username(unix_user_name);
+
+               /* 
+                * Do the length checking only if user is not NULL.
+                */
+
+               if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
+                       return False;
+               if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
+                       return False;
+               if (ntlmssp_resp->hdr_usr.str_str_len == 0)
+                       return False;
+               if (ntlmssp_resp->hdr_domain.str_str_len == 0)
+                       return False;
+               if (ntlmssp_resp->hdr_wks.str_str_len == 0)
+                       return False;
 
-       if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
-       {
-               unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
-                               MIN(l->ntlmssp_resp.hdr_usr   .str_str_len/2,
-                                   sizeof(l->user_name)-1));
-               unibuf_to_ascii(l->domain   , l->ntlmssp_resp.domain,
-                               MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
-                                   sizeof(l->domain   )-1));
-               unibuf_to_ascii(l->wks      , l->ntlmssp_resp.wks,
-                               MIN(l->ntlmssp_resp.hdr_wks   .str_str_len/2,
-                                   sizeof(l->wks      )-1));
-       }
-       else
-       {
-               fstrcpy(l->user_name, l->ntlmssp_resp.user  );
-               fstrcpy(l->domain   , l->ntlmssp_resp.domain);
-               fstrcpy(l->wks      , l->ntlmssp_resp.wks   );
        }
 
+       /*
+        * Find the user in the unix password db.
+        */
 
-       if (anonymous)
-       {
-               DEBUG(5,("anonymous user session\n"));
-               mdfour(l->user_sess_key, null_pwd, 16);
-               pwd = null_pwd;
-               l->ntlmssp_validated = True;
+       if(!(pass = Get_Pwnam(unix_user_name,True))) {
+               DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name));
+               return(False);
        }
-       else
-       {
-               DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
-               become_root(False);
-               l->ntlmssp_validated = check_domain_security(l->user_name, l->domain,
-                                     (uchar*)l->ntlmssp_chal.challenge,
-                                     lm_owf, lm_owf_len,
-                                     nt_owf, nt_owf_len,
-                                     l->user_sess_key);
-               unbecome_root(False);
+
+       if(!guest_user) {
+
+               become_root(True);
+
+               if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain,
+                                     (uchar*)p->challenge, lm_owf, nt_owf, NULL))) {
+                       DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
+failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name ));
+                       unbecome_root(True);
+                       return False;
+               }
+
+               if(!(smb_pass = getsmbpwnam(unix_user_name))) {
+                       DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
+                               unix_user_name));
+                       unbecome_root(True);
+                       return False;
+               }
+
+               unbecome_root(True);
+
+               if (smb_pass == NULL) {
+                       DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", 
+                               unix_user_name));
+                       return(False);
+               }
+
+               /* Quit if the account was disabled. */
+               if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) {
+                       DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name));
+                       return(False);
+               }
+
+               if(!smb_pass->smb_nt_passwd) {
+                       DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name));
+                       return(False);
+               }
+
+               smb_passwd_ptr = smb_pass->smb_passwd;
        }
 
-       if (l->ntlmssp_validated && pwd != NULL)
+       /*
+        * Set up the sign/seal data.
+        */
+
        {
                uchar p24[24];
-               NTLMSSPOWFencrypt(pwd, lm_owf, p24);
+               NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
                {
                        unsigned char j = 0;
                        int ind;
@@ -327,761 +408,670 @@ static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
                        k2[7] = 0xb0;
 
                        for (ind = 0; ind < 256; ind++)
-                       {
-                               l->ntlmssp_hash[ind] = (unsigned char)ind;
-                       }
+                               p->ntlmssp_hash[ind] = (unsigned char)ind;
 
-                       for( ind = 0; ind < 256; ind++)
-                       {
+                       for( ind = 0; ind < 256; ind++) {
                                unsigned char tc;
 
-                               j += (l->ntlmssp_hash[ind] + k2[ind%8]);
+                               j += (p->ntlmssp_hash[ind] + k2[ind%8]);
 
-                               tc = l->ntlmssp_hash[ind];
-                               l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
-                               l->ntlmssp_hash[j] = tc;
+                               tc = p->ntlmssp_hash[ind];
+                               p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
+                               p->ntlmssp_hash[j] = tc;
                        }
 
-                       l->ntlmssp_hash[256] = 0;
-                       l->ntlmssp_hash[257] = 0;
+                       p->ntlmssp_hash[256] = 0;
+                       p->ntlmssp_hash[257] = 0;
                }
-               l->ntlmssp_seq_num = 0;
-       }
-       else
-       {
-               l->ntlmssp_validated = False;
+/*             NTLMSSPhash(p->ntlmssp_hash, p24); */
+               p->ntlmssp_seq_num = 0;
+
        }
 
-       return l->ntlmssp_validated;
-}
+       fstrcpy(p->user_name, user_name);
+       fstrcpy(p->unix_user_name, unix_user_name);
+       fstrcpy(p->domain, domain);
+       fstrcpy(p->wks, wks);
 
-static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
-{
-       /* receive a negotiate; send a challenge; receive a response */
-       switch (l->auth_verifier.msg_type)
-       {
-               case NTLMSSP_NEGOTIATE:
-               {
-                       smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
-                       break;
-               }
-               case NTLMSSP_AUTH:
-               {
-                       smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
-                       if (!api_pipe_ntlmssp_verify(l))
-                       {
-                               pd->offset = 0;
-                       }
-                       break;
-               }
-               default:
-               {
-                       /* NTLMSSP expected: unexpected message type */
-                       DEBUG(3,("unexpected message type in NTLMSSP %d\n",
-                                 l->auth_verifier.msg_type));
-                       return False;
-               }
-       }
+       /*
+        * Store the UNIX credential data (uid/gid pair) in the pipe structure.
+        */
+
+       p->uid = pass->pw_uid;
+       p->gid = pass->pw_gid;
 
-       return (pd->offset != 0);
+       p->ntlmssp_auth_validated = True;
+       return True;
 }
 
+/*******************************************************************
+ The switch table for the pipe names and the functions to handle them.
+ *******************************************************************/
+
 struct api_cmd
 {
   char * pipe_clnt_name;
   char * pipe_srv_name;
-  BOOL (*fn) (rpcsrv_struct *, prs_struct *);
+  BOOL (*fn) (pipes_struct *, prs_struct *);
 };
 
-static struct api_cmd **api_fd_commands = NULL;
-uint32 num_cmds = 0;
-
-static void api_cmd_free(struct api_cmd *item)
-{
-       if (item != NULL)
-       {
-               if (item->pipe_clnt_name != NULL)
-               {
-                       free(item->pipe_clnt_name);
-               }
-               if (item->pipe_srv_name != NULL)
-               {
-                       free(item->pipe_srv_name);
-               }
-               free(item);
-       }
-}
-
-static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
+static struct api_cmd api_fd_commands[] =
 {
-       struct api_cmd *copy = NULL;
-       if (from == NULL)
-       {
-               return NULL;
-       }
-       copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
-       if (copy != NULL)
-       {
-               ZERO_STRUCTP(copy);
-               if (from->pipe_clnt_name != NULL)
-               {
-                       copy->pipe_clnt_name  = strdup(from->pipe_clnt_name );
-               }
-               if (from->pipe_srv_name != NULL)
-               {
-                       copy->pipe_srv_name = strdup(from->pipe_srv_name);
-               }
-               if (from->fn != NULL)
-               {
-                       copy->fn    = from->fn;
-               }
-       }
-       return copy;
-}
+    { "lsarpc",   "lsass",   api_ntlsa_rpc },
+    { "samr",     "lsass",   api_samr_rpc },
+    { "srvsvc",   "ntsvcs",  api_srvsvc_rpc },
+    { "wkssvc",   "ntsvcs",  api_wkssvc_rpc },
+    { "NETLOGON", "lsass",   api_netlog_rpc },
+#if DISABLED_IN_2_0
+    { "winreg",   "winreg",  api_reg_rpc },
+#endif
+    { NULL,       NULL,      NULL }
+};
 
-static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
-{
-       void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
-       free_void_array(num_entries, (void**)entries, *fn);
-}
+/*******************************************************************
+ This is the client reply to our challenge for an authenticated 
+ bind request. The challenge we sent is in p->challenge.
+*******************************************************************/
 
-static struct api_cmd* add_api_cmd_to_array(uint32 *len,
-                               struct api_cmd ***array,
-                               const struct api_cmd *name)
+static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
 {
-       void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
-       return (struct api_cmd*)add_copy_to_array(len,
-                            (void***)array, (const void*)name, *fn, False);
-                               
-}
+       RPC_HDR_AUTHA autha_info;
+       RPC_AUTH_VERIFIER auth_verifier;
+       RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
 
+       DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
 
-void close_msrpc_command_processor(void)
-{
-       free_api_cmd_array(num_cmds, api_fd_commands);
-}
+       if (p->hdr.auth_len == 0) {
+               DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
+               return False;
+       }
 
-void add_msrpc_command_processor(char* pipe_name,
-                               char* process_name,
-                               BOOL (*fn) (rpcsrv_struct *, prs_struct *))
-{
-       struct api_cmd cmd;
-       cmd.pipe_clnt_name = pipe_name;
-       cmd.pipe_srv_name = process_name;
-       cmd.fn = fn;
+       /*
+        * Decode the authentication verifier response.
+        */
 
-       add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
-}
+       if(!smb_io_rpc_hdr_autha("", &autha_info, pd, 0)) {
+               DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n"));
+               return False;
+       }
 
-static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
-{
-       DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+       if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) {
+               DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
+                       (int)autha_info.auth_type, (int)autha_info.auth_level ));
+               return False;
+       }
 
-       if (l->hdr.auth_len == 0) return False;
+       if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
+               DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n"));
+               return False;
+       }
 
-       /* decode the authentication verifier response */
-       smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
-       if (pd->offset == 0) return False;
+       /*
+        * Ensure this is a NTLMSSP_AUTH packet type.
+        */
 
-       if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
+       if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
+               DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
+               return False;
+       }
 
-       smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
-       if (pd->offset == 0) return False;
+       if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, pd, 0)) {
+               DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n"));
+               return False;
+       }
 
-       if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
+       /*
+        * The following call actually checks the challenge/response data.
+        * for correctness against the given DOMAIN\user name.
+        */
        
-       return api_pipe_ntlmssp(l, pd);
+       if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp))
+               return False;
+
+       return True;
 }
 
-static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
+/*******************************************************************
+ Marshall a bind_nak pdu.
+*******************************************************************/
+
+static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd)
 {
-       DEBUG(5,("api_pipe_fault_resp: make response\n"));
+       prs_struct outgoing_rpc;
+       RPC_HDR nak_hdr;
+       uint16 zero = 0;
+
+       /*
+        * Marshall directly into the outgoing PDU space. We
+        * must do this as we need to set to the bind response
+        * header and are never sending more than one PDU here.
+        */
 
-       prs_init(&(l->rhdr     ), 0x18, 4, 0, False);
-       prs_init(&(l->rfault   ), 0x8 , 4, 0, False);
+       prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+       prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False);
 
-       /***/
-       /*** set up the header, response header and fault status ***/
-       /***/
 
-       l->hdr_fault.status   = status;
-       l->hdr_fault.reserved = 0x0;
+       /*
+        * Initialize a bind_nak header.
+        */
 
-       l->hdr_resp.alloc_hint   = 0x0;
-       l->hdr_resp.cancel_count = 0x0;
-       l->hdr_resp.reserved     = 0x0;
+       init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+            p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
 
-       make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
-                    l->hdr.call_id,
-                    0x20,
-                    0);
+       /*
+        * Marshall the header into the outgoing PDU.
+        */
 
-       smb_io_rpc_hdr      ("hdr"  , &(l->hdr      ), &(l->rhdr), 0);
-       smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
-       smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
-       mem_realloc_data(l->rhdr.data, l->rhdr.offset);
-       mem_realloc_data(l->rfault.data, l->rfault.offset);
+       if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
+               DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
+               return False;
+       }
 
-       /***/
-       /*** link rpc header and fault together ***/
-       /***/
+       /*
+        * Now add the reject reason.
+        */
 
-       prs_link(NULL    , &l->rhdr  , &l->rfault);
-       prs_link(&l->rhdr, &l->rfault, NULL      );
+       if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero))
+        return False;
+
+       p->data_sent_length = 0;
+       p->current_pdu_len = prs_offset(&outgoing_rpc);
+       p->current_pdu_sent = 0;
 
        return True;
 }
 
-static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, 
-                               const char* ack_pipe_name,
-                               enum RPC_PKT_TYPE pkt_type)
+/*******************************************************************
+ Respond to a pipe bind request.
+*******************************************************************/
+
+static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
 {
+       RPC_HDR_BA hdr_ba;
+       RPC_HDR_RB hdr_rb;
+       RPC_HDR_AUTH auth_info;
        uint16 assoc_gid;
+       fstring ack_pipe_name;
+       prs_struct out_hdr_ba;
+       prs_struct out_auth;
+       prs_struct outgoing_rpc;
+       int i = 0;
+       int auth_len = 0;
+
+       p->ntlmssp_auth_requested = False;
+
+       DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+
+       /*
+        * Try and find the correct pipe name to ensure
+        * that this is a pipe name we support.
+        */
 
-       l->ntlmssp_auth = False;
+       for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+               if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+                   api_fd_commands[i].fn != NULL) {
+                       DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+                                  api_fd_commands[i].pipe_clnt_name,
+                                  api_fd_commands[i].pipe_srv_name));
+                       fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
+                       break;
+               }
+       }
+
+       if (api_fd_commands[i].fn == NULL) {
+               DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
+                       p->name ));
+               if(!setup_bind_nak(p, pd))
+                       return False;
+               return True;
+       }
 
        /* decode the bind request */
-       smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
+       if(!smb_io_rpc_hdr_rb("", &hdr_rb, pd, 0))  {
+               DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
+               return False;
+       }
 
-       if (pd->offset == 0) return False;
+       /*
+        * Check if this is an authenticated request.
+        */
 
-       if (l->hdr.auth_len != 0)
-       {
-               /* decode the authentication verifier */
-               smb_io_rpc_hdr_auth    ("", &l->auth_info    , pd, 0);
-               if (pd->offset == 0) return False;
+       if (p->hdr.auth_len != 0) {
+               RPC_AUTH_VERIFIER auth_verifier;
+               RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
 
-               l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
+               /* 
+                * Decode the authentication verifier.
+                */
 
-               if (l->ntlmssp_auth)
-               {
-                       smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
-                       if (pd->offset == 0) return False;
+               if(!smb_io_rpc_hdr_auth("", &auth_info, pd, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+                       return False;
+               }
 
-                       l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
+               /*
+                * We only support NTLMSSP_AUTH_TYPE requests.
+                */
+
+               if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) {
+                       DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
+                               auth_info.auth_type ));
+                       return False;
                }
 
-               if (l->ntlmssp_auth)
-               {
-                       if (!api_pipe_ntlmssp(l, pd)) return False;
+               if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+                       return False;
+               }
+
+               if(!strequal(auth_verifier.signature, "NTLMSSP")) {
+                       DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n"));
+                       return False;
+               }
+
+               if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
+                       DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
+                               auth_verifier.msg_type));
+                       return False;
                }
+
+               if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, pd, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
+                       return False;
+               }
+
+               p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
+               p->ntlmssp_auth_requested = True;
        }
 
+       /* name has to be \PIPE\xxxxx */
+       fstrcpy(ack_pipe_name, "\\PIPE\\");
+       fstrcat(ack_pipe_name, p->pipe_srv_name);
+
        DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
 
-       prs_init(&(l->rdata), 1024, 4, 0, False);
-       prs_init(&(l->rhdr ), 0x18, 4, 0, False);
-       prs_init(&(l->rauth), 1024, 4, 0, False);
-       prs_init(&(l->rverf), 0x08, 4, 0, False);
-       prs_init(&(l->rntlm), 1024, 4, 0, False);
+       /* 
+        * Marshall directly into the outgoing PDU space. We
+        * must do this as we need to set to the bind response
+        * header and are never sending more than one PDU here.
+        */
 
-       /***/
-       /*** do the bind ack first ***/
-       /***/
+       prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+       prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False);
 
-       if (l->ntlmssp_auth)
-       {
-               assoc_gid = 0x7a77;
+       /*
+        * Setup the memory to marshall the ba header, and the
+        * auth footers.
+        */
+
+       if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) {
+               DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
+               return False;
        }
-       else
-       {
-               assoc_gid = l->hdr_rb.bba.assoc_gid;
+
+       if(!prs_init(&out_auth, 1024, 4, MARSHALL)) {
+               DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
+               prs_mem_free(&out_hdr_ba);
+               return False;
        }
 
-       make_rpc_hdr_ba(&l->hdr_ba,
-                       l->hdr_rb.bba.max_tsize,
-                       l->hdr_rb.bba.max_rsize,
+       if (p->ntlmssp_auth_requested)
+               assoc_gid = 0x7a77;
+       else
+               assoc_gid = hdr_rb.bba.assoc_gid;
+
+       /*
+        * Create the bind response struct.
+        */
+
+       init_rpc_hdr_ba(&hdr_ba,
+                       hdr_rb.bba.max_tsize,
+                       hdr_rb.bba.max_rsize,
                        assoc_gid,
                        ack_pipe_name,
                        0x1, 0x0, 0x0,
-                       &(l->hdr_rb.transfer));
+                       &hdr_rb.transfer);
+
+       /*
+        * and marshall it.
+        */
 
-       smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
-       mem_realloc_data(l->rdata.data, l->rdata.offset);
+       if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
+               DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
+               goto err_exit;
+       }
 
-       /***/
-       /*** now the authentication ***/
-       /***/
+       /*
+        * Now the authentication.
+        */
 
-       if (l->ntlmssp_auth)
-       {
-               uint8 challenge[8];
-               generate_random_buffer(challenge, 8, False);
+       if (p->ntlmssp_auth_requested) {
+               RPC_AUTH_VERIFIER auth_verifier;
+               RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
 
-               /*** authentication info ***/
+               generate_random_buffer(p->challenge, 8, False);
 
-               make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
-               smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
-               mem_realloc_data(l->rverf.data, l->rverf.offset);
+               /*** Authentication info ***/
+
+               init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1);
+               if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
+                       goto err_exit;
+               }
 
                /*** NTLMSSP verifier ***/
 
-               make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
-                                      "NTLMSSP", NTLMSSP_CHALLENGE);
-               smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
-               mem_realloc_data(l->rauth.data, l->rauth.offset);
+               init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
+               if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
+                       goto err_exit;
+               }
 
                /* NTLMSSP challenge ***/
 
-               make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
-                                          0x000082b1, challenge);
-               smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
-               mem_realloc_data(l->rntlm.data, l->rntlm.offset);
-       }
+               init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge);
+               if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) {
+                       DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n"));
+                       goto err_exit;
+               }
 
-       /***/
-       /*** then do the header, now we know the length ***/
-       /***/
+               /* Auth len in the rpc header doesn't include auth_header. */
+               auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
+       }
 
-       make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
-                    l->hdr.call_id,
-                    l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
-                    l->rauth.offset + l->rntlm.offset);
+       /*
+        * Create the header, now we know the length.
+        */
 
-       smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
-       mem_realloc_data(l->rhdr.data, l->rdata.offset);
+       init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+                       p->hdr.call_id,
+                       RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
+                       auth_len);
 
-       /***/
-       /*** link rpc header, bind acknowledgment and authentication responses ***/
-       /***/
+       /*
+        * Marshall the header into the outgoing PDU.
+        */
 
-       if (l->ntlmssp_auth)
-       {
-               prs_link(NULL     , &l->rhdr , &l->rdata);
-               prs_link(&l->rhdr , &l->rdata, &l->rverf);
-               prs_link(&l->rdata, &l->rverf, &l->rauth);
-               prs_link(&l->rverf, &l->rauth, &l->rntlm);
-               prs_link(&l->rauth, &l->rntlm, NULL     );
+       if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
+               DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
+               goto err_exit;
        }
-       else
-       {
-               prs_link(NULL    , &l->rhdr , &l->rdata);
-               prs_link(&l->rhdr, &l->rdata, NULL     );
+
+       /*
+        * Now add the RPC_HDR_BA and any auth needed.
+        */
+
+       if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
+               DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
+               goto err_exit;
        }
 
-       return True;
-}
+       if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+               DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
+               goto err_exit;
+       }
 
-static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
-                               const char* name,
-                               enum RPC_PKT_TYPE pkt_type)
-{
-       fstring ack_pipe_name;
-       fstring pipe_srv_name;
-       int i = 0;
+       /*
+        * Setup the lengths for the initial reply.
+        */
 
-       DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+       p->data_sent_length = 0;
+       p->current_pdu_len = prs_offset(&outgoing_rpc);
+       p->current_pdu_sent = 0;
 
-       for (i = 0; i < num_cmds; i++)
-       {
-               if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
-                   api_fd_commands[i]->fn != NULL)
-               {
-                       DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
-                                  api_fd_commands[i]->pipe_clnt_name,
-                                  api_fd_commands[i]->pipe_srv_name));
-                       fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
-                       break;
-               }
-       }
+       prs_mem_free(&out_hdr_ba);
+       prs_mem_free(&out_auth);
 
-       if (api_fd_commands[i]->fn == NULL) return False;
+       return True;
 
-       switch (pkt_type)
-       {
-               case RPC_BINDACK:
-               {
-                       /* name has to be \PIPE\xxxxx */
-                       fstrcpy(ack_pipe_name, "\\PIPE\\");
-                       fstrcat(ack_pipe_name, pipe_srv_name);
-                       break;
-               }
-               case RPC_ALTCONTRESP:
-               {
-                       /* secondary address CAN be NULL
-                        * as the specs says it's ignored.
-                        * It MUST NULL to have the spoolss working.
-                        */
-                       fstrcpy(ack_pipe_name, "");
-                       break;
-               }
-               default:
-               {
-                       return False;
-               }
-       }
-       return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
-}
+  err_exit:
 
-/*
- * The RPC Alter-Context call is used only by the spoolss pipe
- * simply because there is a bug (?) in the MS unmarshalling code
- * or in the marshalling code. If it's in the later, then Samba
- * have the same bug.
- */
-static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
-                               const char* name)
-{
-       return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
+       prs_mem_free(&out_hdr_ba);
+       prs_mem_free(&out_auth);
+       return False;
 }
 
-static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
-                               const char* name)
-{
-       return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
-}
+/****************************************************************************
+ Deal with sign & seal processing on an RPC request.
+****************************************************************************/
 
-static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
+static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
 {
-       BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
-       BOOL auth_seal   = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
+       /*
+        * We always negotiate the following two bits....
+        */
+       BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
+       BOOL auth_seal   = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
        int data_len;
        int auth_len;
        uint32 old_offset;
        uint32 crc32 = 0;
 
-       auth_len = l->hdr.auth_len;
+       auth_len = p->hdr.auth_len;
 
-       if (auth_len != 16 && auth_verify)
-       {
+       if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) {
+               DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len ));
                return False;
        }
 
-       data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+       /*
+        * The following is that length of the data we must verify or unseal.
+        * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
+        * preceeding the auth_data.
+        */
+
+       data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - 
+                       (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
        
        DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
                 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
 
-       if (auth_seal)
-       {
-               char *data = mem_data(&pd->data, pd->offset);
-               DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
-               NTLMSSPcalc_p(l, (uchar*)data, data_len);
-               crc32 = crc32_calc_buffer(data_len, data);
+       if (auth_seal) {
+               char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
+               NTLMSSPcalc_p(p, (uchar*)data, data_len);
+               crc32 = crc32_calc_buffer(data, data_len);
        }
 
-       /*** skip the data, record the offset so we can restore it again */
-       old_offset = pd->offset;
+       old_offset = prs_offset(rpc_in);
 
-       if (auth_seal || auth_verify)
-       {
-               pd->offset += data_len;
-               smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
-       }
+       if (auth_seal || auth_verify) {
+               RPC_HDR_AUTH auth_info;
 
-       if (auth_verify)
-       {
-               char *req_data = mem_data(&pd->data, pd->offset + 4);
-               DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
-               NTLMSSPcalc_p(l, (uchar*)req_data, 12);
-               smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
+               if(!prs_set_offset(rpc_in, old_offset + data_len)) {
+                       DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n",
+                               (unsigned int)old_offset + data_len ));
+                       return False;
+               }
 
-               if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
-                                         l->ntlmssp_seq_num))
-               {
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
+                       DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
                        return False;
                }
        }
 
-       pd->offset = old_offset;
-
-       return True;
-}
-
-static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
-{
-       int i = 0;
-
-       if (l->ntlmssp_auth && l->ntlmssp_validated)
-       {
-               if (!api_pipe_auth_process(l, pd)) return False;
+       if (auth_verify) {
+               RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+               char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4;
 
-               DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
-#if 0
-               become_user();
-#endif
-       }
+               DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4));
 
-       for (i = 0; i < num_cmds; i++)
-       {
-               if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
-                   api_fd_commands[i]->fn != NULL)
-               {
-                       DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
-                       return api_fd_commands[i]->fn(l, pd);
+               /*
+                * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the
+                * incoming buffer.
+                */
+               if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) {
+                       DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n",
+                               RPC_AUTH_NTLMSSP_CHK_LEN - 4 ));
+                       return False;
                }
-       }
-       return False;
-}
-
-BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
-{
-       int prev_size;
-       int new_size;
-       char *to = NULL;
-
-       ps->offset = 0;
 
-       if (ps->data == NULL)
-       {
-               DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
-               prs_init(ps, len, 4, 0, True);
-               prev_size = 0;
-               new_size  = len;
-               if (ps->data == NULL)
-               {
+               NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+               if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) {
+                       DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n"));
                        return False;
                }
-       }
-       else
-       {
-               prev_size = ps->data->data_used;
-               new_size  = prev_size + len;
-               DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
-                               prev_size, new_size));
-               if (!mem_realloc_data(ps->data, new_size))
-               {
+
+               if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) {
+                       DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n"));
                        return False;
                }
        }
 
-       DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
-       ps->data->offset.start = 0x0;
+       /*
+        * Return the current pointer to the data offset.
+        */
 
-       to = mem_data(&ps->data, prev_size);
-       if (to == NULL)
-       {
-               DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
-               return False;
-       }
-       if (ps->data->data_used != new_size)
-       {
-               DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
-                               ps->data->data_used, new_size));
+       if(!prs_set_offset(rpc_in, old_offset)) {
+               DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
+                       (unsigned int)old_offset ));
                return False;
        }
-       memcpy(to, data, len);
+
        return True;
 }
 
-static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
+/****************************************************************************
+ Find the correct RPC function to call for this request.
+ If the pipe is authenticated then become the correct UNIX user
+ before doing the call.
+****************************************************************************/
+
+static BOOL api_pipe_request(pipes_struct *p, prs_struct *rpc_in)
 {
-       DEBUG(10,("rpc_redirect\n"));
+       int i = 0;
+       BOOL ret = False;
+       BOOL changed_user_id = False;
 
-       if (!msrpc_send_prs(p->m, req))
-       {
-               DEBUG(2,("msrpc redirect send failed\n"));
-               return False;
+       if (p->ntlmssp_auth_validated) {
+               if (!api_pipe_auth_process(p, rpc_in))
+                       return False;
+
+               if(!become_authenticated_pipe_user(p))
+                       return False;
+
+               changed_user_id = True;
        }
-       if (!msrpc_receive_prs(p->m, resp))
-       {
-               DEBUG(2,("msrpc redirect receive failed\n"));
-               return False;
+
+       for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+               if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+                   api_fd_commands[i].fn != NULL) {
+                       DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+                       ret = api_fd_commands[i].fn(p, rpc_in);
+               }
        }
-       prs_link(NULL, resp, NULL);
-       prs_debug_out(resp, "redirect", 100);
-       return True;
+
+       if(changed_user_id)
+               unbecome_authenticated_pipe_user(p);
+
+       return ret;
 }
 
-static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
-                               const char* name)
+/****************************************************************************
+ This function is the entry point to processing a DCE/RPC request.
+ All the data for the request (including RPC headers and authentication
+ verifiers) must be linearized in the input_data buffer, with a length
+ of data_len.
+
+ The output is placed into the pipes_struct, and handed back to the
+ client on demand.
+****************************************************************************/
+
+BOOL rpc_command(pipes_struct *p, char *input_data, int data_len)
 {
+       prs_struct rpc_in;
        BOOL reply = False;
 
-       if (req->data == NULL) return False;
+       if (input_data == NULL)
+               return False;
+
+       prs_init(&rpc_in, 0, 4, UNMARSHALL);
 
-       /* lkclXXXX still assume that the first complete PDU is always
-          in a single request!!!
+       /*
+        * Hand the data to the prs_struct, but don't let
+        * it own it.
         */
-       /* process the rpc header */
-       req->offset = 0x0;
-       smb_io_rpc_hdr("", &l->hdr, req, 0);
+       prs_give_memory( &rpc_in, input_data, (uint32)data_len, False);
 
-       if (req->offset == 0) return False;
+       /* Unmarshall the rpc header */
+       if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
+               DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+               return False;
+       }
 
-       switch (l->hdr.pkt_type)
-       {
-               case RPC_BIND   :
-               {
-                       reply = api_pipe_bind_req(l, req, name);
-                       break;
-               }
-               case RPC_ALTCONT:
-               {
-                       reply = api_pipe_alt_req(l, req, name);
-                       break;
-               }
-               case RPC_REQUEST:
-               {
-                       if (l->ntlmssp_auth && !l->ntlmssp_validated)
-                       {
-                               /* authentication _was_ requested
-                                  and it failed.  sorry, no deal!
-                                */
-                               reply = False;
-                       }
-                       else
-                       {
-                               /* read the rpc header */
-                               smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
-                               reply = api_pipe_request(l, req, name);
+       /*
+        * Create the response data buffer.
+        */
+
+       if(!pipe_init_outgoing_data(p)) {
+               DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+               return False;
+       }
+
+       switch (p->hdr.pkt_type) {
+       case RPC_BIND:
+               reply = api_pipe_bind_req(p, &rpc_in);
+               break;
+       case RPC_REQUEST:
+               if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
+                       /* authentication _was_ requested
+                          and it failed.  sorry, no deal!
+                        */
+                       DEBUG(0,("rpc_command: RPC request received on pipe %s where \
+authentication failed. Denying the request.\n", p->name));
+                       reply = False;
+               } else {
+                       /* read the RPC request header */
+                       if(!smb_io_rpc_hdr_req("req", &p->hdr_req, &rpc_in, 0)) {
+                               DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR_REQ.\n"));
+                               return False;
                        }
-                       break;
-               }
-               case RPC_BINDRESP: /* not the real name! */
-               {
-                       reply = api_pipe_bind_auth_resp(l, req);
-                       l->ntlmssp_auth = reply;
-                       break;
+                       reply = api_pipe_request(p, &rpc_in);
                }
+               break;
+       case RPC_BINDRESP: /* not the real name! */
+               reply = api_pipe_bind_auth_resp(p, &rpc_in);
+               break;
        }
 
        if (!reply)
-       {
-               reply = api_pipe_fault_resp(l, req, 0x1c010002);
-       }
-       
-       if (reply)
-       {
-               /* flatten the data into a single pdu */
-               reply = prs_copy(resp, &l->rhdr);
-       }
-
-       /* delete intermediate data used to set up the pdu.  leave
-          rdata alone because that's got the rest of the data in it */
-       rpcsrv_free_temp(l);
+               DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
 
        return reply;
 }
 
-BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
-{
-       DEBUG(10,("rpc_send_and_rcv_pdu\n"));
-
-       if (p->m != NULL)
-       {
-               return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
-       }
-       else if (p->l != NULL)
-       {
-               return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
-                                       p->name);
-       }
-       return False;
-}
 
 /*******************************************************************
- entry point from msrpc to smb.  adds data received to pdu; checks
- pdu; hands pdu off to msrpc, which gets a pdu back (except in the
- case of the RPC_BINDCONT pdu).
+ Calls the underlying RPC function for a named pipe.
  ********************************************************************/
-BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
-{
-       BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
 
-       if (reply && is_complete_pdu(&p->smb_pdu))
-       {
-               p->smb_pdu.offset = p->smb_pdu.data->data_size;
-               prs_link(NULL, &p->smb_pdu, NULL);
-               reply = rpc_send_and_rcv_pdu(p);
-               mem_free_data(p->smb_pdu.data);
-               prs_init(&p->smb_pdu, 0, 4, 0, True);
-
-       }
-       return reply;
-}
-
-/*******************************************************************
- receives a netlogon pipe and responds.
- ********************************************************************/
-static BOOL api_rpc_command(rpcsrv_struct *l, 
-                               char *rpc_name, struct api_struct *api_rpc_cmds,
-                               prs_struct *data)
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+                               prs_struct *rpc_in)
 {
        int fn_num;
-       DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
 
-       for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
-       {
-               if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
-               {
+       /* interpret the command */
+       DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
+
+       for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
+               if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
                        DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
                        break;
                }
        }
 
-       if (api_rpc_cmds[fn_num].name == NULL)
-       {
+       if (api_rpc_cmds[fn_num].name == NULL) {
                DEBUG(4, ("unknown\n"));
                return False;
        }
 
-       /* start off with 1024 bytes, and a large safety margin too */
-       prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
-
        /* do the actual command */
-       api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
-
-       if (l->rdata.data == NULL || l->rdata.offset == 0)
-       {
-               mem_free_data(l->rdata.data);
+       if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->rdata)) {
+               DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
+               prs_mem_free(&p->rdata);
                return False;
        }
 
-       mem_realloc_data(l->rdata.data, l->rdata.offset);
-
-       DEBUG(10,("called %s\n", rpc_name));
+       DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
 
        return True;
 }
-
-
-/*******************************************************************
- receives a netlogon pipe and responds.
- ********************************************************************/
-BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
-                               prs_struct *data)
-{
-       if (data == NULL || data->data == NULL)
-       {
-               DEBUG(2,("%s: NULL data received\n", rpc_name));
-               return False;
-       }
-
-       /* interpret the command */
-       if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
-       {
-               return False;
-       }
-
-       /* create the rpc header */
-       if (!create_rpc_reply(l, 0))
-       {
-               return False;
-       }
-
-       return True;
-}
-
-BOOL is_complete_pdu(prs_struct *ps)
-{
-       RPC_HDR hdr;
-       int len = ps->data->data_size;
-
-       DEBUG(10,("is_complete_pdu - len %d\n", len));
-       ps->offset = 0x0;
-
-       if (!ps->io)
-       {
-               /* writing.  oops!! */
-               DEBUG(4,("is_complete_pdu: write set, not read!\n"));
-               return False;
-       }
-               
-       if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
-       {
-               return False;
-       }
-       /* check that the fragment length is equal to the data length so far */
-       return hdr.frag_len == len;
-}
index f8bde1bf9b0237b6ec93cbf7d3b187f2236a0aad..b21b768a6e4b865922d281dda1c7f3e2480907bd 100644 (file)
@@ -5,6 +5,7 @@
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1998,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ *  Copyright (C) Jeremy Allison                                   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
@@ -55,7 +56,7 @@ void set_pipe_handle_offset(int max_open_files)
 }
 
 /****************************************************************************
-  reset pipe chain handle number
+ Reset pipe chain handle number.
 ****************************************************************************/
 void reset_chain_p(void)
 {
@@ -63,63 +64,64 @@ void reset_chain_p(void)
 }
 
 /****************************************************************************
 initialise pipe handle states...
Initialise pipe handle states.
 ****************************************************************************/
+
 void init_rpc_pipe_hnd(void)
 {
        bmap = bitmap_allocate(MAX_OPEN_PIPES);
-       if (!bmap) {
+       if (!bmap)
                exit_server("out of memory in init_rpc_pipe_hnd\n");
-       }
 }
 
+/****************************************************************************
+ Initialise an outgoing packet.
+****************************************************************************/
+
+BOOL pipe_init_outgoing_data( pipes_struct *p)
+{
+
+       memset(p->current_pdu, '\0', sizeof(p->current_pdu));
+
+       /* Free any memory in the current return data buffer. */
+       prs_mem_free(&p->rdata);
+
+       /*
+        * Initialize the outgoing RPC data buffer.
+        * we will use this as the raw data area for replying to rpc requests.
+        */     
+       if(!prs_init(&p->rdata, 1024, 4, MARSHALL)) {
+               DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
+               return False;
+       }
+
+       /* Reset the offset counters. */
+       p->data_sent_length = 0;
+       p->current_pdu_len = 0;
+       p->current_pdu_sent = 0;
+
+       return True;
+}
 
 /****************************************************************************
-  find first available file slot
+ Find first available pipe slot.
 ****************************************************************************/
+
 pipes_struct *open_rpc_pipe_p(char *pipe_name, 
                              connection_struct *conn, uint16 vuid)
 {
        int i;
        pipes_struct *p;
        static int next_pipe;
-       struct msrpc_state *m = NULL;
-       struct rpcsrv_struct *l = NULL;
-       user_struct *vuser = get_valid_user_struct(vuid);
-       struct user_creds usr;
-
-       ZERO_STRUCT(usr);
 
        DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
                 pipe_name, pipes_open));
        
-       if (vuser == NULL)
-       {
-               DEBUG(4,("invalid vuid %d\n", vuid));
-               return NULL;
-       }
-
-       /* set up unix credentials from the smb side, to feed over the pipe */
-       make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
-                                     vuser->real_name, vuser->guest);
-       usr.ptr_uxc = 1;
-       make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
-                                     vuser->n_groups, vuser->groups);
-       usr.ptr_uxs = 1;
-
-       /* set up nt credentials from the smb side, to feed over the pipe */
-       /* lkclXXXX todo!
-       make_creds_nt(&usr.ntc);
-       make_creds_nt_sec(&usr.nts);
-       */
-
        /* not repeating pipe numbers makes it easier to track things in 
           log files and prevents client bugs where pipe numbers are reused
           over connection restarts */
        if (next_pipe == 0)
-       {
                next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
-       }
 
        i = bitmap_find(bmap, next_pipe);
 
@@ -131,44 +133,19 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
        next_pipe = (i+1) % MAX_OPEN_PIPES;
 
        for (p = Pipes; p; p = p->next)
-       {
                DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
-       }
-
-       m = msrpc_use_add(pipe_name, &usr, False);
-       if (m == NULL)
-       {
-               DEBUG(5,("open pipes: msrpc redirect failed\n"));
-               return NULL;
-       }
-#if 0
-       }
-       else
-       {
-               l = malloc(sizeof(*l));
-               if (l == NULL)
-               {
-                       DEBUG(5,("open pipes: local msrpc malloc failed\n"));
-                       return NULL;
-               }
-               ZERO_STRUCTP(l);
-               l->rhdr.data  = NULL;
-               l->rdata.data = NULL;
-               l->rhdr.offset  = 0;
-               l->rdata.offset = 0;
-               
-               l->ntlmssp_validated = False;
-               l->ntlmssp_auth      = False;
-
-               memcpy(l->user_sess_key, vuser->user_sess_key,
-                      sizeof(l->user_sess_key));
-       }
-#endif
 
        p = (pipes_struct *)malloc(sizeof(*p));
-       if (!p) return NULL;
+       if (!p)
+               return NULL;
 
        ZERO_STRUCTP(p);
+
+       /*
+        * Initialize the RPC and PDU data buffers with no memory.
+        */     
+       prs_init(&p->rdata, 0, 4, MARSHALL);
+       
        DLIST_ADD(Pipes, p);
 
        bitmap_set(bmap, i);
@@ -177,24 +154,28 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
        pipes_open++;
 
        p->pnum = i;
-       p->m = m;
-       p->l = l;
 
        p->open = True;
        p->device_state = 0;
        p->priority = 0;
        p->conn = conn;
        p->vuid  = vuid;
+
+       p->max_trans_reply = 0;
        
-       p->file_offset     = 0;
-       p->prev_pdu_file_offset = 0;
-       p->hdr_offsets     = 0;
-       
-       fstrcpy(p->name, pipe_name);
+       p->ntlmssp_chal_flags = 0;
+       p->ntlmssp_auth_validated = False;
+       p->ntlmssp_auth_requested = False;
 
-       prs_init(&p->smb_pdu, 0, 4, 0, True);
-       prs_init(&p->rsmb_pdu, 0, 4, 0, False);
+       p->current_pdu_len = 0;
+       p->current_pdu_sent = 0;
+       p->data_sent_length = 0;
 
+       p->uid = (uid_t)-1;
+       p->gid = (gid_t)-1;
+       
+       fstrcpy(p->name, pipe_name);
+       
        DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
                 pipe_name, i, pipes_open));
        
@@ -202,182 +183,179 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
        
        /* OVERWRITE p as a temp variable, to display all open pipes */ 
        for (p = Pipes; p; p = p->next)
-       {
                DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
-       }
 
        return chain_p;
 }
 
 
 /****************************************************************************
writes data to a pipe.
Accepts incoming data on an rpc pipe.
 
- SERIOUSLY ALPHA CODE!
+ This code is probably incorrect at the moment. The problem is
+ that the rpc request shouldn't really be executed until all the
+ data needed for it is received. This currently assumes that each
+ SMBwrite or SMBwriteX contains all the data needed for an rpc
+ request. JRA.
  ****************************************************************************/
-ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
+
+ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
 {
        DEBUG(6,("write_pipe: %x", p->pnum));
+
        DEBUG(6,("name: %s open: %s len: %d",
-                p->name, BOOLSTR(p->open), n));
+                p->name, BOOLSTR(p->open), (int)n));
 
        dump_data(50, data, n);
 
-       return rpc_to_smb(p, data, n) ? ((ssize_t)n) : -1;
+       return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
 }
 
 
 /****************************************************************************
reads data from a pipe.
Replyies to a request to read data from a pipe.
 
headers are interspersed with the data at regular intervals.  by the time
Headers are interspersed with the data at PDU intervals. By the time
  this function is called, the start of the data could possibly have been
  read by an SMBtrans (file_offset != 0).
 
calling create_rpc_reply() here is a fudge.  the data should already
Calling create_rpc_reply() here is a hack. The data should already
  have been prepared into arrays of headers + data stream sections.
 
  ****************************************************************************/
-int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
+
+int read_from_pipe(pipes_struct *p, char *data, int n)
 {
-       int num = 0;
-       int pdu_len = 0;
-       uint32 hdr_num = 0;
-       int pdu_data_sent; /* amount of current pdu already sent */
-       int data_pos; /* entire rpc data sent - no headers, no auth verifiers */
-       int this_pdu_data_pos;
-
-       DEBUG(6,("read_pipe: %x name: %s open: %s pos: %d len: %d",
-                p->pnum, p->name, BOOLSTR(p->open),
-                pos, n));
-
-       if (!p || !p->open)
-       {
-               DEBUG(6,("pipe not open\n"));
+       uint32 pdu_remaining = 0;
+       int data_returned = 0;
+
+       if (!p || !p->open) {
+               DEBUG(0,("read_from_pipe: pipe not open\n"));
                return -1;              
        }
 
+       DEBUG(6,("read_from_pipe: %x", p->pnum));
 
-       if (p->rsmb_pdu.data == NULL || p->rsmb_pdu.data->data == NULL ||
-           p->rsmb_pdu.data->data_used == 0)
-       {
-               return 0;
+       DEBUG(6,("name: %s len: %d\n", p->name, n));
+
+       /*
+        * We cannot return more than one PDU length per
+        * read request.
+        */
+
+       if(n > MAX_PDU_FRAG_LEN) {
+               DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
+only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
+               return -1;
        }
 
-       DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
-                p, p->file_offset, n));
+       /*
+        * Determine if there is still data to send in the
+        * pipe PDU buffer. Always send this first. Never
+        * send more than is left in the current PDU. The
+        * client should send a new read request for a new
+        * PDU.
+        */
 
-       /* the read request starts from where the SMBtrans2 left off. */
-       data_pos = p->file_offset - p->hdr_offsets;
-       pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
-       this_pdu_data_pos = (pdu_data_sent == 0) ? 0 : (pdu_data_sent - 0x18);
+       if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) {
+               data_returned = MIN(n, pdu_remaining);
 
-       if (!IS_BITS_SET_ALL(p->l->hdr.flags, RPC_FLG_LAST))
-       {
-               /* intermediate fragment - possibility of another header */
-               
-               DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
-                        p->l->hdr.frag_len, data_pos, pdu_data_sent));
-               
-               if (pdu_data_sent == 0)
-               {
-                       DEBUG(6,("read_pipe: next fragment header\n"));
-
-                       /* this is subtracted from the total data bytes, later */
-                       hdr_num = 0x18;
-                       p->hdr_offsets += 0x18;
-                       data_pos -= 0x18;
-
-                       /* create and copy in a new header. */
-                       create_rpc_reply(p->l, data_pos);
-               }                       
-       }
-       
-       pdu_len = mem_buf_len(p->rsmb_pdu.data);
-       num = pdu_len - this_pdu_data_pos;
-       
-       DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
-       
-       if (num > n) num = n;
-       if (num <= 0)
-       {
-               DEBUG(5,("read_pipe: 0 or -ve data length\n"));
-               return 0;
-       }
+               DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
+returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, 
+                       (unsigned int)p->current_pdu_sent, (int)data_returned));
 
-       if (num < hdr_num)
-       {
-               DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
+               memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned);
+               p->current_pdu_sent += (uint32)data_returned;
+               return data_returned;
        }
 
-       mem_buf_copy(data, p->rsmb_pdu.data, pdu_data_sent, num);
-       
-       p->file_offset  += num;
-       pdu_data_sent  += num;
-       
-       if (hdr_num == 0x18 && num == 0x18)
-       {
-               DEBUG(6,("read_pipe: just header read\n"));
+       /*
+        * At this point p->current_pdu_len == p->current_pdu_sent (which
+        * may of course be zero if this is the first return fragment.
+        */
+
+       DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n",
+               p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) ));
+
+       if(p->data_sent_length >= prs_offset(&p->rdata)) {
+               /*
+                * We have sent all possible data. Return 0.
+                */
+               return 0;
        }
 
-       if (pdu_data_sent == p->l->hdr.frag_len)
-       {
-               DEBUG(6,("read_pipe: next fragment expected\n"));
-               p->prev_pdu_file_offset = p->file_offset;
+       /*
+        * We need to create a new PDU from the data left in p->rdata.
+        * Create the header/data/footers. This also sets up the fields
+        * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
+        * and stores the outgoing PDU in p->current_pdu.
+        */
+
+       if(!create_next_pdu(p)) {
+               DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
+                        p->name));
+               return -1;
        }
 
-       return num;
-}
+       data_returned = MIN(n, p->current_pdu_len);
 
+       memcpy( data, p->current_pdu, (size_t)data_returned);
+       p->current_pdu_sent += (uint32)data_returned;
+       return data_returned;
+}
 
 /****************************************************************************
 wait device state on a pipe.  exactly what this is for is unknown...
Wait device state on a pipe. Exactly what this is for is unknown...
 ****************************************************************************/
+
 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
 {
-       if (p == NULL) return False;
+       if (p == NULL)
+               return False;
 
-       if (p->open)
-       {
-               DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
-                        timestring(), priority, p->name));
+       if (p->open) {
+               DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
+                        priority, p->name));
 
                p->priority = priority;
                
                return True;
        } 
 
-       DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
-                timestring(), priority, p->name));
+       DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
+                priority, p->name));
        return False;
 }
 
 
 /****************************************************************************
 set device state on a pipe.  exactly what this is for is unknown...
Set device state on a pipe. Exactly what this is for is unknown...
 ****************************************************************************/
+
 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
 {
-       if (p == NULL) return False;
+       if (p == NULL)
+               return False;
 
        if (p->open) {
-               DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
-                        timestring(), device_state, p->name));
+               DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
+                        device_state, p->name));
 
                p->device_state = device_state;
                
                return True;
        } 
 
-       DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
-                timestring(), device_state, p->name));
+       DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
+                device_state, p->name));
        return False;
 }
 
 
 /****************************************************************************
-  close an rpc pipe
+ Close an rpc pipe.
 ****************************************************************************/
+
 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
 {
        if (!p) {
@@ -385,8 +363,7 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
                return False;
        }
 
-       mem_buf_free(&(p->smb_pdu .data));
-       mem_buf_free(&(p->rsmb_pdu.data));
+       prs_mem_free(&p->rdata);
 
        bitmap_clear(bmap, p->pnum - pipe_handle_offset);
 
@@ -397,50 +374,31 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
 
        DLIST_REMOVE(Pipes, p);
 
-       if (p->m != NULL)
-       {
-               DEBUG(4,("closed msrpc redirect: "));
-               if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
-               {
-                       DEBUG(4,("OK\n"));
-               }
-               else
-               {
-                       DEBUG(4,("FAILED\n"));
-               }
-       }
-
-       if (p->l != NULL)
-       {
-               DEBUG(4,("closed msrpc local: OK\n"));
-
-               mem_free_data(p->l->rdata  .data);
-               rpcsrv_free_temp(p->l);
-
-               free(p->l);
-       }
-
        ZERO_STRUCTP(p);
+
        free(p);
        
        return True;
 }
 
 /****************************************************************************
-  close an rpc pipe
+ Find an rpc pipe given a pipe handle in a buffer and an offset.
 ****************************************************************************/
+
 pipes_struct *get_rpc_pipe_p(char *buf, int where)
 {
        int pnum = SVAL(buf,where);
 
-       if (chain_p) return chain_p;
+       if (chain_p)
+               return chain_p;
 
        return get_rpc_pipe(pnum);
 }
 
 /****************************************************************************
-  close an rpc pipe
+ Find an rpc pipe given a pipe handle.
 ****************************************************************************/
+
 pipes_struct *get_rpc_pipe(int pnum)
 {
        pipes_struct *p;
@@ -448,15 +406,11 @@ pipes_struct *get_rpc_pipe(int pnum)
        DEBUG(4,("search for pipe pnum=%x\n", pnum));
 
        for (p=Pipes;p;p=p->next)
-       {
                DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n", 
                          p->name, p->pnum, pipes_open));  
-       }
 
-       for (p=Pipes;p;p=p->next)
-       {
-               if (p->pnum == pnum)
-               {
+       for (p=Pipes;p;p=p->next) {
+               if (p->pnum == pnum) {
                        chain_p = p;
                        return p;
                }
@@ -464,4 +418,3 @@ pipes_struct *get_rpc_pipe(int pnum)
 
        return NULL;
 }
-
index ea3150fd3c4d59b6346450000fd1cb3ed45a565d..fc3ce9c0d23042d32defb08a7550c898be137646 100644 (file)
@@ -1,4 +1,3 @@
-
 /* 
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
@@ -38,10 +37,10 @@ static void reg_reply_close(REG_Q_CLOSE *q_r,
        REG_R_CLOSE r_u;
 
        /* set up the REG unknown_1 response */
-       bzero(r_u.pol.data, POL_HND_SIZE);
+       memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
 
        /* close the policy handle */
-       if (close_policy_hnd(&(q_r->pol)))
+       if (close_lsa_policy_hnd(&(q_r->pol)))
        {
                r_u.status = 0;
        }
@@ -61,7 +60,7 @@ static void reg_reply_close(REG_Q_CLOSE *q_r,
 /*******************************************************************
  api_reg_close
  ********************************************************************/
-static void api_reg_close( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_close( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        REG_Q_CLOSE q_r;
@@ -71,6 +70,8 @@ static void api_reg_close( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        reg_reply_close(&q_r, rdata);
+
+       return True;
 }
 
 
@@ -84,7 +85,7 @@ static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
 
        r_u.status = 0x0;
        /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !open_policy_hnd(&(r_u.pol)))
+       if (r_u.status == 0x0 && !open_lsa_policy_hnd(&(r_u.pol)))
        {
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
@@ -100,7 +101,7 @@ static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
 /*******************************************************************
  api_reg_open
  ********************************************************************/
-static void api_reg_open( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_open( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        REG_Q_OPEN_HKLM q_u;
@@ -110,6 +111,8 @@ static void api_reg_open( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        reg_reply_open(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -126,35 +129,30 @@ static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
 
        DEBUG(5,("reg_open_entry: %d\n", __LINE__));
 
-       if (status == 0 && find_policy_by_hnd(&(q_u->pol)) == -1)
+       if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
        {
                status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       if (status == 0x0 && !open_policy_hnd(&pol))
+       if (status == 0x0 && !open_lsa_policy_hnd(&pol))
        {
                status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
        }
 
-       unistr2_to_ascii(name, &q_u->uni_name, sizeof(name)-1);
+       fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));
 
        if (status == 0x0)
        {
                DEBUG(5,("reg_open_entry: %s\n", name));
                /* lkcl XXXX do a check on the name, here */
-               if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") &&
-                   !strequal(name, "SYSTEM\\CurrentControlSet\\Services\\NETLOGON\\Parameters\\"))
-               {
-                       status = 0xC000000 | NT_STATUS_ACCESS_DENIED;
-               }
        }
 
-       if (status == 0x0 && !set_policy_reg_name(&pol, name))
+       if (status == 0x0 && !set_lsa_policy_reg_name(&pol, name))
        {
                status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
        }
 
-       make_reg_r_open_entry(&r_u, &pol, status);
+       init_reg_r_open_entry(&r_u, &pol, status);
 
        /* store the response in the SMB stream */
        reg_io_r_open_entry("", &r_u, rdata, 0);
@@ -165,7 +163,7 @@ static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
 /*******************************************************************
  api_reg_open_entry
  ********************************************************************/
-static void api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_open_entry( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        REG_Q_OPEN_ENTRY q_u;
@@ -175,6 +173,8 @@ static void api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply. */
        reg_reply_open_entry(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -187,32 +187,19 @@ static void reg_reply_info(REG_Q_INFO *q_u,
        uint32 status     = 0;
 
        REG_R_INFO r_u;
-       uint32 type = 0xcafeface;
-       BUFFER2 buf;
-       fstring name;
-
-       ZERO_STRUCT(buf);
 
        DEBUG(5,("reg_info: %d\n", __LINE__));
 
-       if (status == 0x0 && !get_policy_reg_name(&q_u->pol, name))
+       if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
        {
                status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       if (status == 0 &&
-          strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions"))
+       if (status == 0)
        {
-               char *key = "LanmanNT";
-               make_buffer2(&buf, key, strlen(key));
-               type = 0x1;
-       }
-       else
-       {
-               status = 0x2; /* Win32 status code.  ick */
        }
 
-       make_reg_r_info(&r_u, &type, &buf, status);
+       init_reg_r_info(&r_u, 1, "LanmanNT", 0x12, 0x12, status);
 
        /* store the response in the SMB stream */
        reg_io_r_info("", &r_u, rdata, 0);
@@ -223,7 +210,7 @@ static void reg_reply_info(REG_Q_INFO *q_u,
 /*******************************************************************
  api_reg_info
  ********************************************************************/
-static void api_reg_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_info( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        REG_Q_INFO q_u;
@@ -233,6 +220,8 @@ static void api_reg_info( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        reg_reply_info(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -251,7 +240,7 @@ static struct api_struct api_reg_cmds[] =
 /*******************************************************************
  receives a reg pipe and responds.
  ********************************************************************/
-BOOL api_reg_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds, data);
 }
index 738623ec4d5229bf9218b50a2feaae836aad5892..169dc2169edc4cd5b50c1433653059894fcf9b2d 100644 (file)
 
 extern int DEBUGLEVEL;
 
-extern fstring global_sam_name;
+extern fstring global_myworkgroup;
 extern pstring global_myname;
 extern DOM_SID global_sam_sid;
-extern DOM_SID global_sid_S_1_1;
-extern DOM_SID global_sid_S_1_5_20;
+
+extern rid_name domain_group_rids[];
+extern rid_name domain_alias_rids[];
+extern rid_name builtin_alias_rids[];
 
 /*******************************************************************
   This next function should be replaced with something that
@@ -69,18 +71,15 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
                        /* skip the requested number of entries.
                           not very efficient, but hey...
                         */
-                       if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
-                       {
-                               start_idx--;
-                       }
+                       start_idx--;
                        continue;
                }
 
-               user_name_len = strlen(pwd->nt_name);
-               make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->nt_name, user_name_len);
-               make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
+               user_name_len = strlen(pwd->smb_name);
+               init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
+               init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
                pw_buf[(*num_entries)].user_rid = pwd->user_rid;
-               bzero( pw_buf[(*num_entries)].nt_pwd , 16);
+               memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
 
                /* Now check if the NT compatible password is available. */
                if (pwd->smb_nt_passwd != NULL)
@@ -91,7 +90,7 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
                pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
 
                DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
-                         (*num_entries), pwd->nt_name,
+                         (*num_entries), pwd->smb_name,
                          pwd->user_rid, pwd->acct_ctrl));
 
                if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
@@ -121,10 +120,10 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
        SAMR_R_CLOSE_HND r_u;
 
        /* set up the SAMR unknown_1 response */
-       bzero(r_u.pol.data, POL_HND_SIZE);
+       memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
 
        /* close the policy handle */
-       if (close_policy_hnd(&(q_u->pol)))
+       if (close_lsa_policy_hnd(&(q_u->pol)))
        {
                r_u.status = 0;
        }
@@ -145,11 +144,17 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
 /*******************************************************************
  api_samr_close_hnd
  ********************************************************************/
-static void api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CLOSE_HND q_u;
+
+       /* grab the samr unknown 1 */
        samr_io_q_close_hnd("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_close_hnd(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -165,19 +170,19 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
        r_u.status = 0x0;
 
        /* find the connection policy handle. */
-       if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->connect_pol)) == -1))
+       if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
        {
                r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
        /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.domain_pol))))
+       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
        {
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /* associate the domain SID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
+       if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
        {
                /* oh, whoops.  don't know what error message to return, here */
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -185,7 +190,7 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
 
        if (r_u.status != 0 && pol_open)
        {
-               close_policy_hnd(&(r_u.domain_pol));
+               close_lsa_policy_hnd(&(r_u.domain_pol));
        }
 
        DEBUG(5,("samr_open_domain: %d\n", __LINE__));
@@ -200,11 +205,17 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
 /*******************************************************************
  api_samr_open_domain
  ********************************************************************/
-static void api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_OPEN_DOMAIN q_u;
+
+       /* grab the samr open */
        samr_io_q_open_domain("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_open_domain(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -218,18 +229,18 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
        uint32 status = 0x0;
 
        /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
        {
                status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
        /* find the user's rid */
-       if ((status == 0x0) && (get_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
+       if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
        {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
-       make_samr_r_unknown_2c(&r_u, status);
+       init_samr_r_unknown_2c(&r_u, status);
 
        DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
 
@@ -243,11 +254,17 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
 /*******************************************************************
  api_samr_unknown_2c
  ********************************************************************/
-static void api_samr_unknown_2c( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_2C q_u;
+
+       /* grab the samr open */
        samr_io_q_unknown_2c("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_unknown_2c(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -265,37 +282,40 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
        status = 0x0;
 
        /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
        {
                status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
        /* find the user's rid */
-       if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
+       if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
        {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        if (status == 0x0)
        {
-               DOM_SID usr_sid;
+               DOM_SID user_sid;
+               DOM_SID everyone_sid;
 
-               usr_sid = global_sam_sid;
+               user_sid = global_sam_sid;
 
-               SMB_ASSERT_ARRAY(usr_sid.sub_auths, usr_sid.num_auths+1);
+               SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
 
                /*
                 * Add the user RID.
                 */
-               sid_append_rid(&usr_sid, rid);
+               user_sid.sub_auths[user_sid.num_auths++] = rid;
                
-               /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
-               /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
-               make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &global_sid_S_1_1);
-               make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &usr_sid);
+                       string_to_sid(&everyone_sid, "S-1-1");
+
+                       /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
+                       /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
+                       init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
+                       init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
        }
 
-       make_samr_r_unknown_3(&r_u,
+       init_samr_r_unknown_3(&r_u,
                                0x0001, 0x8004,
                                0x00000014, 0x0002, 0x0070,
                                2, sid, status);
@@ -312,11 +332,17 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
 /*******************************************************************
  api_samr_unknown_3
  ********************************************************************/
-static void api_samr_unknown_3( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_UNKNOWN_3 q_u;
+
+       /* grab the samr open */
        samr_io_q_unknown_3("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_unknown_3(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -332,9 +358,10 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
        int total_entries;
 
        r_e.status = 0x0;
+       r_e.total_num_entries = 0;
 
        /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
@@ -342,27 +369,16 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
        DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
 
        become_root(True);
-       get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
-                          MAX_SAM_ENTRIES, q_u->acb_mask);
+       get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
        unbecome_root(True);
 
-       make_samr_r_enum_dom_users(&r_e, 
-                                  q_u->start_idx + num_entries, num_entries,
+       init_samr_r_enum_dom_users(&r_e, total_entries,
+                                  q_u->unknown_0, num_entries,
                                   pass, r_e.status);
 
        /* store the response in the SMB stream */
        samr_io_r_enum_dom_users("", &r_e, rdata, 0);
 
-       if (r_e.sam != NULL)
-       {
-               free(r_e.sam);
-       }
-
-       if (r_e.uni_acct_name != NULL)
-       {
-               free(r_e.uni_acct_name);
-       }
-
        DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
 
 }
@@ -370,2278 +386,984 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
 /*******************************************************************
  api_samr_enum_dom_users
  ********************************************************************/
-static void api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_ENUM_DOM_USERS q_e;
+
+       /* grab the samr open */
        samr_io_q_enum_dom_users("", &q_e, data, 0);
+
+       /* construct reply. */
        samr_reply_enum_dom_users(&q_e, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
- samr_reply_add_groupmem
+ samr_reply_enum_dom_groups
  ********************************************************************/
-static void samr_reply_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_u,
+static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_ADD_GROUPMEM r_e;
-       DOM_SID group_sid;
-       uint32 group_rid;
-       fstring group_sid_str;
+       SAMR_R_ENUM_DOM_GROUPS r_e;
+       SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+       int num_entries;
+       BOOL got_grps;
+       char *dummy_group = "Domain Admins";
 
        r_e.status = 0x0;
+       r_e.num_entries = 0;
 
        /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
+       if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
-       else
-       {
-               sid_to_string(group_sid_str, &group_sid);
-               sid_split_rid(&group_sid, &group_rid);
-       }
 
-       if (r_e.status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", group_sid_str));
+       DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
 
-               if (sid_equal(&group_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
+       got_grps = True;
+       num_entries = 1;
+       init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
+       pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
 
-                       become_root(True);
-                       r_e.status = add_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
-               }
+       if (r_e.status == 0 && got_grps)
+       {
+               init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
        }
 
        /* store the response in the SMB stream */
-       samr_io_r_add_groupmem("", &r_e, rdata, 0);
+       samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
 
-       DEBUG(5,("samr_add_groupmem: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_add_groupmem
+ api_samr_enum_dom_groups
  ********************************************************************/
-static void api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_ADD_GROUPMEM q_e;
-       samr_io_q_add_groupmem("", &q_e, data, 0);
-       samr_reply_add_groupmem(&q_e, rdata);
+       SAMR_Q_ENUM_DOM_GROUPS q_e;
+
+       /* grab the samr open */
+       samr_io_q_enum_dom_groups("", &q_e, data, 0);
+
+       /* construct reply. */
+       samr_reply_enum_dom_groups(&q_e, rdata);
+
+       return True;
 }
 
+
 /*******************************************************************
- samr_reply_del_groupmem
+ samr_reply_enum_dom_aliases
  ********************************************************************/
-static void samr_reply_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_u,
+static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_DEL_GROUPMEM r_e;
-       DOM_SID group_sid;
-       uint32 group_rid;
-       fstring group_sid_str;
+       SAMR_R_ENUM_DOM_ALIASES r_e;
+       SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+       int num_entries = 0;
+       DOM_SID sid;
+       fstring sid_str;
+       fstring sam_sid_str;
 
        r_e.status = 0x0;
+       r_e.num_entries = 0;
 
        /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
+       if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
        {
                r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
-       else
-       {
-               sid_to_string(group_sid_str, &group_sid);
-               sid_split_rid(&group_sid, &group_rid);
-       }
 
-       if (r_e.status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", group_sid_str));
+       sid_to_string(sid_str, &sid);
+       sid_to_string(sam_sid_str, &global_sam_sid);
 
-               if (sid_equal(&group_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
+       DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
 
-                       become_root(True);
-                       r_e.status = del_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else
+       /* well-known aliases */
+       if (strequal(sid_str, "S-1-5-32"))
+       {
+               char *name;
+               while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
                {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
+                       init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
+                       pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
+                       num_entries++;
                }
        }
+       else if (strequal(sid_str, sam_sid_str))
+       {
+               /* local aliases */
+               /* oops!  there's no code to deal with this */
+               DEBUG(3,("samr_reply_enum_dom_aliases: enum of aliases in our domain not supported yet\n"));
+               num_entries = 0;
+       }
+               
+       init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
 
        /* store the response in the SMB stream */
-       samr_io_r_del_groupmem("", &r_e, rdata, 0);
+       samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
 
-       DEBUG(5,("samr_del_groupmem: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_del_groupmem
+ api_samr_enum_dom_aliases
  ********************************************************************/
-static void api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_DEL_GROUPMEM q_e;
-       samr_io_q_del_groupmem("", &q_e, data, 0);
-       samr_reply_del_groupmem(&q_e, rdata);
+       SAMR_Q_ENUM_DOM_ALIASES q_e;
+
+       /* grab the samr open */
+       samr_io_q_enum_dom_aliases("", &q_e, data, 0);
+
+       /* construct reply. */
+       samr_reply_enum_dom_aliases(&q_e, rdata);
+
+       return True;
 }
 
+
 /*******************************************************************
- samr_reply_add_aliasmem
+ samr_reply_query_dispinfo
  ********************************************************************/
-static void samr_reply_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u,
+static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_ADD_ALIASMEM r_e;
-       DOM_SID alias_sid;
-       uint32 alias_rid;
-       fstring alias_sid_str;
+       SAMR_R_QUERY_DISPINFO r_e;
+       SAM_INFO_CTR ctr;
+       SAM_INFO_1 info1;
+       SAM_INFO_2 info2;
+       SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+       int num_entries = 0;
+       int total_entries = 0;
+       BOOL got_pwds;
+       uint16 switch_level = 0x0;
+
+       ZERO_STRUCT(r_e);
 
        r_e.status = 0x0;
 
+       DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
        /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
+       if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(alias_sid_str, &alias_sid);
-               sid_split_rid(&alias_sid, &alias_rid);
+               DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
        }
 
        if (r_e.status == 0x0)
        {
-               DEBUG(10,("sid is %s\n", alias_sid_str));
+               become_root(True);
+               got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
+               unbecome_root(True);
 
-               if (sid_equal(&alias_sid, &global_sam_sid))
+               switch (q_u->switch_level)
                {
-                       DEBUG(10,("add member on Domain SID\n"));
+                       case 0x1:
+                       {
+                       
+                               /* query disp info is for users */
+                               switch_level = 0x1;
+                               init_sam_info_1(&info1, ACB_NORMAL,
+                                       q_u->start_idx, num_entries, pass);
 
-                       become_root(True);
-                       r_e.status = add_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
-               {
-                       DEBUG(10,("add member on BUILTIN SID\n"));
+                               ctr.sam.info1 = &info1;
 
-                       become_root(True);
-                       r_e.status = add_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+                               break;
+                       }
+                       case 0x2:
+                       {
+                               /* query disp info is for servers */
+                               switch_level = 0x2;
+                               init_sam_info_2(&info2, ACB_WSTRUST,
+                                       q_u->start_idx, num_entries, pass);
+
+                               ctr.sam.info2 = &info2;
+
+                               break;
+                       }
                }
        }
 
+       if (r_e.status == 0 && got_pwds)
+       {
+               init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
+       }
+
        /* store the response in the SMB stream */
-       samr_io_r_add_aliasmem("", &r_e, rdata, 0);
+       samr_io_r_query_dispinfo("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
 
-       DEBUG(5,("samr_add_aliasmem: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_add_aliasmem
+ api_samr_query_dispinfo
  ********************************************************************/
-static void api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_ADD_ALIASMEM q_e;
-       samr_io_q_add_aliasmem("", &q_e, data, 0);
-       samr_reply_add_aliasmem(&q_e, rdata);
+       SAMR_Q_QUERY_DISPINFO q_e;
+
+       /* grab the samr open */
+       samr_io_q_query_dispinfo("", &q_e, data, 0);
+
+       /* construct reply. */
+       samr_reply_query_dispinfo(&q_e, rdata);
+
+       return True;
 }
 
+
 /*******************************************************************
- samr_reply_del_aliasmem
+ samr_reply_query_aliasinfo
  ********************************************************************/
-static void samr_reply_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u,
+static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_DEL_ALIASMEM r_e;
-       DOM_SID alias_sid;
-       uint32 alias_rid;
-       fstring alias_sid_str;
+       SAMR_R_QUERY_ALIASINFO r_e;
 
        r_e.status = 0x0;
+       r_e.ptr = 0;
 
        /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
+       if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
-       else
-       {
-               sid_to_string(alias_sid_str, &alias_sid);
-               sid_split_rid(&alias_sid, &alias_rid);
-       }
+
+       DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
 
        if (r_e.status == 0x0)
        {
-               DEBUG(10,("sid is %s\n", alias_sid_str));
-
-               if (sid_equal(&alias_sid, &global_sam_sid))
+               if (q_u->switch_level != 3)
                {
-                       DEBUG(10,("del member on Domain SID\n"));
-
-                       become_root(True);
-                       r_e.status = del_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
-               {
-                       DEBUG(10,("del member on BUILTIN SID\n"));
-
-                       become_root(True);
-                       r_e.status = del_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
+                       r_e.status = NT_STATUS_INVALID_INFO_CLASS;
                }
        }
 
+       init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
+                           "<account description>",
+                               r_e.status);
+
        /* store the response in the SMB stream */
-       samr_io_r_del_aliasmem("", &r_e, rdata, 0);
+       samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
+
+       DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
 
-       DEBUG(5,("samr_del_aliasmem: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_del_aliasmem
+ api_samr_query_aliasinfo
  ********************************************************************/
-static void api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_DEL_ALIASMEM q_e;
-       samr_io_q_del_aliasmem("", &q_e, data, 0);
-       samr_reply_del_aliasmem(&q_e, rdata);
+       SAMR_Q_QUERY_ALIASINFO q_e;
+
+       /* grab the samr open */
+       samr_io_q_query_aliasinfo("", &q_e, data, 0);
+
+       /* construct reply. */
+       samr_reply_query_aliasinfo(&q_e, rdata);
+
+       return True;
 }
 
+
 /*******************************************************************
- samr_reply_enum_domains
+ samr_reply_lookup_ids
  ********************************************************************/
-static void samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS *q_u,
+static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_ENUM_DOMAINS r_e;
-       char  **doms = NULL;
-       uint32 num_entries = 0;
-
-       r_e.status = 0x0;
-       r_e.num_entries2 = 0;
+       uint32 rid[MAX_SAM_ENTRIES];
+       uint32 status     = 0;
+       int num_rids = q_u->num_sids1;
 
-       ZERO_STRUCT(r_e);
+       SAMR_R_LOOKUP_IDS r_u;
 
-       r_e.status = 0x0;
+       DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
 
-       /* find the connection policy handle. */
-       if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       if (num_rids > MAX_SAM_ENTRIES)
        {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+               num_rids = MAX_SAM_ENTRIES;
+               DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
        }
 
-       DEBUG(5,("samr_reply_enum_domains:\n"));
+#if 0
+       int i;
+       SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
 
-       if (!enumdomains(&doms, &num_entries))
+       for (i = 0; i < num_rids && status == 0; i++)
        {
-               r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
-       }
+               struct sam_passwd *sam_pass;
+               fstring user_name;
 
-       if (r_e.status == 0x0)
-       {
-               make_samr_r_enum_domains(&r_e,
-                         q_u->start_idx + num_entries,
-                         num_entries, doms, r_e.status);
-       }
 
-       /* store the response in the SMB stream */
-       samr_io_r_enum_domains("", &r_e, rdata, 0);
+               fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
+                                           q_u->uni_user_name[i].uni_str_len));
 
-       free_char_array(num_entries, doms);
+               /* find the user account */
+               become_root(True);
+               sam_pass = get_smb21pwd_entry(user_name, 0);
+               unbecome_root(True);
 
-       if (r_e.sam != NULL)
-       {
-               free(r_e.sam);
+               if (sam_pass == NULL)
+               {
+                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+                       rid[i] = 0;
+               }
+               else
+               {
+                       rid[i] = sam_pass->user_rid;
+               }
        }
+#endif
 
-       if (r_e.uni_dom_name != NULL)
-       {
-               free(r_e.uni_dom_name);
-       }
+       num_rids = 1;
+       rid[0] = BUILTIN_ALIAS_RID_USERS;
+
+       init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
+
+       /* store the response in the SMB stream */
+       samr_io_r_lookup_ids("", &r_u, rdata, 0);
+
+       DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
 
-       DEBUG(5,("samr_enum_domains: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_enum_domains
+ api_samr_lookup_ids
  ********************************************************************/
-static void api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_ENUM_DOMAINS q_e;
+       SAMR_Q_LOOKUP_IDS q_u;
 
-       /* grab the samr open */
-       samr_io_q_enum_domains("", &q_e, data, 0);
+       /* grab the samr 0x10 */
+       samr_io_q_lookup_ids("", &q_u, data, 0);
 
-       /* construct reply. */
-       samr_reply_enum_domains(&q_e, rdata);
+       /* construct reply.  always indicate success */
+       samr_reply_lookup_ids(&q_u, rdata);
+
+       return True;
 }
 
 /*******************************************************************
- samr_reply_enum_dom_groups
+ samr_reply_lookup_names
  ********************************************************************/
-static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
+
+static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_ENUM_DOM_GROUPS r_e;
-       DOMAIN_GRP *grps = NULL;
-       int num_entries = 0;
-       DOM_SID sid;
-       fstring sid_str;
-
-       r_e.status = 0x0;
-       r_e.num_entries2 = 0;
-
-       /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
-       {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
+       uint32 rid[MAX_SAM_ENTRIES];
+       uint8  type[MAX_SAM_ENTRIES];
+       uint32 status = 0;
+       int i;
+       int num_rids = q_u->num_names1;
+       DOM_SID pol_sid;
 
-       sid_to_string(sid_str, &sid);
+       SAMR_R_LOOKUP_NAMES r_u;
 
-       DEBUG(5,("samr_reply_enum_dom_groups: sid %s\n", sid_str));
+       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
 
-       if (sid_equal(&sid, &global_sam_sid))
-       {
-               BOOL ret;
+       ZERO_ARRAY(rid);
+       ZERO_ARRAY(type);
 
-               become_root(True);
-               ret = enumdomgroups(&grps, &num_entries);
-               unbecome_root(True);
-               if (!ret)
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
+       if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
+        status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+               init_samr_r_lookup_names(&r_u, 0, rid, type, status);
+               if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+                       DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+               return False;
                }
-       }
+               return True;
+    }
 
-       if (r_e.status == 0x0)
-       {
-               make_samr_r_enum_dom_groups(&r_e,
-                         q_u->start_idx + num_entries,
-                         num_entries, grps, r_e.status);
+       if (num_rids > MAX_SAM_ENTRIES) {
+               num_rids = MAX_SAM_ENTRIES;
+               DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
        }
 
-       /* store the response in the SMB stream */
-       samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
+       SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
 
-       if (grps != NULL)
-       {
-               free(grps);
-       }
-
-       if (r_e.sam != NULL)
-       {
-               free(r_e.sam);
-       }
-
-       if (r_e.uni_grp_name != NULL)
-       {
-               free(r_e.uni_grp_name);
-       }
-
-       DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_enum_dom_groups
- ********************************************************************/
-static void api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_ENUM_DOM_GROUPS q_e;
-
-       /* grab the samr open */
-       samr_io_q_enum_dom_groups("", &q_e, data, 0);
-
-       /* construct reply. */
-       samr_reply_enum_dom_groups(&q_e, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_enum_dom_aliases
- ********************************************************************/
-static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_ENUM_DOM_ALIASES r_e;
-       LOCAL_GRP *alss = NULL;
-       int num_entries = 0;
-       DOM_SID sid;
-       fstring sid_str;
-
-       r_e.status = 0x0;
-       r_e.num_entries2 = 0;
-
-       /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
-       {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       sid_to_string(sid_str, &sid);
-
-       DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
-
-       /* well-known aliases */
-       if (sid_equal(&sid, &global_sid_S_1_5_20))
-       {
-               BOOL ret;
-               /* builtin aliases */
-
-               become_root(True);
-               ret = enumdombuiltins(&alss, &num_entries);
-               unbecome_root(True);
-               if (!ret)
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
-               }
-       }
-       else if (sid_equal(&sid, &global_sam_sid))
-       {
-               BOOL ret;
-               /* local aliases */
-
-               become_root(True);
-               ret = enumdomaliases(&alss, &num_entries);
-               unbecome_root(True);
-               if (!ret)
-               {
-                       r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
-               }
-       }
-               
-       if (r_e.status == 0x0)
-       {
-               make_samr_r_enum_dom_aliases(&r_e,
-                              q_u->start_idx + num_entries,
-                              num_entries, alss, r_e.status);
-       }
-
-       /* store the response in the SMB stream */
-       samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
-
-       if (alss != NULL)
-       {
-               free(alss);
-       }
-
-       if (r_e.sam != NULL)
-       {
-               free(r_e.sam);
-       }
-
-       if (r_e.uni_grp_name != NULL)
-       {
-               free(r_e.uni_grp_name);
-       }
-
-       DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_enum_dom_aliases
- ********************************************************************/
-static void api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_ENUM_DOM_ALIASES q_e;
-
-       /* grab the samr open */
-       samr_io_q_enum_dom_aliases("", &q_e, data, 0);
-
-       /* construct reply. */
-       samr_reply_enum_dom_aliases(&q_e, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_dispinfo
- ********************************************************************/
-static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_QUERY_DISPINFO r_e;
-       SAM_DISPINFO_CTR ctr;
-       SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
-       DOMAIN_GRP *grps = NULL;
-       DOMAIN_GRP *sam_grps = NULL;
-       uint32 data_size = 0;
-       uint32 status = 0x0;
-       uint16 acb_mask = ACB_NORMAL;
-       int num_sam_entries = 0;
-       int num_entries = 0;
-       int total_entries;
-
-       DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (find_policy_by_hnd(&(q_u->domain_pol)) == -1)
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-               DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
-       }
-
-       if (status == 0x0)
-       {
-               become_root(True);
-
-               /* Get what we need from the password database */
-               switch (q_u->switch_level)
-               {
-                       case 0x2:
-                       {
-                               acb_mask = ACB_WSTRUST;
-                               /* Fall through */
-                       }
-                       case 0x1:
-                       case 0x4:
-                       {
-                               get_sampwd_entries(pass, q_u->start_idx,
-                                             &total_entries, &num_sam_entries,
-                                             MAX_SAM_ENTRIES, acb_mask);
-                               break;
-                       }
-                       case 0x3:
-                       case 0x5:
-                       {
-                               enumdomgroups(&sam_grps, &num_sam_entries);
-
-                               if (q_u->start_idx < num_sam_entries) {
-                                       grps = sam_grps + q_u->start_idx;
-                                       num_sam_entries -= q_u->start_idx;
-                               } else {
-                                       num_sam_entries = 0;
-                               }
-                               break;
-                       }
-               }
-
-               unbecome_root(True);
-
-               num_entries = num_sam_entries;
-
-               if (num_entries > q_u->max_entries)
-               {
-                       num_entries = q_u->max_entries;
-               }
-
-               if (num_entries > MAX_SAM_ENTRIES)
-               {
-                       num_entries = MAX_SAM_ENTRIES;
-                       DEBUG(5,("limiting number of entries to %d\n", 
-                                num_entries));
-               }
-
-               data_size = q_u->max_size;
-
-               /* Now create reply structure */
-               switch (q_u->switch_level)
-               {
-                       case 0x1:
-                       {
-                               ctr.sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
-                               make_sam_dispinfo_1(ctr.sam.info1,
-                                                   &num_entries, &data_size,
-                                                   q_u->start_idx, pass);
-                               break;
-                       }
-                       case 0x2:
-                       {
-                               ctr.sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
-                               make_sam_dispinfo_2(ctr.sam.info2,
-                                                   &num_entries, &data_size,
-                                                   q_u->start_idx, pass);
-                               break;
-                       }
-                       case 0x3:
-                       {
-                               ctr.sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
-                               make_sam_dispinfo_3(ctr.sam.info3,
-                                                   &num_entries, &data_size,
-                                                   q_u->start_idx, grps);
-                               break;
-                       }
-                       case 0x4:
-                       {
-                               ctr.sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
-                               make_sam_dispinfo_4(ctr.sam.info4,
-                                                   &num_entries, &data_size,
-                                                   q_u->start_idx, pass);
-                               break;
-                       }
-                       case 0x5:
-                       {
-                               ctr.sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
-                               make_sam_dispinfo_5(ctr.sam.info5,
-                                                   &num_entries, &data_size,
-                                                   q_u->start_idx, grps);
-                               break;
-                       }
-                       default:
-                       {
-                               ctr.sam.info = NULL;
-                               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-                               break;
-                       }
-               }
-       }
-
-       if ((status == 0) && (num_entries < num_sam_entries))
-       {
-               status = STATUS_MORE_ENTRIES;
-       }
-
-       make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
-                                  q_u->switch_level, &ctr, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_dispinfo("", &r_e, rdata, 0);
-
-       /* free malloc'd areas */
-       if (sam_grps != NULL)
-       {
-               free(sam_grps);
-       }
-
-       if (ctr.sam.info != NULL)
-       {
-               free(ctr.sam.info);
-       }
-
-       DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_query_dispinfo
- ********************************************************************/
-static void api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_DISPINFO q_e;
-
-       samr_io_q_query_dispinfo("", &q_e, data, 0);
-       samr_reply_query_dispinfo(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_delete_dom_group
- ********************************************************************/
-static void samr_reply_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_u,
-                               prs_struct *rdata)
-{
-       uint32 status = 0;
-
-       DOM_SID group_sid;
-       uint32 group_rid;
-       fstring group_sid_str;
-
-       SAMR_R_DELETE_DOM_GROUP r_u;
-
-       DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(group_sid_str, &group_sid     );
-               sid_split_rid(&group_sid, &group_rid);
-       }
-
-       if (status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", group_sid_str));
-
-               if (sid_equal(&group_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
-
-                       become_root(True);
-                       status = del_group_entry(group_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
-               }
-       }
-
-       make_samr_r_delete_dom_group(&r_u, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_delete_dom_group("", &r_u, rdata, 0);
-}
-
-/*******************************************************************
- api_samr_delete_dom_group
- ********************************************************************/
-static void api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_DELETE_DOM_GROUP q_u;
-       samr_io_q_delete_dom_group("", &q_u, data, 0);
-       samr_reply_delete_dom_group(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_groupmem
- ********************************************************************/
-static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
-                               prs_struct *rdata)
-{
-       uint32 status = 0;
-
-       DOMAIN_GRP_MEMBER *mem_grp = NULL;
-       uint32 *rid = NULL;
-       uint32 *attr = NULL;
-       int num_rids = 0;
-       DOM_SID group_sid;
-       uint32 group_rid;
-       fstring group_sid_str;
-
-       SAMR_R_QUERY_GROUPMEM r_u;
-
-       DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(group_sid_str, &group_sid     );
-               sid_split_rid(&group_sid, &group_rid);
-       }
-
-       if (status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", group_sid_str));
-
-               if (sid_equal(&group_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
-
-                       become_root(True);
-                       status = getgrouprid(group_rid, &mem_grp, &num_rids) != NULL ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
-               }
-       }
-
-       if (status == 0x0 && num_rids > 0)
-       {
-               rid  = malloc(num_rids * sizeof(uint32));
-               attr = malloc(num_rids * sizeof(uint32));
-               if (mem_grp != NULL && rid != NULL && attr != NULL)
-               {
-                       int i;
-                       for (i = 0; i < num_rids; i++)
-                       {
-                               rid [i] = mem_grp[i].rid;
-                               attr[i] = mem_grp[i].attr;
-                       }
-                       free(mem_grp);
-               }
-       }
-
-       make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_groupmem("", &r_u, rdata, 0);
-
-       if (rid != NULL)
-       {
-               free(rid);
-       }
-
-       if (attr != NULL)
-       {
-               free(attr);
-       }
-
-       DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_groupmem
- ********************************************************************/
-static void api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_GROUPMEM q_u;
-       samr_io_q_query_groupmem("", &q_u, data, 0);
-       samr_reply_query_groupmem(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_groupinfo
- ********************************************************************/
-static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_QUERY_GROUPINFO r_e;
-       GROUP_INFO_CTR ctr;
-       uint32 status = 0x0;
-
-       r_e.ptr = 0;
-
-       /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
-       {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       DEBUG(5,("samr_reply_query_groupinfo: %d\n", __LINE__));
-
-       if (status == 0x0)
-       {
-               if (q_u->switch_level == 1)
-               {
-                       r_e.ptr = 1;
-                       ctr.switch_value1 = 1;
-                       make_samr_group_info1(&ctr.group.info1,
-                                             "fake account name",
-                                             "fake account description", 2);
-               }
-               else if (q_u->switch_level == 4)
-               {
-                       r_e.ptr = 1;
-                       ctr.switch_value1 = 4;
-                       make_samr_group_info4(&ctr.group.info4,
-                                            "fake account description");
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-               }
-       }
-
-       make_samr_r_query_groupinfo(&r_e, status == 0 ? &ctr : NULL, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_groupinfo("", &r_e, rdata, 0);
-
-       DEBUG(5,("samr_query_groupinfo: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_groupinfo
- ********************************************************************/
-static void api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_GROUPINFO q_e;
-       samr_io_q_query_groupinfo("", &q_e, data, 0);
-       samr_reply_query_groupinfo(&q_e, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_aliasinfo
- ********************************************************************/
-static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_QUERY_ALIASINFO r_e;
-       ALIAS_INFO_CTR ctr;
-       uint32 status = 0x0;
-
-       r_e.ptr = 0;
-
-       /* find the policy handle.  open a policy on it. */
-       if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
-       {
-               r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
-
-       if (status == 0x0)
-       {
-               if (q_u->switch_level == 3)
-               {
-                       r_e.ptr = 1;
-                       ctr.switch_value1 = 3;
-                       make_samr_alias_info3(&ctr.alias.info3, "<fake account description>");
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-               }
-       }
-
-       make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
-
-       DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_aliasinfo
- ********************************************************************/
-static void api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_ALIASINFO q_e;
-       samr_io_q_query_aliasinfo("", &q_e, data, 0);
-       samr_reply_query_aliasinfo(&q_e, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_useraliases
- ********************************************************************/
-static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
-                               prs_struct *rdata)
-{
-       uint32 status = 0;
-
-       LOCAL_GRP *mem_grp = NULL;
-       uint32 *rid = NULL;
-       int num_rids = 0;
-       struct sam_passwd *sam_pass;
-       DOM_SID usr_sid;
-       DOM_SID dom_sid;
-       uint32 user_rid;
-       fstring sam_sid_str;
-       fstring dom_sid_str;
-       fstring usr_sid_str;
-
-       SAMR_R_QUERY_USERALIASES r_u;
-       ZERO_STRUCT(r_u);
-
-       DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(dom_sid_str, &dom_sid       );
-               sid_to_string(sam_sid_str, &global_sam_sid);
-       }
-
-       if (status == 0x0)
-       {
-               usr_sid = q_u->sid[0].sid;
-               sid_split_rid(&usr_sid, &user_rid);
-               sid_to_string(usr_sid_str, &usr_sid);
-
-       }
-
-       if (status == 0x0)
-       {
-               /* find the user account */
-               become_root(True);
-               sam_pass = getsam21pwrid(user_rid);
-               unbecome_root(True);
-
-               if (sam_pass == NULL)
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-                       num_rids = 0;
-               }
-       }
-
-       if (status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", dom_sid_str));
-
-               if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
-               {
-                       DEBUG(10,("lookup on S-1-5-20\n"));
-
-                       become_root(True);
-                       getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
-                       unbecome_root(True);
-               }
-               else if (sid_equal(&dom_sid, &usr_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
-
-                       become_root(True);
-                       getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-               }
-       }
-
-       if (status == 0x0 && num_rids > 0)
-       {
-               rid = malloc(num_rids * sizeof(uint32));
-               if (mem_grp != NULL && rid != NULL)
-               {
-                       int i;
-                       for (i = 0; i < num_rids; i++)
-                       {
-                               rid[i] = mem_grp[i].rid;
-                       }
-                       free(mem_grp);
-               }
-       }
-
-       make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_useraliases("", &r_u, rdata, 0);
-
-       if (rid != NULL)
-       {
-               free(rid);
-       }
-
-       DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_useraliases
- ********************************************************************/
-static void api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_USERALIASES q_u;
-       ZERO_STRUCT(q_u);
-       samr_io_q_query_useraliases("", &q_u, data, 0);
-       samr_reply_query_useraliases(&q_u, rdata);
-       samr_free_q_query_useraliases(&q_u);
-}
-
-/*******************************************************************
- samr_reply_delete_dom_alias
- ********************************************************************/
-static void samr_reply_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u,
-                               prs_struct *rdata)
-{
-       uint32 status = 0;
-
-       DOM_SID alias_sid;
-       uint32 alias_rid;
-       fstring alias_sid_str;
-
-       SAMR_R_DELETE_DOM_ALIAS r_u;
-
-       DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(alias_sid_str, &alias_sid     );
-               sid_split_rid(&alias_sid, &alias_rid);
-       }
-
-       if (status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", alias_sid_str));
-
-               if (sid_equal(&alias_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
-
-                       become_root(True);
-                       status = del_alias_entry(alias_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_ALIAS);
-                       unbecome_root(True);
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
-               }
-       }
-
-       make_samr_r_delete_dom_alias(&r_u, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
-}
-
-/*******************************************************************
- api_samr_delete_dom_alias
- ********************************************************************/
-static void api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_DELETE_DOM_ALIAS q_u;
-       samr_io_q_delete_dom_alias("", &q_u, data, 0);
-       samr_reply_delete_dom_alias(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_aliasmem
- ********************************************************************/
-static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
-                               prs_struct *rdata)
-{
-       uint32 status = 0;
-
-       LOCAL_GRP_MEMBER *mem_grp = NULL;
-       DOM_SID2 *sid = NULL;
-       int num_sids = 0;
-       DOM_SID alias_sid;
-       uint32 alias_rid;
-       fstring alias_sid_str;
-
-       SAMR_R_QUERY_ALIASMEM r_u;
-
-       DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-       else
-       {
-               sid_to_string(alias_sid_str, &alias_sid     );
-               sid_split_rid(&alias_sid, &alias_rid);
-       }
-
-       if (status == 0x0)
-       {
-               DEBUG(10,("sid is %s\n", alias_sid_str));
-
-               if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
-               {
-                       DEBUG(10,("lookup on S-1-5-20\n"));
-
-                       become_root(True);
-                       status = getbuiltinrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
-                       unbecome_root(True);
-               }
-               else if (sid_equal(&alias_sid, &global_sam_sid))
-               {
-                       DEBUG(10,("lookup on Domain SID\n"));
-
-                       become_root(True);
-                       status = getaliasrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
-                       unbecome_root(True);
-               }
-               else
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
-               }
-       }
-
-       if (status == 0x0 && num_sids > 0)
-       {
-               sid = malloc(num_sids * sizeof(DOM_SID));
-               if (mem_grp != NULL && sid != NULL)
-               {
-                       int i;
-                       for (i = 0; i < num_sids; i++)
-                       {
-                               make_dom_sid2(&sid[i], &mem_grp[i].sid);
-                       }
-                       free(mem_grp);
-               }
-       }
-
-       make_samr_r_query_aliasmem(&r_u, num_sids, sid, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_query_aliasmem("", &r_u, rdata, 0);
-
-       if (sid != NULL)
-       {
-               free(sid);
-       }
-
-       DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_aliasmem
- ********************************************************************/
-static void api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_ALIASMEM q_u;
-       samr_io_q_query_aliasmem("", &q_u, data, 0);
-       samr_reply_query_aliasmem(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_lookup_names
- ********************************************************************/
-static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
-                               prs_struct *rdata)
-{
-       uint32 rid [MAX_SAM_ENTRIES];
-       uint8  type[MAX_SAM_ENTRIES];
-       uint32 status     = 0;
-       int i;
-       int num_rids = q_u->num_names1;
-       DOM_SID pol_sid;
-
-       SAMR_R_LOOKUP_NAMES r_u;
-
-       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
-
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-
-       if (num_rids > MAX_SAM_ENTRIES)
-       {
-               num_rids = MAX_SAM_ENTRIES;
-               DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
-       }
-
-       SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
-
-       for (i = 0; i < num_rids && status == 0; i++)
-       {
-               DOM_SID sid;
-               fstring name;
-               unistr2_to_ascii(name, &q_u->uni_name[i], sizeof(name)-1);
-
-               status = lookup_name(name, &sid, &(type[i]));
-               if (status == 0x0)
-               {
-                       sid_split_rid(&sid, &rid[i]);
-               }
-               else
-               {
-                       type[i] = SID_NAME_UNKNOWN;
-                       rid [i] = 0xffffffff;
-               }
-               if (!sid_equal(&pol_sid, &sid))
-               {
-                       rid [i] = 0xffffffff;
-                       type[i] = SID_NAME_UNKNOWN;
-               }
-       }
-
-       make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_lookup_names("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_lookup_names
- ********************************************************************/
-static void api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_LOOKUP_NAMES q_u;
-       samr_io_q_lookup_names("", &q_u, data, 0);
-       samr_reply_lookup_names(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_chgpasswd_user
- ********************************************************************/
-static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_CHGPASSWD_USER r_u;
-       uint32 status = 0x0;
-       fstring user_name;
-       fstring wks;
-
-       unistr2_to_ascii(user_name, &q_u->uni_user_name, sizeof(user_name)-1);
-       unistr2_to_ascii(wks, &q_u->uni_dest_host, sizeof(wks)-1);
-
-       DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
-
-       if (!pass_oem_change(user_name,
-                            q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
-                            q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
-       {
-               status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
-       }
-
-       make_samr_r_chgpasswd_user(&r_u, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_chgpasswd_user
- ********************************************************************/
-static void api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_CHGPASSWD_USER q_u;
-       samr_io_q_chgpasswd_user("", &q_u, data, 0);
-       samr_reply_chgpasswd_user(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_unknown_38
- ********************************************************************/
-static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_UNKNOWN_38 r_u;
-
-       DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
-
-       make_samr_r_unknown_38(&r_u);
-
-       /* store the response in the SMB stream */
-       samr_io_r_unknown_38("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_unknown_38
- ********************************************************************/
-static void api_samr_unknown_38( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_UNKNOWN_38 q_u;
-       samr_io_q_unknown_38("", &q_u, data, 0);
-       samr_reply_unknown_38(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_lookup_rids
- ********************************************************************/
-static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
-                               prs_struct *rdata)
-{
-       fstring group_names[MAX_SAM_ENTRIES];
-       uint8   group_attrs[MAX_SAM_ENTRIES];
-       uint32 status     = 0;
-       int num_rids = q_u->num_rids1;
-       DOM_SID pol_sid;
-
-       SAMR_R_LOOKUP_RIDS r_u;
-       ZERO_STRUCT(r_u);
-
-       DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-
-       if (status == 0x0)
-       {
-               int i;
-               if (num_rids > MAX_SAM_ENTRIES)
-               {
-                       num_rids = MAX_SAM_ENTRIES;
-                       DEBUG(5,("samr_lookup_rids: truncating entries to %d\n", num_rids));
-               }
-
-               for (i = 0; i < num_rids && status == 0; i++)
-               {
-                       DOM_SID sid;
-                       sid_copy(&sid, &pol_sid);
-                       sid_append_rid(&sid, q_u->rid[i]);
-                       lookup_sid(&sid, group_names[i], &group_attrs[i]);
-               }
-       }
-
-       make_samr_r_lookup_rids(&r_u, num_rids, group_names, group_attrs, status);
-
-       /* store the response in the SMB stream */
-       samr_io_r_lookup_rids("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_lookup_rids
- ********************************************************************/
-static void api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_LOOKUP_RIDS q_u;
-       ZERO_STRUCT(q_u);
-       samr_io_q_lookup_rids("", &q_u, data, 0);
-       samr_reply_lookup_rids(&q_u, rdata);
-       samr_free_q_lookup_rids(&q_u);
-}
-
-
-/*******************************************************************
- samr_reply_open_user
- ********************************************************************/
-static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
-                               prs_struct *rdata,
-                               int status)
-{
-       SAMR_R_OPEN_USER r_u;
-       struct sam_passwd *sam_pass;
-       BOOL pol_open = False;
-
-       /* set up the SAMR open_user response */
-       bzero(r_u.user_pol.data, POL_HND_SIZE);
-
-       r_u.status = 0x0;
-
-       /* find the policy handle.  open a policy on it. */
-       if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
+       for (i = 0; i < num_rids; i++) {
+               fstring name;
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.user_pol))))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
+               status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
 
-       become_root(True);
-       sam_pass = getsam21pwrid(q_u->user_rid);
-       unbecome_root(True);
+               rid [i] = 0xffffffff;
+               type[i] = SID_NAME_UNKNOWN;
 
-       /* check that the RID exists in our domain. */
-       if (r_u.status == 0x0 && sam_pass == NULL)
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-       }
+               fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
+                               q_u->uni_name[i].uni_str_len));
 
-       /* associate the RID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
+               if(sid_equal(&pol_sid, &global_sam_sid)) {
+                       DOM_SID sid;
 
-       if (r_u.status != 0 && pol_open)
-       {
-               close_policy_hnd(&(r_u.user_pol));
+                       if(lookup_local_name(global_myname, name, &sid, &type[i])) {
+                               sid_split_rid( &sid, &rid[i]);
+                               status = 0;
+                       }
+               }
        }
 
-       DEBUG(5,("samr_open_user: %d\n", __LINE__));
+       init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_open_user("", &r_u, rdata, 0);
+       if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+               DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+               return False;
+       }
 
-       DEBUG(5,("samr_open_user: %d\n", __LINE__));
+       DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
 
+       return True;
 }
 
 /*******************************************************************
- api_samr_open_user
+ api_samr_lookup_names
  ********************************************************************/
-static void api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_OPEN_USER q_u;
-       samr_io_q_open_user("", &q_u, data, 0);
-       samr_reply_open_user(&q_u, rdata, 0x0);
-}
-
 
-/*************************************************************************
- get_user_info_10
- *************************************************************************/
-static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
+static BOOL api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       struct sam_passwd *sam_pass;
+       SAMR_Q_LOOKUP_NAMES q_u;
 
-       become_root(True);
-       sam_pass = getsam21pwrid(user_rid);
-       unbecome_root(True);
+       memset(&q_u, '\0', sizeof(q_u));
 
-       if (sam_pass == NULL)
-       {
-               DEBUG(4,("User 0x%x not found\n", user_rid));
+       /* grab the samr lookup names */
+       if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
+               DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
                return False;
        }
 
-       DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
-
-       make_sam_user_info10(id10, sam_pass->acct_ctrl); 
-
-       return True;
-}
-
-/*************************************************************************
- get_user_info_21
- *************************************************************************/
-static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
-{
-       struct sam_passwd *sam_pass;
-       LOGON_HRS hrs;
-       int i;
-
-       become_root(True);
-       sam_pass = getsam21pwrid(user_rid);
-       unbecome_root(True);
-
-       if (sam_pass == NULL)
-       {
-               DEBUG(4,("User 0x%x not found\n", user_rid));
+       /* construct reply.  always indicate success */
+       if(!samr_reply_lookup_names(&q_u, rdata))
                return False;
-       }
-
-       DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
-
-       /* create a LOGON_HRS structure */
-       hrs.len = sam_pass->hours_len;
-       SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
-       for (i = 0; i < hrs.len; i++)
-       {
-               hrs.hours[i] = sam_pass->hours[i];
-       }
-
-       make_sam_user_info21(id21,
-
-                          &sam_pass->logon_time,
-                          &sam_pass->logoff_time,
-                          &sam_pass->kickoff_time,
-                          &sam_pass->pass_last_set_time,
-                          &sam_pass->pass_can_change_time,
-                          &sam_pass->pass_must_change_time,
-
-                          sam_pass->nt_name, /* user_name */
-                          sam_pass->full_name, /* full_name */
-                          sam_pass->home_dir, /* home_dir */
-                          sam_pass->dir_drive, /* dir_drive */
-                          sam_pass->logon_script, /* logon_script */
-                          sam_pass->profile_path, /* profile_path */
-                          sam_pass->acct_desc, /* description */
-                          sam_pass->workstations, /* workstations user can log in from */
-                          sam_pass->unknown_str, /* don't know, yet */
-                          sam_pass->munged_dial, /* dialin info.  contains dialin path and tel no */
-
-                          sam_pass->user_rid, /* RID user_id */
-                          sam_pass->group_rid, /* RID group_id */
-                          sam_pass->acct_ctrl,
-
-                          sam_pass->unknown_3, /* unknown_3 */
-                          sam_pass->logon_divs, /* divisions per week */
-                          &hrs, /* logon hours */
-                          sam_pass->unknown_5,
-                          sam_pass->unknown_6);
 
        return True;
 }
 
 /*******************************************************************
- samr_reply_query_userinfo
+ samr_reply_chgpasswd_user
  ********************************************************************/
-static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+
+static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_QUERY_USERINFO r_u;
-#if 0
-       SAM_USER_INFO_11 id11;
-#endif
-       SAM_USER_INFO_10 id10;
-       SAM_USER_INFO_21 id21;
-       void *info = NULL;
-
+       SAMR_R_CHGPASSWD_USER r_u;
        uint32 status = 0x0;
-       uint32 rid = 0x0;
-
-       DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
-
-       /* search for the handle */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
+       fstring user_name;
+       fstring wks;
 
-       /* find the user's rid */
-       if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
+       fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
+       fstrcpy(wks      , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
 
-       DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
+       DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
 
-       /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
-       if (status == 0x0)
+       if (!pass_oem_change(user_name,
+                            q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
+                            q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
        {
-               switch (q_u->switch_value)
-               {
-                       case 0x10:
-                       {
-                               info = (void*)&id10;
-                               status = get_user_info_10(&id10, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
-                               break;
-                       }
-#if 0
-/* whoops - got this wrong.  i think.  or don't understand what's happening. */
-                       case 0x11:
-                       {
-                               NTTIME expire;
-                               info = (void*)&id11;
-                               
-                               expire.low  = 0xffffffff;
-                               expire.high = 0x7fffffff;
-
-                               make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
-
-                               break;
-                       }
-#endif
-                       case 21:
-                       {
-                               info = (void*)&id21;
-                               status = get_user_info_21(&id21, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
-                               break;
-                       }
-
-                       default:
-                       {
-                               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-
-                               break;
-                       }
-               }
+               status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
        }
 
-       make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
+       init_samr_r_chgpasswd_user(&r_u, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_query_userinfo("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- set_user_info_24
- ********************************************************************/
-static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
-{
-       struct sam_passwd *pwd = getsam21pwrid(rid);
-       struct sam_passwd new_pwd;
-       static uchar nt_hash[16];
-       static uchar lm_hash[16];
-       UNISTR2 new_pw;
-       uint32 len;
-
-       if (pwd == NULL)
-       {
+       if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
+               DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
                return False;
        }
 
-       pwdb_init_sam(&new_pwd);
-       copy_sam_passwd(&new_pwd, pwd);
-
-       if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
-       {
-               return False;
-       }
-
-       new_pw.uni_max_len = len / 2;
-       new_pw.uni_str_len = len / 2;
-
-       nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
-
-       new_pwd.smb_passwd    = lm_hash;
-       new_pwd.smb_nt_passwd = nt_hash;
-
-       return mod_sam21pwd_entry(&new_pwd, True);
+       DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
+       return True;
 }
 
 /*******************************************************************
- set_user_info_23
+ api_samr_chgpasswd_user
  ********************************************************************/
-static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
+
+static BOOL api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       struct sam_passwd *pwd = getsam21pwrid(rid);
-       struct sam_passwd new_pwd;
-       static uchar nt_hash[16];
-       static uchar lm_hash[16];
-       UNISTR2 new_pw;
-       uint32 len;
-
-       if (id23 == NULL)
-       {
-               DEBUG(5, ("set_user_info_23: NULL id23\n"));
-               return False;
-       }
-       if (pwd == NULL)
-       {
+       SAMR_Q_CHGPASSWD_USER q_u;
+
+       /* unknown 38 command */
+       if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
+               DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
                return False;
        }
 
-       pwdb_init_sam(&new_pwd);
-       copy_sam_passwd(&new_pwd, pwd);
-       copy_id23_to_sam_passwd(&new_pwd, id23);
-
-       if (!decode_pw_buffer(id23->pass, (char*)new_pw.buffer, 256, &len))
-       {
+       /* construct reply. */
+       if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
+               DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
                return False;
        }
 
-       new_pw.uni_max_len = len / 2;
-       new_pw.uni_str_len = len / 2;
-
-       nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
-
-       new_pwd.smb_passwd    = lm_hash;
-       new_pwd.smb_nt_passwd = nt_hash;
-
-       return mod_sam21pwd_entry(&new_pwd, True);
+       return True;
 }
 
+
 /*******************************************************************
- set_user_info_16
+ samr_reply_unknown_38
  ********************************************************************/
-static BOOL set_user_info_16(SAM_USER_INFO_16 *id16, uint32 rid)
+static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
+                               prs_struct *rdata)
 {
-       struct sam_passwd *pwd = getsam21pwrid(rid);
-       struct sam_passwd new_pwd;
+       SAMR_R_UNKNOWN_38 r_u;
 
-       if (id16 == NULL)
-       {
-               DEBUG(5, ("set_user_info_16: NULL id16\n"));
-               return False;
-       }
-       if (pwd == NULL)
-       {
-               return False;
-       }
+       DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
 
-       copy_sam_passwd(&new_pwd, pwd);
+       init_samr_r_unknown_38(&r_u);
 
-       new_pwd.acct_ctrl = id16->acb_info;
+       /* store the response in the SMB stream */
+       samr_io_r_unknown_38("", &r_u, rdata, 0);
 
-       return mod_sam21pwd_entry(&new_pwd, True);
+       DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
 }
 
 /*******************************************************************
- api_samr_query_userinfo
+ api_samr_unknown_38
  ********************************************************************/
-static void api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_QUERY_USERINFO q_u;
-       samr_io_q_query_userinfo("", &q_u, data, 0);
-       samr_reply_query_userinfo(&q_u, rdata);
+       SAMR_Q_UNKNOWN_38 q_u;
+
+       /* unknown 38 command */
+       samr_io_q_unknown_38("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
+       samr_reply_unknown_38(&q_u, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
- samr_reply_set_userinfo2
+ samr_reply_unknown_12
  ********************************************************************/
-static void samr_reply_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
-                               prs_struct *rdata, uchar user_sess_key[16])
+static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+                               prs_struct *rdata)
 {
-       SAMR_R_SET_USERINFO2 r_u;
+       fstring group_names[MAX_SAM_ENTRIES];
+       uint32  group_attrs[MAX_SAM_ENTRIES];
+       uint32 status     = 0;
+       int num_gids = q_u->num_gids1;
 
-       uint32 status = 0x0;
-       uint32 rid = 0x0;
+       SAMR_R_UNKNOWN_12 r_u;
 
-       DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
+       DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
 
-       /* search for the handle */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       /* find the policy handle.  open a policy on it. */
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       /* find the user's rid */
-       if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-
-       DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
-
-       /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
-       if (status == 0x0 && q_u->info.id == NULL)
-       {
-               DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
-               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-       }
-
        if (status == 0x0)
        {
-               switch (q_u->switch_value)
+               int i;
+               if (num_gids > MAX_SAM_ENTRIES)
                {
-                       case 16:
-                       {
-                               SAM_USER_INFO_16 *id16 = q_u->info.id16;
-                               status = set_user_info_16(id16, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                               break;
-                       }
-                       default:
-                       {
-                               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+                       num_gids = MAX_SAM_ENTRIES;
+                       DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
+               }
 
-                               break;
-                       }
+               for (i = 0; i < num_gids && status == 0; i++)
+               {
+                       fstrcpy(group_names[i], "dummy group");
+                       group_attrs[i] = 0x2;
                }
        }
 
-       make_samr_r_set_userinfo2(&r_u, status);
+       init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_set_userinfo2("", &r_u, rdata, 0);
+       samr_io_r_unknown_12("", &r_u, rdata, 0);
 
-       DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
+       DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
 
 }
 
 /*******************************************************************
- api_samr_set_userinfo2
+ api_samr_unknown_12
  ********************************************************************/
-static void api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_SET_USERINFO2 q_u;
-       ZERO_STRUCT(q_u);
+       SAMR_Q_UNKNOWN_12 q_u;
 
-       samr_io_q_set_userinfo2("", &q_u, data, 0);
-       samr_reply_set_userinfo2(&q_u, rdata, p->user_sess_key);
+       /* grab the samr lookup names */
+       samr_io_q_unknown_12("", &q_u, data, 0);
 
-       if (q_u.info.id != NULL)
-       {
-               free(q_u.info.id);
-       }
+       /* construct reply.  always indicate success */
+       samr_reply_unknown_12(&q_u, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
- samr_reply_set_userinfo
+ samr_reply_open_user
  ********************************************************************/
-static void samr_reply_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
-                               prs_struct *rdata, uchar user_sess_key[16])
+static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
+                               prs_struct *rdata,
+                               int status)
 {
-       SAMR_R_SET_USERINFO r_u;
+       SAMR_R_OPEN_USER r_u;
+       struct sam_passwd *sam_pass;
+       BOOL pol_open = False;
 
-       uint32 status = 0x0;
-       uint32 rid = 0x0;
+       /* set up the SAMR open_user response */
+       memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
 
-       DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
+       r_u.status = 0x0;
 
-       /* search for the handle */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       /* find the policy handle.  open a policy on it. */
+       if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
        {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       /* find the user's rid */
-       if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+       /* get a (unique) handle.  open a policy on it. */
+       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
        {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
+       become_root(True);
+       sam_pass = getsam21pwrid(q_u->user_rid);
+       unbecome_root(True);
 
-       /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
-       if (status == 0x0 && q_u->info.id == NULL)
+       /* check that the RID exists in our domain. */
+       if (r_u.status == 0x0 && sam_pass == NULL)
        {
-               DEBUG(5,("samr_reply_set_userinfo: NULL info level\n"));
-               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+               r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
        }
 
-       if (status == 0x0)
+       /* associate the RID with the (unique) handle. */
+       if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
        {
-               switch (q_u->switch_value)
-               {
-                       case 24:
-                       {
-                               SAM_USER_INFO_24 *id24 = q_u->info.id24;
-                               SamOEMhash(id24->pass, user_sess_key, True);
-                               status = set_user_info_24(id24, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                               break;
-                       }
-
-                       case 23:
-                       {
-                               SAM_USER_INFO_23 *id23 = q_u->info.id23;
-                               SamOEMhash(id23->pass, user_sess_key, 1);
-#if DEBUG_PASSWORD
-                               DEBUG(100,("pass buff:\n"));
-                               dump_data(100, id23->pass, sizeof(id23->pass));
-#endif
-                               dbgflush();
-
-                               status = set_user_info_23(id23, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-                               break;
-                       }
-
-                       default:
-                       {
-                               status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+               /* oh, whoops.  don't know what error message to return, here */
+               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
 
-                               break;
-                       }
-               }
+       if (r_u.status != 0 && pol_open)
+       {
+               close_lsa_policy_hnd(&(r_u.user_pol));
        }
 
-       make_samr_r_set_userinfo(&r_u, status);
+       DEBUG(5,("samr_open_user: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_set_userinfo("", &r_u, rdata, 0);
+       samr_io_r_open_user("", &r_u, rdata, 0);
 
-       DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
+       DEBUG(5,("samr_open_user: %d\n", __LINE__));
 
 }
 
 /*******************************************************************
- api_samr_set_userinfo
+ api_samr_open_user
  ********************************************************************/
-static void api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_SET_USERINFO q_u;
-       ZERO_STRUCT(q_u);
+       SAMR_Q_OPEN_USER q_u;
 
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("set user info: sess_key: "));
-       dump_data(100, p->user_sess_key, 16);
-#endif
-       samr_io_q_set_userinfo("", &q_u, data, 0);
-       samr_reply_set_userinfo(&q_u, rdata, p->user_sess_key);
+       /* grab the samr unknown 22 */
+       samr_io_q_open_user("", &q_u, data, 0);
 
-       if (q_u.info.id != NULL)
-       {
-               free(q_u.info.id);
-       }
+       /* construct reply.  always indicate success */
+       samr_reply_open_user(&q_u, rdata, 0x0);
+
+       return True;
 }
 
 
-/*******************************************************************
- samr_reply_query_usergroups
- ********************************************************************/
-static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
-                               prs_struct *rdata)
+/*************************************************************************
+ get_user_info_10
+ *************************************************************************/
+static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
 {
-       SAMR_R_QUERY_USERGROUPS r_u;
-       uint32 status = 0x0;
-
-       struct sam_passwd *sam_pass;
-       DOM_GID *gids = NULL;
-       int num_groups = 0;
-       uint32 rid;
-
-       DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+       struct smb_passwd *smb_pass;
 
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       if (!pdb_rid_is_user(user_rid))
        {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+               DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+               return False;
        }
 
-       /* find the user's rid */
-       if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
+       become_root(True);
+       smb_pass = getsmbpwrid(user_rid);
+       unbecome_root(True);
 
-       if (status == 0x0)
+       if (smb_pass == NULL)
        {
-               become_root(True);
-               sam_pass = getsam21pwrid(rid);
-               unbecome_root(True);
-
-               if (sam_pass == NULL)
-               {
-                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-               }
+               DEBUG(4,("User 0x%x not found\n", user_rid));
+               return False;
        }
 
-       if (status == 0x0)
-       {
-               DOMAIN_GRP *mem_grp = NULL;
-
-               become_root(True);
-               getusergroupsntnam(sam_pass->nt_name, &mem_grp, &num_groups);
-               unbecome_root(True);
-
-                gids = NULL;
-               num_groups = make_dom_gids(mem_grp, num_groups, &gids);
+       DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
 
-               if (mem_grp != NULL)
-               {
-                       free(mem_grp);
-               }
-       }
+       init_sam_user_info10(id10, smb_pass->acct_ctrl); 
 
-       /* construct the response.  lkclXXXX: gids are not copied! */
-       make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
+       return True;
+}
 
-       /* store the response in the SMB stream */
-       samr_io_r_query_usergroups("", &r_u, rdata, 0);
+/*************************************************************************
+ get_user_info_21
+ *************************************************************************/
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
+{
+       NTTIME dummy_time;
+       struct sam_passwd *sam_pass;
+       LOGON_HRS hrs;
+       int i;
 
-       if (gids)
+       if (!pdb_rid_is_user(user_rid))
        {
-               free((char *)gids);
+               DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+               return False;
        }
 
-       DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+       become_root(True);
+       sam_pass = getsam21pwrid(user_rid);
+       unbecome_root(True);
 
-}
+       if (sam_pass == NULL)
+       {
+               DEBUG(4,("User 0x%x not found\n", user_rid));
+               return False;
+       }
 
-/*******************************************************************
- api_samr_query_usergroups
- ********************************************************************/
-static void api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_QUERY_USERGROUPS q_u;
-       samr_io_q_query_usergroups("", &q_u, data, 0);
-       samr_reply_query_usergroups(&q_u, rdata);
-}
+       DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
 
+       dummy_time.low  = 0xffffffff;
+       dummy_time.high = 0x7fffffff;
 
-/*******************************************************************
- opens a samr alias by rid, returns a policy handle.
- ********************************************************************/
-static uint32 open_samr_alias(DOM_SID *sid, POLICY_HND *alias_pol,
-                               uint32 alias_rid)
-{
-       BOOL pol_open = False;
-       uint32 status = 0x0;
+       DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
 
-       /* get a (unique) handle.  open a policy on it. */
-       if (status == 0x0 && !(pol_open = open_policy_hnd(alias_pol)))
+       /* create a LOGON_HRS structure */
+       hrs.len = sam_pass->hours_len;
+       SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
+       for (i = 0; i < hrs.len; i++)
        {
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               hrs.hours[i] = sam_pass->hours[i];
        }
 
-       DEBUG(0,("TODO: verify that the alias rid exists\n"));
+       init_sam_user_info21(id21,
 
-       /* associate a RID with the (unique) handle. */
-       if (status == 0x0 && !set_policy_samr_rid(alias_pol, alias_rid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
+                          &dummy_time, /* logon_time */
+                          &dummy_time, /* logoff_time */
+                          &dummy_time, /* kickoff_time */
+                          &dummy_time, /* pass_last_set_time */
+                          &dummy_time, /* pass_can_change_time */
+                          &dummy_time, /* pass_must_change_time */
 
-       sid_append_rid(sid, alias_rid);
+                          sam_pass->smb_name, /* user_name */
+                          sam_pass->full_name, /* full_name */
+                          sam_pass->home_dir, /* home_dir */
+                          sam_pass->dir_drive, /* dir_drive */
+                          sam_pass->logon_script, /* logon_script */
+                          sam_pass->profile_path, /* profile_path */
+                          sam_pass->acct_desc, /* description */
+                          sam_pass->workstations, /* workstations user can log in from */
+                          sam_pass->unknown_str, /* don't know, yet */
+                          sam_pass->munged_dial, /* dialin info.  contains dialin path and tel no */
 
-       /* associate an alias SID with the (unique) handle. */
-       if (status == 0x0 && !set_policy_samr_sid(alias_pol, sid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
+                          sam_pass->user_rid, /* RID user_id */
+                          sam_pass->group_rid, /* RID group_id */
+                      sam_pass->acct_ctrl,
 
-       if (status != 0 && pol_open)
-       {
-               close_policy_hnd(alias_pol);
-       }
+                  sam_pass->unknown_3, /* unknown_3 */
+                      sam_pass->logon_divs, /* divisions per week */
+                          &hrs, /* logon hours */
+                      sam_pass->unknown_5,
+                      sam_pass->unknown_6);
 
-       return status;
+       return True;
 }
 
 /*******************************************************************
- samr_reply_create_dom_alias
+ samr_reply_query_userinfo
  ********************************************************************/
-static void samr_reply_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u,
+static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_CREATE_DOM_ALIAS r_u;
-       DOM_SID dom_sid;
-       LOCAL_GRP grp;
-       POLICY_HND alias_pol;
-       uint32 status = 0x0;
+       SAMR_R_QUERY_USERINFO r_u;
+#if 0
+       SAM_USER_INFO_11 id11;
+#endif
+       SAM_USER_INFO_10 id10;
+       SAM_USER_INFO_21 id21;
+       void *info = NULL;
 
-       bzero(&alias_pol, sizeof(alias_pol));
+       uint32 status = 0x0;
+       uint32 rid = 0x0;
 
-       DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
+       DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
 
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->dom_pol)) == -1))
+       /* search for the handle */
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+               status = NT_STATUS_INVALID_HANDLE;
        }
 
-       /* find the domain sid */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &dom_sid))
+       /* find the user's rid */
+       if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
        {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
-       if (!sid_equal(&dom_sid, &global_sam_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-       }
+       DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
 
+       /* ok!  user info levels (there are lots: see MSDEV help), off we go... */
        if (status == 0x0)
        {
-               unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
-               fstrcpy(grp.comment, "");
-               grp.rid = 0xffffffff;
+               switch (q_u->switch_value)
+               {
+                       case 0x10:
+                       {
+                               info = (void*)&id10;
+                               status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+                               break;
+                       }
+#if 0
+/* whoops - got this wrong.  i think.  or don't understand what's happening. */
+                       case 0x11:
+                       {
+                               NTTIME expire;
+                               info = (void*)&id11;
+                               
+                               expire.low  = 0xffffffff;
+                               expire.high = 0x7fffffff;
+
+                               make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
+
+                               break;
+                       }
+#endif
+                       case 21:
+                       {
+                               info = (void*)&id21;
+                               status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+                               break;
+                       }
 
-               become_root(True);
-               status = add_alias_entry(&grp) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
-               unbecome_root(True);
-       }
+                       default:
+                       {
+                               status = NT_STATUS_INVALID_INFO_CLASS;
 
-       if (status == 0x0)
-       {
-               status = open_samr_alias(&dom_sid, &alias_pol, grp.rid);
+                               break;
+                       }
+               }
        }
 
-       /* construct the response. */
-       make_samr_r_create_dom_alias(&r_u, &alias_pol, grp.rid, status);
+       init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_create_dom_alias("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
+       samr_io_r_query_userinfo("", &r_u, rdata, 0);
 
-}
+       DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
 
-/*******************************************************************
- api_samr_create_dom_alias
- ********************************************************************/
-static void api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_CREATE_DOM_ALIAS q_u;
-       samr_io_q_create_dom_alias("", &q_u, data, 0);
-       samr_reply_create_dom_alias(&q_u, rdata);
 }
 
-
 /*******************************************************************
- opens a samr group by rid, returns a policy handle.
+ api_samr_query_userinfo
  ********************************************************************/
-static uint32 open_samr_group(DOM_SID *sid, POLICY_HND *group_pol,
-                               uint32 group_rid)
+static BOOL api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       BOOL pol_open = False;
-       uint32 status = 0x0;
-
-       /* get a (unique) handle.  open a policy on it. */
-       if (status == 0x0 && !(pol_open = open_policy_hnd(group_pol)))
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       DEBUG(0,("TODO: verify that the group rid exists\n"));
-
-       /* associate a RID with the (unique) handle. */
-       if (status == 0x0 && !set_policy_samr_rid(group_pol, group_rid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       sid_append_rid(sid, group_rid);
+       SAMR_Q_QUERY_USERINFO q_u;
 
-       /* associate an group SID with the (unique) handle. */
-       if (status == 0x0 && !set_policy_samr_sid(group_pol, sid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
+       /* grab the samr unknown 24 */
+       samr_io_q_query_userinfo("", &q_u, data, 0);
 
-       if (status != 0 && pol_open)
-       {
-               close_policy_hnd(group_pol);
-       }
+       /* construct reply.  always indicate success */
+       samr_reply_query_userinfo(&q_u, rdata);
 
-       return status;
+       return True;
 }
 
+
 /*******************************************************************
- samr_reply_create_dom_group
+ samr_reply_query_usergroups
  ********************************************************************/
-static void samr_reply_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_u,
+static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
                                prs_struct *rdata)
 {
-       SAMR_R_CREATE_DOM_GROUP r_u;
-       DOM_SID dom_sid;
-       DOMAIN_GRP grp;
-       POLICY_HND group_pol;
+       SAMR_R_QUERY_USERGROUPS r_u;
        uint32 status = 0x0;
 
-       bzero(&group_pol, sizeof(group_pol));
+       struct sam_passwd *sam_pass;
+       DOM_GID *gids = NULL;
+       int num_groups = 0;
+       uint32 rid;
 
-       DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
+       DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
 
        /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+       if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
        {
                status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
        }
 
-       /* find the domain sid */
-       if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-
-       if (!sid_equal(&dom_sid, &global_sam_sid))
+       /* find the user's rid */
+       if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
        {
-               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+               status = NT_STATUS_OBJECT_TYPE_MISMATCH;
        }
 
        if (status == 0x0)
        {
-               unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
-               fstrcpy(grp.comment, "");
-               grp.rid = 0xffffffff;
-               grp.attr = 0x07;
-
                become_root(True);
-               status = add_group_entry(&grp) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
+               sam_pass = getsam21pwrid(rid);
                unbecome_root(True);
+
+               if (sam_pass == NULL)
+               {
+                       status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+               }
        }
 
        if (status == 0x0)
        {
-               status = open_samr_group(&dom_sid, &group_pol, grp.rid);
+               pstring groups;
+               get_domain_user_groups(groups, sam_pass->smb_name);
+                gids = NULL;
+               num_groups = make_dom_gids(groups, &gids);
        }
 
-       /* construct the response. */
-       make_samr_r_create_dom_group(&r_u, &group_pol, grp.rid, status);
+       /* construct the response.  lkclXXXX: gids are not copied! */
+       init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
 
        /* store the response in the SMB stream */
-       samr_io_r_create_dom_group("", &r_u, rdata, 0);
+       samr_io_r_query_usergroups("", &r_u, rdata, 0);
+
+       if (gids)
+       {
+               free((char *)gids);
+       }
 
-       DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
+       DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
 
 }
 
 /*******************************************************************
- api_samr_create_dom_group
+ api_samr_query_usergroups
  ********************************************************************/
-static void api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_CREATE_DOM_GROUP q_u;
-       samr_io_q_create_dom_group("", &q_u, data, 0);
-       samr_reply_create_dom_group(&q_u, rdata);
+       SAMR_Q_QUERY_USERGROUPS q_u;
+       /* grab the samr unknown 32 */
+       samr_io_q_query_usergroups("", &q_u, data, 0);
+
+       /* construct reply. */
+       samr_reply_query_usergroups(&q_u, rdata);
+
+       return True;
 }
 
 
@@ -2664,7 +1386,7 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
        DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
 
        /* find the policy handle.  open a policy on it. */
-       if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
+       if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
        {
                r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
                DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
@@ -2674,38 +1396,10 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
        {
                switch (q_u->switch_value)
                {
-                       case 0x07:
-                       {
-                               switch_value = 0x7;
-                               make_unk_info7(&ctr.info.inf7);
-
-                               break;
-                       }
-                       case 0x06:
-                       {
-                               switch_value = 0x6;
-                               make_unk_info6(&ctr.info.inf6);
-
-                               break;
-                       }
-                       case 0x03:
-                       {
-                               switch_value = 0x3;
-                               make_unk_info3(&ctr.info.inf3);
-
-                               break;
-                       }
                        case 0x02:
                        {
                                switch_value = 0x2;
-                               make_unk_info2(&ctr.info.inf2, global_sam_name, global_myname);
-
-                               break;
-                       }
-                       case 0x01:
-                       {
-                               switch_value = 0x1;
-                               make_unk_info1(&ctr.info.inf1);
+                               init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
 
                                break;
                        }
@@ -2717,7 +1411,7 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
                }
        }
 
-       make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
+       init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
 
        /* store the response in the SMB stream */
        samr_io_r_query_dom_info("", &r_u, rdata, 0);
@@ -2729,123 +1423,96 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
 /*******************************************************************
  api_samr_query_dom_info
  ********************************************************************/
-static void api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_QUERY_DOMAIN_INFO q_e;
+
+       /* grab the samr unknown 8 command */
        samr_io_q_query_dom_info("", &q_e, data, 0);
+
+       /* construct reply. */
        samr_reply_query_dom_info(&q_e, rdata);
+
+       return True;
 }
 
 
 
 /*******************************************************************
- samr_reply_create_user
+ samr_reply_unknown_32
  ********************************************************************/
-static void samr_reply_create_user(SAMR_Q_CREATE_USER *q_u,
-                               prs_struct *rdata)
+static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
+                               prs_struct *rdata,
+                               int status)
 {
-       struct sam_passwd *sam_pass;
-       fstring user_name;
-
-       SAMR_R_CREATE_USER r_u;
-       POLICY_HND pol;
-       uint32 status = 0x0;
-       uint32 user_rid = 0x0;
-       BOOL pol_open = False;
-       uint32 unk_0 = 0x30;
-
-       /* find the machine account: tell the caller if it exists.
-          lkclXXXX i have *no* idea if this is a problem or not
-          or even if you are supposed to construct a different
-          reply if the account already exists...
-        */
-
-       /* find the policy handle.  open a policy on it. */
-       if (status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
-       {
-               status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       /* get a (unique) handle.  open a policy on it. */
-       if (status == 0x0 && !(pol_open = open_policy_hnd(&pol)))
-       {
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       unistr2_to_ascii(user_name, &q_u->uni_name, sizeof(user_name)-1);
-
-       sam_pass = getsam21pwntnam(user_name);
+       int i;
+       SAMR_R_UNKNOWN_32 r_u;
 
-       if (sam_pass != NULL)
-       {
-               /* account exists: say so */
-               status = 0xC0000000 | NT_STATUS_USER_EXISTS;
-       }
-       else
+       /* set up the SAMR unknown_32 response */
+       memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+       if (status == 0)
        {
-               pstring err_str;
-               pstring msg_str;
-
-               if (!local_password_change(user_name, True,
-                         q_u->acb_info | ACB_DISABLED | ACB_PWNOTREQ, 0xffff,
-                         NULL,
-                         err_str, sizeof(err_str),
-                         msg_str, sizeof(msg_str)))
-               {
-                       DEBUG(0,("%s\n", err_str));
-                       status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-               }
-               else
+               for (i = 4; i < POL_HND_SIZE; i++)
                {
-                       sam_pass = getsam21pwntnam(user_name);
-                       if (sam_pass == NULL)
-                       {
-                               /* account doesn't exist: say so */
-                               status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-                       }
-                       else
-                       {
-                               user_rid = sam_pass->user_rid;
-                               unk_0 = 0x000703ff;
-                       }
+                       r_u.pol.data[i] = i+1;
                }
        }
 
-       /* associate the RID with the (unique) handle. */
-       if (status == 0x0 && !set_policy_samr_rid(&pol, user_rid))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       if (status != 0 && pol_open)
-       {
-               close_policy_hnd(&pol);
-       }
-
-       DEBUG(5,("samr_create_user: %d\n", __LINE__));
+       init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
+       r_u.status    = status;
 
-       make_samr_r_create_user(&r_u, &pol, unk_0, user_rid, status);
+       DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
 
        /* store the response in the SMB stream */
-       samr_io_r_create_user("", &r_u, rdata, 0);
+       samr_io_r_unknown_32("", &r_u, rdata, 0);
 
-       DEBUG(5,("samr_create_user: %d\n", __LINE__));
+       DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
 
 }
 
 /*******************************************************************
- api_samr_create_user
+ api_samr_unknown_32
  ********************************************************************/
-static void api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
-       SAMR_Q_CREATE_USER q_u;
+       uint32 status = 0;
+       struct sam_passwd *sam_pass;
+       fstring mach_acct;
+
+       SAMR_Q_UNKNOWN_32 q_u;
 
        /* grab the samr unknown 32 */
-       samr_io_q_create_user("", &q_u, data, 0);
+       samr_io_q_unknown_32("", &q_u, data, 0);
+
+       /* find the machine account: tell the caller if it exists.
+          lkclXXXX i have *no* idea if this is a problem or not
+          or even if you are supposed to construct a different
+          reply if the account already exists...
+        */
+
+       fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
+                                   q_u.uni_mach_acct.uni_str_len));
+
+       become_root(True);
+       sam_pass = getsam21pwnam(mach_acct);
+       unbecome_root(True);
+
+       if (sam_pass != NULL)
+       {
+               /* machine account exists: say so */
+               status = 0xC0000000 | NT_STATUS_USER_EXISTS;
+       }
+       else
+       {
+               /* this could cause trouble... */
+               DEBUG(0,("trouble!\n"));
+               status = 0;
+       }
 
        /* construct reply. */
-       samr_reply_create_user(&q_u, rdata);
+       samr_reply_unknown_32(&q_u, rdata, status);
+
+       return True;
 }
 
 
@@ -2862,13 +1529,13 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
 
        r_u.status = 0x0;
        /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
+       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
        {
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /* associate the domain SID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+       if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
        {
                /* oh, whoops.  don't know what error message to return, here */
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2876,7 +1543,7 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
 
        if (r_u.status != 0 && pol_open)
        {
-               close_policy_hnd(&(r_u.connect_pol));
+               close_lsa_policy_hnd(&(r_u.connect_pol));
        }
 
        DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
@@ -2891,11 +1558,17 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
 /*******************************************************************
  api_samr_connect_anon
  ********************************************************************/
-static void api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CONNECT_ANON q_u;
+
+       /* grab the samr open policy */
        samr_io_q_connect_anon("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_connect_anon(&q_u, rdata);
+
+       return True;
 }
 
 /*******************************************************************
@@ -2911,13 +1584,13 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
 
        r_u.status = 0x0;
        /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
+       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
        {
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /* associate the domain SID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+       if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
        {
                /* oh, whoops.  don't know what error message to return, here */
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2925,7 +1598,7 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
 
        if (r_u.status != 0 && pol_open)
        {
-               close_policy_hnd(&(r_u.connect_pol));
+               close_lsa_policy_hnd(&(r_u.connect_pol));
        }
 
        DEBUG(5,("samr_connect: %d\n", __LINE__));
@@ -2940,11 +1613,17 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
 /*******************************************************************
  api_samr_connect
  ********************************************************************/
-static void api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
 {
        SAMR_Q_CONNECT q_u;
+
+       /* grab the samr open policy */
        samr_io_q_connect("", &q_u, data, 0);
+
+       /* construct reply.  always indicate success */
        samr_reply_connect(&q_u, rdata);
+
+       return True;
 }
 
 /*******************************************************************
@@ -2954,36 +1633,19 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
                                prs_struct *rdata)
 {
        SAMR_R_OPEN_ALIAS r_u;
-       DOM_SID sid;
        BOOL pol_open = False;
 
        /* set up the SAMR open_alias response */
 
        r_u.status = 0x0;
-       if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &sid))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
        /* get a (unique) handle.  open a policy on it. */
-       if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.pol))))
+       if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
        {
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       DEBUG(0,("TODO: verify that the alias rid exists\n"));
-
        /* associate a RID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
-       {
-               /* oh, whoops.  don't know what error message to return, here */
-               r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       sid_append_rid(&sid, q_u->rid_alias);
-
-       /* associate an alias SID with the (unique) handle. */
-       if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.pol), &sid))
+       if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
        {
                /* oh, whoops.  don't know what error message to return, here */
                r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2991,7 +1653,7 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
 
        if (r_u.status != 0 && pol_open)
        {
-               close_policy_hnd(&(r_u.pol));
+               close_lsa_policy_hnd(&(r_u.pol));
        }
 
        DEBUG(5,("samr_open_alias: %d\n", __LINE__));
@@ -3006,117 +1668,18 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
 /*******************************************************************
  api_samr_open_alias
  ********************************************************************/
-static void api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
                                 
 {
        SAMR_Q_OPEN_ALIAS q_u;
-       samr_io_q_open_alias("", &q_u, data, 0);
-       samr_reply_open_alias(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_open_group
- ********************************************************************/
-static void samr_reply_open_group(SAMR_Q_OPEN_GROUP *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_OPEN_GROUP r_u;
-       DOM_SID sid;
-
-       DEBUG(5,("samr_open_group: %d\n", __LINE__));
-
-       r_u.status = 0x0;
-
-       /* find the domain sid associated with the policy handle */
-       if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->domain_pol, &sid))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       if (r_u.status == 0x0 && !sid_equal(&sid, &global_sam_sid))
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
-       }
-
-       if (r_u.status == 0x0)
-       {
-               r_u.status = open_samr_group(&sid, &r_u.pol, q_u->rid_group);
-       }
-
-       /* store the response in the SMB stream */
-       samr_io_r_open_group("", &r_u, rdata, 0);
-
-       DEBUG(5,("samr_open_group: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_open_group
- ********************************************************************/
-static void api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-                                
-{
-       SAMR_Q_OPEN_GROUP q_u;
-       samr_io_q_open_group("", &q_u, data, 0);
-       samr_reply_open_group(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_lookup_domain
- ********************************************************************/
-static void samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
-                               prs_struct *rdata)
-{
-       SAMR_R_LOOKUP_DOMAIN r_u;
-       fstring domain;
-
-       DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
-
-       r_u.ptr_sid = 0;
-       r_u.status = 0x0;
-
-       /* find the connection policy handle */
-       if (find_policy_by_hnd(&(q_u->connect_pol)) == -1)
-       {
-               r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
-       }
-
-       if (r_u.status == 0x0)
-        {
-               unistr2_to_ascii(domain, &(q_u->uni_domain), sizeof(domain));
-               DEBUG(5, ("Lookup Domain: %s\n", domain));
-
-               /* check it's one of ours */
-               if (strequal(domain, global_sam_name))
-               {
-                       make_dom_sid2(&(r_u.dom_sid), &global_sam_sid);
-                       r_u.ptr_sid = 1;
-               }
-               else if (strequal(domain, "BUILTIN"))
-               {
-                       make_dom_sid2(&(r_u.dom_sid), &global_sid_S_1_5_20);
-                       r_u.ptr_sid = 1;
-               }
-               else
-               {
-                       r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_DOMAIN;
-               }
-       }
 
-       /* store the response in the SMB stream */
-       samr_io_r_lookup_domain("", &r_u, rdata, 0);
+       /* grab the samr open policy */
+       samr_io_q_open_alias("", &q_u, data, 0);
 
-       DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
-}
+       /* construct reply.  always indicate success */
+       samr_reply_open_alias(&q_u, rdata);
 
-/*******************************************************************
- api_samr_lookup_domain
- ********************************************************************/
-static void api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
-       SAMR_Q_LOOKUP_DOMAIN q_u;
-       samr_io_q_lookup_domain("", &q_u, data, 0);
-       samr_reply_lookup_domain(&q_u, rdata);
+       return True;
 }
 
 /*******************************************************************
@@ -3127,51 +1690,32 @@ static 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_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_IDS"       , SAMR_LOOKUP_IDS       , api_samr_lookup_ids       },
        { "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_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_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_unknown_38       },
+       { "SAMR_0x32"             , 0x32                  , api_samr_unknown_32       },
+       { "SAMR_UNKNOWN_12"       , SAMR_UNKNOWN_12       , api_samr_unknown_12       },
+       { "SAMR_UNKNOWN_38"       , SAMR_UNKNOWN_38       , api_samr_unknown_38       },
        { "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_LOOKUP_DOMAIN"    , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
-       { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_unknown_3        },
-       { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_unknown_2c       },
+       { "SAMR_UNKNOWN_3"        , SAMR_UNKNOWN_3        , api_samr_unknown_3        },
+       { "SAMR_UNKNOWN_2C"       , SAMR_UNKNOWN_2C       , api_samr_unknown_2c       },
        { NULL                    , 0                     , NULL                      }
 };
 
 /*******************************************************************
  receives a samr pipe and responds.
  ********************************************************************/
-BOOL api_samr_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
 {
     return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
 }
-
index 8dd99cccc6fb1f240a92ecb22841fef341846203..f42b94832b04f72b6bd551a686bf6c230b5a4665 100644 (file)
@@ -30,248 +30,253 @@ extern int DEBUGLEVEL;
 extern pstring global_myname;
 
 /*******************************************************************
- fill in a share info level 1 structure.
+ Fill in a share info level 1 structure.
+ ********************************************************************/
 
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself.  yuck.
+static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
+{
+       int len_net_name;
+       pstring net_name;
+       pstring remark;
+       uint32 type;
 
- see ipc.c:fill_share_info()
+       pstrcpy(net_name, lp_servicename(snum));
+       pstrcpy(remark, lp_comment(snum));
+       pstring_sub(remark,"%S",lp_servicename(snum));
+       len_net_name = strlen(net_name);
 
+       /* work out the share type */
+       type = STYPE_DISKTREE;
+               
+       if (lp_print_ok(snum))
+               type = STYPE_PRINTQ;
+       if (strequal("IPC$", net_name))
+               type = STYPE_IPC;
+       if (net_name[len_net_name] == '$')
+               type |= STYPE_HIDDEN;
+
+       init_srv_share_info1(&sh1->info_1, net_name, type, remark);
+       init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
+}
+
+/*******************************************************************
+ Fill in a share info level 2 structure.
  ********************************************************************/
-static void make_srv_share_1_info(SH_INFO_1    *sh1,
-                                  SH_INFO_1_STR *str1, int snum)
+
+static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
 {
        int len_net_name;
        pstring net_name;
        pstring remark;
+       pstring path;
+       pstring passwd;
        uint32 type;
 
        pstrcpy(net_name, lp_servicename(snum));
-       pstrcpy(remark  , lp_comment    (snum));
+       pstrcpy(remark, lp_comment(snum));
+       pstring_sub(remark,"%S",lp_servicename(snum));
+       pstrcpy(path, lp_pathname(snum));
+       pstrcpy(passwd, "");
        len_net_name = strlen(net_name);
 
        /* work out the share type */
        type = STYPE_DISKTREE;
                
-       if (lp_print_ok(snum))             type = STYPE_PRINTQ;
-       if (strequal("IPC$", net_name))    type = STYPE_IPC;
-       if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
-
-       make_srv_share_info1    (sh1 , net_name, type, remark);
-       make_srv_share_info1_str(str1, net_name,       remark);
+       if (lp_print_ok(snum))
+               type = STYPE_PRINTQ;
+       if (strequal("IPC$", net_name))
+               type = STYPE_IPC;
+       if (net_name[len_net_name] == '$')
+               type |= STYPE_HIDDEN;
+
+       init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
+       init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
 }
 
 /*******************************************************************
- fill in a share info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself.  yuck.
-
+ Fill in a share info structure.
  ********************************************************************/
-static void make_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, uint32 *snum, uint32 *svcs)
+
+static BOOL init_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
+              uint32 info_level, uint32 *resume_hnd, uint32 *total_entries)
 {
-       uint32 num_entries = 0;
-       (*svcs) = lp_numservices();
+       int num_entries = 0;
+       int num_services = lp_numservices();
+       int snum;
 
-       if (sh1 == NULL)
-       {
-               (*snum) = 0;
-               return;
+       DEBUG(5,("init_srv_share_info_ctr\n"));
+
+       ZERO_STRUCTPN(ctr);
+
+       ctr->info_level = ctr->switch_value = info_level;
+       *resume_hnd = 0;
+
+       /* Count the number of entries. */
+       for (snum = 0; snum < num_services; snum++) {
+               if (lp_browseable(snum) && lp_snum_ok(snum))
+                       num_entries++;
        }
 
-       DEBUG(5,("make_srv_share_1_sh1\n"));
+       *total_entries = num_entries;
+       ctr->num_entries2 = ctr->num_entries = num_entries;
+       ctr->ptr_share_info = ctr->ptr_entries = 1;
 
-       for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
+       if (!num_entries)
+               return True;
+
+       switch (info_level) {
+       case 1:
        {
-               if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
-               {
-                       make_srv_share_1_info(&(sh1->info_1    [num_entries]),
-                                                 &(sh1->info_1_str[num_entries]), (*snum));
+               SRV_SHARE_INFO_1 *info1;
+               int i = 0;
 
-                       /* move on to creating next share */
-                       num_entries++;
+               info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1));
+
+               for (snum = *resume_hnd; snum < num_services; snum++) {
+                       if (lp_browseable(snum) && lp_snum_ok(snum)) {
+                               init_srv_share_info_1(&info1[i++], snum);
+                       }
                }
+
+               ctr->share.info1 = info1;
+               break;
        }
 
-       sh1->num_entries_read  = num_entries;
-       sh1->ptr_share_info    = num_entries > 0 ? 1 : 0;
-       sh1->num_entries_read2 = num_entries;
-       
-       if ((*snum) >= (*svcs))
+       case 2:
        {
-               (*snum) = 0;
+               SRV_SHARE_INFO_2 *info2;
+               int i = 0;
+
+               info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2));
+
+               for (snum = *resume_hnd; snum < num_services; snum++) {
+                       if (lp_browseable(snum) && lp_snum_ok(snum)) {
+                               init_srv_share_info_2(&info2[i++], snum);
+                       }
+               }
+
+               ctr->share.info2 = info2;
+               break;
        }
-}
 
-/*******************************************************************
- fill in a share info level 2 structure.
+       default:
+               DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
+               return False;
+       }
 
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself.  yuck.
+       return True;
+}
 
- see ipc.c:fill_share_info()
+/*******************************************************************
+ Inits a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
 
- ********************************************************************/
-static void make_srv_share_2_info(SH_INFO_2     *sh2,
-                                  SH_INFO_2_STR *str2, int snum)
+static void init_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
+                                     uint32 info_level, uint32 resume_hnd)  
 {
-       int len_net_name;
-       pstring net_name;
-       pstring remark;
-       pstring path;
-       pstring passwd;
-       uint32 type;
+       DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
 
-       pstrcpy(net_name, lp_servicename(snum));
-       pstrcpy(remark  , lp_comment    (snum));
-       pstrcpy(path    , lp_pathname   (snum));
-       pstrcpy(passwd  , "");
-       len_net_name = strlen(net_name);
-
-       /* work out the share type */
-       type = STYPE_DISKTREE;
-               
-       if (lp_print_ok(snum))             type = STYPE_PRINTQ;
-       if (strequal("IPC$", net_name))    type = STYPE_IPC;
-       if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+       if (init_srv_share_info_ctr(&r_n->ctr, info_level,
+                                   &resume_hnd, &r_n->total_entries)) {
+               r_n->status = 0x0;
+       } else {
+               r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+       }
 
-       make_srv_share_info2    (sh2 , net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
-       make_srv_share_info2_str(str2, net_name,       remark,                   path, passwd);
+       init_enum_hnd(&r_n->enum_hnd, resume_hnd);
 }
 
 /*******************************************************************
- fill in a share info level 2 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself.  yuck.
+ Net share enum.
+********************************************************************/
 
- ********************************************************************/
-static void make_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, uint32 *snum, uint32 *svcs)
+static BOOL srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+                               prs_struct *rdata)
 {
-       uint32 num_entries = 0;
-       (*svcs) = lp_numservices();
+       SRV_R_NET_SHARE_ENUM r_n;
+       BOOL ret;
 
-       if (sh2 == NULL)
-       {
-               (*snum) = 0;
-               return;
-       }
+       DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
 
-       DEBUG(5,("make_srv_share_2_sh1\n"));
+       /* Create the list of shares for the response. */
+       init_srv_r_net_share_enum(&r_n,
+                               q_n->ctr.info_level,
+                               get_enum_hnd(&q_n->enum_hnd));
 
-       for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
-       {
-               if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
-               {
-                       make_srv_share_2_info(&(sh2->info_2    [num_entries]),
-                                                 &(sh2->info_2_str[num_entries]), (*snum));
+       /* store the response in the SMB stream */
+       ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
 
-                       /* move on to creating next share */
-                       num_entries++;
-               }
-       }
+       /* Free the memory used by the response. */
+       free_srv_r_net_share_enum(&r_n);
 
-       sh2->num_entries_read  = num_entries;
-       sh2->ptr_share_info    = num_entries > 0 ? 1 : 0;
-       sh2->num_entries_read2 = num_entries;
-       
-       if ((*snum) >= (*svcs))
-       {
-               (*snum) = 0;
-       }
+       DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
+
+       return ret;
 }
 
 /*******************************************************************
makes a SRV_R_NET_SHARE_ENUM structure.
Inits a SRV_R_NET_SHARE_GET_INFO structure.
 ********************************************************************/
-static uint32 make_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
-                               int switch_value, uint32 *resume_hnd, uint32 *total_entries)  
+
+static void init_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
+                                 char *share_name, uint32 info_level)
 {
        uint32 status = 0x0;
-       DEBUG(5,("make_srv_share_info_ctr: %d\n", __LINE__));
+       int snum;
 
-       ctr->switch_value = switch_value;
+       DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
 
-       switch (switch_value)
-       {
+       r_n->switch_value = info_level;
+
+       snum = find_service(share_name);
+
+       if (snum >= 0) {
+               switch (info_level) {
                case 1:
-               {
-                       make_srv_share_info_1(&(ctr->share.info1), resume_hnd, total_entries);
-                       ctr->ptr_share_ctr = 1;
+                       init_srv_share_info_1(&r_n->share.info1, snum);
                        break;
-               }
                case 2:
-               {
-                       make_srv_share_info_2(&(ctr->share.info2), resume_hnd, total_entries);
-                       ctr->ptr_share_ctr = 2;
+                       init_srv_share_info_2(&r_n->share.info2, snum);
                        break;
-               }
                default:
-               {
-                       DEBUG(5,("make_srv_share_info_ctr: unsupported switch value %d\n",
-                                 switch_value));
-                       (*resume_hnd = 0);
-                       (*total_entries) = 0;
-                       ctr->ptr_share_ctr = 0;
+                       DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
                        status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
                        break;
                }
+       } else {
+               status = 0xC0000000 | NT_STATUS_BAD_NETWORK_NAME;
        }
 
-       return status;
+       r_n->ptr_share_ctr = (status == 0x0) ? 1 : 0;
+       r_n->status = status;
 }
 
 /*******************************************************************
makes a SRV_R_NET_SHARE_ENUM structure.
Net share get info.
 ********************************************************************/
-static void make_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
-                               uint32 resume_hnd, int share_level, int switch_value)  
-{
-       DEBUG(5,("make_srv_r_net_share_enum: %d\n", __LINE__));
-
-       r_n->share_level  = share_level;
-       if (share_level == 0)
-       {
-               r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-       }
-       else
-       {
-               r_n->status = make_srv_share_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
-       }
-       if (r_n->status != 0x0)
-       {
-               resume_hnd = 0;
-       }
-       make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
-}
 
-/*******************************************************************
-net share enum
-********************************************************************/
-static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
-                               prs_struct *rdata)
+static BOOL srv_reply_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
+                                         prs_struct *rdata)
 {
-       SRV_R_NET_SHARE_ENUM r_n;
-       SRV_SHARE_INFO_CTR ctr;
+       SRV_R_NET_SHARE_GET_INFO r_n;
+       char *share_name;
+       BOOL ret;
 
-       r_n.ctr = &ctr;
+       DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
 
-       DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
-
-       /* set up the */
-       make_srv_r_net_share_enum(&r_n,
-                               get_enum_hnd(&q_n->enum_hnd),
-                               q_n->share_level,
-                               q_n->ctr->switch_value);
+       /* Create the list of shares for the response. */
+       share_name = dos_unistr2_to_str(&q_n->uni_share_name);
+       init_srv_r_net_share_get_info(&r_n, share_name, q_n->info_level);
 
        /* store the response in the SMB stream */
-       srv_io_r_net_share_enum("", &r_n, rdata, 0);
+       ret = srv_io_r_net_share_get_info("", &r_n, rdata, 0);
 
-       DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
+       /* Free the memory used by the response. */
+       free_srv_r_net_share_get_info(&r_n);
+
+       DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
+
+       return ret;
 }
 
 /*******************************************************************
@@ -282,11 +287,11 @@ static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_sess_0_info(SESS_INFO_0    *se0, SESS_INFO_0_STR *str0,
+static void init_srv_sess_0_info(SESS_INFO_0    *se0, SESS_INFO_0_STR *str0,
                                char *name)
 {
-       make_srv_sess_info0    (se0 , name);
-       make_srv_sess_info0_str(str0, name);
+       init_srv_sess_info0    (se0 , name);
+       init_srv_sess_info0_str(str0, name);
 }
 
 /*******************************************************************
@@ -297,39 +302,26 @@ static void make_srv_sess_0_info(SESS_INFO_0    *se0, SESS_INFO_0_STR *str0,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
 {
        uint32 num_entries = 0;
-       struct connect_record *crec;
-       uint32 session_count;
+       (*stot) = 1;
 
-        if (!get_session_count(&crec, &session_count))
-       {
-               (*snum) = 0;
-               (*stot) = 0;
-               return;
-       }
-
-       (*stot) = session_count;
-
-       DEBUG(0,("Session Count : %u\n",session_count));
-       
        if (ss0 == NULL)
        {
                (*snum) = 0;
-               free(crec);
                return;
        }
 
+       DEBUG(5,("init_srv_sess_0_ss0\n"));
+
        if (snum)
        {
-               DEBUG(0,("snum ok\n"));
                for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
                {
-                       make_srv_sess_0_info(&(ss0->info_0    [num_entries]),
-                                                                &(ss0->info_0_str[num_entries]), crec[num_entries].machine);
+                       init_srv_sess_0_info(&(ss0->info_0    [num_entries]),
+                                                                &(ss0->info_0_str[num_entries]), "MACHINE");
 
-                       DEBUG(0,("make_srv_sess_0_info\n"));
                        /* move on to creating next session */
                        /* move on to creating next sess */
                        num_entries++;
@@ -350,7 +342,6 @@ static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
                ss0->ptr_sess_info = 0;
                ss0->num_entries_read2 = 0;
        }
-       free(crec);
 }
 
 /*******************************************************************
@@ -361,14 +352,14 @@ static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_sess_1_info(SESS_INFO_1    *se1, SESS_INFO_1_STR *str1,
+static void init_srv_sess_1_info(SESS_INFO_1    *se1, SESS_INFO_1_STR *str1,
                                char *name, char *user,
                                uint32 num_opens,
                                uint32 open_time, uint32 idle_time,
                                uint32 usr_flgs)
 {
-       make_srv_sess_info1    (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
-       make_srv_sess_info1_str(str1, name, user);
+       init_srv_sess_info1    (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
+       init_srv_sess_info1_str(str1, name, user);
 }
 
 /*******************************************************************
@@ -379,41 +370,26 @@ static void make_srv_sess_1_info(SESS_INFO_1    *se1, SESS_INFO_1_STR *str1,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
 {
        uint32 num_entries = 0;
-       struct connect_record *crec;
-       uint32 session_count;
+       (*stot) = 1;
 
-        if (!get_session_count(&crec, &session_count))
-       {
-               (*snum) = 0;
-               (*stot) = 0;
-               return;
-       }
-
-       (*stot) = session_count;
-
-       DEBUG(0,("Session Count (info1) : %u\n",session_count));
        if (ss1 == NULL)
        {
                (*snum) = 0;
-               free(crec);
                return;
        }
 
-       DEBUG(5,("make_srv_sess_1_ss1\n"));
+       DEBUG(5,("init_srv_sess_1_ss1\n"));
 
        if (snum)
        {
                for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
                {
-                       DEBUG(0,("sess1 machine: %s, uid : %u\n",crec[num_entries].machine,crec[num_entries].uid));
-                       make_srv_sess_1_info(&(ss1->info_1    [num_entries]),
+                       init_srv_sess_1_info(&(ss1->info_1    [num_entries]),
                                                                 &(ss1->info_1_str[num_entries]),
-                                            crec[num_entries].machine, 
-                                            uidtoname(crec[num_entries].uid), 1, 10, 5, 0);
-/*     What are these on the End ??? */
+                                            "MACHINE", "dummy_user", 1, 10, 5, 0);
 
                        /* move on to creating next session */
                        /* move on to creating next sess */
@@ -437,17 +413,16 @@ static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
                
                (*stot) = 0;
        }
-       free(crec);
 }
 
 /*******************************************************************
  makes a SRV_R_NET_SESS_ENUM structure.
 ********************************************************************/
-static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
+static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
                                int switch_value, uint32 *resume_hnd, uint32 *total_entries)
 {
        uint32 status = 0x0;
-       DEBUG(5,("make_srv_sess_info_ctr: %d\n", __LINE__));
+       DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
 
        ctr->switch_value = switch_value;
 
@@ -455,19 +430,19 @@ static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
        {
                case 0:
                {
-                       make_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
+                       init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
                        ctr->ptr_sess_ctr = 1;
                        break;
                }
                case 1:
                {
-                       make_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
+                       init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
                        ctr->ptr_sess_ctr = 1;
                        break;
                }
                default:
                {
-                       DEBUG(5,("make_srv_sess_info_ctr: unsupported switch value %d\n",
+                       DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n",
                                  switch_value));
                        (*resume_hnd) = 0;
                        (*total_entries) = 0;
@@ -483,10 +458,10 @@ static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
 /*******************************************************************
  makes a SRV_R_NET_SESS_ENUM structure.
 ********************************************************************/
-static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
+static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
                                uint32 resume_hnd, int sess_level, int switch_value)  
 {
-       DEBUG(5,("make_srv_r_net_sess_enum: %d\n", __LINE__));
+       DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
 
        r_n->sess_level  = sess_level;
        if (sess_level == -1)
@@ -495,13 +470,13 @@ static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
        }
        else
        {
-               r_n->status = make_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+               r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
        }
        if (r_n->status != 0x0)
        {
                resume_hnd = 0;
        }
-       make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+       init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
 }
 
 /*******************************************************************
@@ -518,7 +493,7 @@ static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
        DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
 
        /* set up the */
-       make_srv_r_net_sess_enum(&r_n,
+       init_srv_r_net_sess_enum(&r_n,
                                get_enum_hnd(&q_n->enum_hnd),
                                q_n->sess_level,
                                q_n->ctr->switch_value);
@@ -537,20 +512,10 @@ static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
 {
-       uint32 num_entries = 0; 
-       struct connect_record *crec;
-       uint32 connection_count;
-
-        if (!get_connection_status(&crec, &connection_count))
-       {
-               (*snum) = 0;
-               (*stot) = 0;
-               return;
-       }
-
-       (*stot) = connection_count;
+       uint32 num_entries = 0;
+       (*stot) = 1;
 
        if (ss0 == NULL)
        {
@@ -558,13 +523,13 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
                return;
        }
 
-       DEBUG(0,("make_srv_conn_0_ss0\n"));
+       DEBUG(5,("init_srv_conn_0_ss0\n"));
 
        if (snum)
        {
                for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
                {
-                       make_srv_conn_info0(&(ss0->info_0    [num_entries]), (*snum));
+                       init_srv_conn_info0(&(ss0->info_0    [num_entries]), (*stot));
 
                        /* move on to creating next connection */
                        /* move on to creating next conn */
@@ -590,8 +555,6 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
 
                (*stot) = 0;
        }
-
-       free(crec);
 }
 
 /*******************************************************************
@@ -602,13 +565,13 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_conn_1_info(CONN_INFO_1    *se1, CONN_INFO_1_STR *str1,
+static void init_srv_conn_1_info(CONN_INFO_1    *se1, CONN_INFO_1_STR *str1,
                                uint32 id, uint32 type,
                                uint32 num_opens, uint32 num_users, uint32 open_time,
                                char *usr_name, char *net_name)
 {
-       make_srv_conn_info1    (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
-       make_srv_conn_info1_str(str1, usr_name, net_name);
+       init_srv_conn_info1    (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
+       init_srv_conn_info1_str(str1, usr_name, net_name);
 }
 
 /*******************************************************************
@@ -619,23 +582,10 @@ static void make_srv_conn_1_info(CONN_INFO_1    *se1, CONN_INFO_1_STR *str1,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
 {
-       uint32 num_entries = 0; 
-        time_t current_time;
-        time_t diff;
-
-       struct connect_record *crec;
-       uint32 connection_count;
-
-        if (!get_connection_status(&crec, &connection_count))
-       {
-               (*snum) = 0;
-               (*stot) = 0;
-               return;
-       }
-
-       (*stot) = connection_count;
+       uint32 num_entries = 0;
+       (*stot) = 1;
 
        if (ss1 == NULL)
        {
@@ -643,21 +593,15 @@ static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
                return;
        }
 
-        current_time=time(NULL);
-        
-       DEBUG(5,("make_srv_conn_1_ss1\n"));
+       DEBUG(5,("init_srv_conn_1_ss1\n"));
 
        if (snum)
        {
                for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
                {
-                       diff = current_time - crec[num_entries].start;
-                       make_srv_conn_1_info(&(ss1->info_1    [num_entries]),
+                       init_srv_conn_1_info(&(ss1->info_1    [num_entries]),
                                                                 &(ss1->info_1_str[num_entries]),
-                                            (*snum), 0, 0, 1, diff,uidtoname(crec[num_entries].uid), 
-                                            crec[num_entries].name);
-
-/* FIXME : type of connection + number of locked files */
+                                            (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
 
                        /* move on to creating next connection */
                        /* move on to creating next conn */
@@ -682,18 +626,16 @@ static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
                
                (*stot) = 0;
        }
-
-       free(crec);
 }
 
 /*******************************************************************
  makes a SRV_R_NET_CONN_ENUM structure.
 ********************************************************************/
-static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
+static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
                                int switch_value, uint32 *resume_hnd, uint32 *total_entries)
 {
        uint32 status = 0x0;
-       DEBUG(5,("make_srv_conn_info_ctr: %d\n", __LINE__));
+       DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
 
        ctr->switch_value = switch_value;
 
@@ -701,19 +643,19 @@ static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
        {
                case 0:
                {
-                       make_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
+                       init_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
                        ctr->ptr_conn_ctr = 1;
                        break;
                }
                case 1:
                {
-                       make_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
+                       init_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
                        ctr->ptr_conn_ctr = 1;
                        break;
                }
                default:
                {
-                       DEBUG(5,("make_srv_conn_info_ctr: unsupported switch value %d\n",
+                       DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n",
                                  switch_value));
                        (*resume_hnd = 0);
                        (*total_entries) = 0;
@@ -729,10 +671,10 @@ static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
 /*******************************************************************
  makes a SRV_R_NET_CONN_ENUM structure.
 ********************************************************************/
-static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
+static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
                                uint32 resume_hnd, int conn_level, int switch_value)  
 {
-       DEBUG(5,("make_srv_r_net_conn_enum: %d\n", __LINE__));
+       DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
 
        r_n->conn_level  = conn_level;
        if (conn_level == -1)
@@ -741,13 +683,13 @@ static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
        }
        else
        {
-               r_n->status = make_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+               r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
        }
        if (r_n->status != 0x0)
        {
                resume_hnd = 0;
        }
-       make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+       init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
 }
 
 /*******************************************************************
@@ -764,7 +706,7 @@ static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
        DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
 
        /* set up the */
-       make_srv_r_net_conn_enum(&r_n,
+       init_srv_r_net_conn_enum(&r_n,
                                get_enum_hnd(&q_n->enum_hnd),
                                q_n->conn_level,
                                q_n->ctr->switch_value);
@@ -778,12 +720,12 @@ static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
 /*******************************************************************
  fill in a file info level 3 structure.
  ********************************************************************/
-static void make_srv_file_3_info(FILE_INFO_3     *fl3, FILE_INFO_3_STR *str3,
+static void init_srv_file_3_info(FILE_INFO_3     *fl3, FILE_INFO_3_STR *str3,
                                uint32 fnum, uint32 perms, uint32 num_locks,
                                char *path_name, char *user_name)
 {
-       make_srv_file_info3    (fl3 , fnum, perms, num_locks, path_name, user_name);
-       make_srv_file_info3_str(str3, path_name, user_name);
+       init_srv_file_info3    (fl3 , fnum, perms, num_locks, path_name, user_name);
+       init_srv_file_info3_str(str3, path_name, user_name);
 }
 
 /*******************************************************************
@@ -794,7 +736,7 @@ static void make_srv_file_3_info(FILE_INFO_3     *fl3, FILE_INFO_3_STR *str3,
  functions itself.  yuck.
 
  ********************************************************************/
-static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
+static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
 {
        uint32 num_entries = 0;
        (*ftot) = 1;
@@ -805,11 +747,11 @@ static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
                return;
        }
 
-       DEBUG(5,("make_srv_file_3_fl3\n"));
+       DEBUG(5,("init_srv_file_3_fl3\n"));
 
        for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
        {
-               make_srv_file_3_info(&(fl3->info_3    [num_entries]),
+               init_srv_file_3_info(&(fl3->info_3    [num_entries]),
                                         &(fl3->info_3_str[num_entries]),
                                     (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
 
@@ -830,11 +772,11 @@ static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
 /*******************************************************************
  makes a SRV_R_NET_FILE_ENUM structure.
 ********************************************************************/
-static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
                                int switch_value, uint32 *resume_hnd, uint32 *total_entries)  
 {
        uint32 status = 0x0;
-       DEBUG(5,("make_srv_file_info_ctr: %d\n", __LINE__));
+       DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
 
        ctr->switch_value = switch_value;
 
@@ -842,13 +784,13 @@ static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
        {
                case 3:
                {
-                       make_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
+                       init_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
                        ctr->ptr_file_ctr = 1;
                        break;
                }
                default:
                {
-                       DEBUG(5,("make_srv_file_info_ctr: unsupported switch value %d\n",
+                       DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n",
                                  switch_value));
                        (*resume_hnd = 0);
                        (*total_entries) = 0;
@@ -864,10 +806,10 @@ static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
 /*******************************************************************
  makes a SRV_R_NET_FILE_ENUM structure.
 ********************************************************************/
-static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
+static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
                                uint32 resume_hnd, int file_level, int switch_value)  
 {
-       DEBUG(5,("make_srv_r_net_file_enum: %d\n", __LINE__));
+       DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
 
        r_n->file_level  = file_level;
        if (file_level == 0)
@@ -876,13 +818,13 @@ static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
        }
        else
        {
-               r_n->status = make_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
+               r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
        }
        if (r_n->status != 0x0)
        {
                resume_hnd = 0;
        }
-       make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+       init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
 }
 
 /*******************************************************************
@@ -899,7 +841,7 @@ static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
        DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
 
        /* set up the */
-       make_srv_r_net_file_enum(&r_n,
+       init_srv_r_net_file_enum(&r_n,
                                get_enum_hnd(&q_n->enum_hnd),
                                q_n->file_level,
                                q_n->ctr->switch_value);
@@ -913,6 +855,7 @@ static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
 /*******************************************************************
 net server get info
 ********************************************************************/
+
 static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
                                prs_struct *rdata)
 {
@@ -927,12 +870,10 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
        {
                case 102:
                {
-                       make_srv_info_102(&ctr.srv.sv102,
-                                         500, /* platform id */
-                                         global_myname,
-                                         lp_serverstring(),
-                                         lp_major_announce_version(),
-                                         lp_minor_announce_version(),
+                       init_srv_info_102(&ctr.srv.sv102,
+                                         500, global_myname, 
+                                         string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
+                                         lp_major_announce_version(), lp_minor_announce_version(),
                                          lp_default_server_announce(),
                                          0xffffffff, /* users */
                                          0xf, /* disc */
@@ -945,13 +886,11 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
                }
                case 101:
                {
-                       make_srv_info_101(&ctr.srv.sv101,
-                                         500, /* platform id */
-                                         global_myname,
-                                         lp_major_announce_version(),
-                                         lp_minor_announce_version(),
+                       init_srv_info_101(&ctr.srv.sv101,
+                                         500, global_myname,
+                                         lp_major_announce_version(), lp_minor_announce_version(),
                                          lp_default_server_announce(),
-                                         lp_serverstring());
+                                         string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
                        break;
                }
                default:
@@ -962,7 +901,7 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
        }
 
        /* set up the net server get info structure */
-       make_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
+       init_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
 
        /* store the response in the SMB stream */
        srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
@@ -972,7 +911,7 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
 
 /*******************************************************************
 ********************************************************************/
-static void api_srv_net_srv_get_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_srv_get_info( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_SRV_GET_INFO q_n;
@@ -982,12 +921,14 @@ static void api_srv_net_srv_get_info( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        srv_reply_net_srv_get_info(&q_n, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
 ********************************************************************/
-static void api_srv_net_file_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_file_enum( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_FILE_ENUM q_n;
@@ -1000,12 +941,14 @@ static void api_srv_net_file_enum( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        srv_reply_net_file_enum(&q_n, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
 ********************************************************************/
-static void api_srv_net_conn_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_conn_enum( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_CONN_ENUM q_n;
@@ -1018,12 +961,14 @@ static void api_srv_net_conn_enum( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        srv_reply_net_conn_enum(&q_n, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
 ********************************************************************/
-static void api_srv_net_sess_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_sess_enum( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_SESS_ENUM q_n;
@@ -1036,30 +981,63 @@ static void api_srv_net_sess_enum( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        srv_reply_net_sess_enum(&q_n, rdata);
+
+       return True;
 }
 
 
 /*******************************************************************
+ RPC to enumerate shares.
 ********************************************************************/
-static void api_srv_net_share_enum( rpcsrv_struct *p, prs_struct *data,
+
+static BOOL api_srv_net_share_enum( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_SHARE_ENUM q_n;
-       SRV_SHARE_INFO_CTR ctr;
+       BOOL ret;
 
-       q_n.ctr = &ctr;
+       /* Unmarshall the net server get enum. */
+       if(!srv_io_q_net_share_enum("", &q_n, data, 0)) {
+               DEBUG(0,("api_srv_net_share_enum: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n"));
+               return False;
+       }
 
-       /* grab the net server get enum */
-       srv_io_q_net_share_enum("", &q_n, data, 0);
+       ret = srv_reply_net_share_enum(&q_n, rdata);
 
-       /* construct reply.  always indicate success */
-       srv_reply_net_share_enum(&q_n, rdata);
+       /* Free any data allocated in the unmarshalling. */
+       free_srv_q_net_share_enum(&q_n);
+
+       return ret;
+}
+
+/*******************************************************************
+ RPC to return share information.
+********************************************************************/
+
+static BOOL api_srv_net_share_get_info( uint16 vuid, prs_struct *data,
+                                        prs_struct *rdata )
+{
+       SRV_Q_NET_SHARE_GET_INFO q_n;
+       BOOL ret;
+
+       /* Unmarshall the net server get info. */
+       if(!srv_io_q_net_share_get_info("", &q_n, data, 0)) {
+               DEBUG(0,("api_srv_net_share_get_info: Failed to unmarshall SRV_Q_NET_SHARE_GET_INFO.\n"));
+               return False;
+       }
+
+       ret = srv_reply_net_share_get_info(&q_n, rdata);
+
+       /* Free any data allocated in the unmarshalling. */
+       free_srv_q_net_share_get_info(&q_n);
+
+       return ret;
 }
 
 /*******************************************************************
 time of day
 ********************************************************************/
-static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
+static BOOL srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
                                prs_struct *rdata)
 {
        SRV_R_NET_REMOTE_TOD r_n;
@@ -1076,7 +1054,7 @@ static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
        t = gmtime(&unixdate);
 
        /* set up the */
-       make_time_of_day_info(&tod,
+       init_time_of_day_info(&tod,
                              unixdate,
                              0,
                              t->tm_hour,
@@ -1094,10 +1072,12 @@ static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
        srv_io_r_net_remote_tod("", &r_n, rdata, 0);
        
        DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
+
+       return True;
 }
 /*******************************************************************
 ********************************************************************/
-static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_remote_tod( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        SRV_Q_NET_REMOTE_TOD q_n;
@@ -1107,6 +1087,8 @@ static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        srv_reply_net_remote_tod(&q_n, rdata);
+
+       return True;
 }
 
 
@@ -1115,20 +1097,20 @@ static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
 ********************************************************************/
 struct api_struct api_srv_cmds[] =
 {
-       { "SRV_NETCONNENUM"     , SRV_NETCONNENUM     , api_srv_net_conn_enum    },
-       { "SRV_NETSESSENUM"     , SRV_NETSESSENUM     , api_srv_net_sess_enum    },
-       { "SRV_NETSHAREENUM"    , SRV_NETSHAREENUM    , api_srv_net_share_enum   },
-       { "SRV_NETFILEENUM"     , SRV_NETFILEENUM     , api_srv_net_file_enum    },
-       { "SRV_NET_SRV_GET_INFO", SRV_NET_SRV_GET_INFO, api_srv_net_srv_get_info },
-       { "SRV_NET_REMOTE_TOD"  , SRV_NET_REMOTE_TOD  , api_srv_net_remote_tod   },
-       { NULL                  , 0                   , NULL                     }
+       { "SRV_NETCONNENUM"       , SRV_NETCONNENUM       , api_srv_net_conn_enum    },
+       { "SRV_NETSESSENUM"       , SRV_NETSESSENUM       , api_srv_net_sess_enum    },
+       { "SRV_NETSHAREENUM"      , SRV_NETSHAREENUM      , api_srv_net_share_enum   },
+       { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info },
+       { "SRV_NETFILEENUM"       , SRV_NETFILEENUM       , api_srv_net_file_enum    },
+       { "SRV_NET_SRV_GET_INFO"  , SRV_NET_SRV_GET_INFO  , api_srv_net_srv_get_info },
+       { "SRV_NET_REMOTE_TOD"    , SRV_NET_REMOTE_TOD    , api_srv_net_remote_tod   },
+       { NULL                    , 0                     , NULL                     }
 };
 
 /*******************************************************************
 receives a srvsvc pipe and responds.
 ********************************************************************/
-BOOL api_srvsvc_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
 }
-
index 25dceb41a0d25bbb7140aad6c8a6dc28732f5e49..097ab92d76a2d4b072f74cb25e5b8f9946e2324d 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* retired module */
+/*  this module apparently provides an implementation of DCE/RPC over a
+ *  named pipe (IPC$ connection using SMBtrans).  details of DCE/RPC
+ *  documentation are available (in on-line form) from the X-Open group.
+ *
+ *  this module should provide a level of abstraction between SMB
+ *  and DCE/RPC, while minimising the amount of mallocs, unnecessary
+ *  data copies, and network traffic.
+ *
+ *  in this version, which takes a "let's learn what's going on and
+ *  get something running" approach, there is additional network
+ *  traffic generated, but the code should be easier to understand...
+ *
+ *  ... if you read the docs.  or stare at packets for weeks on end.
+ *
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/*
+ * A list of the rids of well known BUILTIN and Domain users
+ * and groups.
+ */
+
+rid_name builtin_alias_rids[] =
+{  
+    { BUILTIN_ALIAS_RID_ADMINS       , "Administrators" },
+    { BUILTIN_ALIAS_RID_USERS        , "Users" },
+    { BUILTIN_ALIAS_RID_GUESTS       , "Guests" },
+    { BUILTIN_ALIAS_RID_POWER_USERS  , "Power Users" },
+   
+    { BUILTIN_ALIAS_RID_ACCOUNT_OPS  , "Account Operators" },
+    { BUILTIN_ALIAS_RID_SYSTEM_OPS   , "System Operators" },
+    { BUILTIN_ALIAS_RID_PRINT_OPS    , "Print Operators" },
+    { BUILTIN_ALIAS_RID_BACKUP_OPS   , "Backup Operators" },
+    { BUILTIN_ALIAS_RID_REPLICATOR   , "Replicator" },
+    { 0                             , NULL }
+};
+
+/* array lookup of well-known Domain RID users. */
+rid_name domain_user_rids[] =
+{  
+    { DOMAIN_USER_RID_ADMIN         , "Administrator" },
+    { DOMAIN_USER_RID_GUEST         , "Guest" },
+    { 0                             , NULL }
+};
+
+/* array lookup of well-known Domain RID groups. */
+rid_name domain_group_rids[] =
+{  
+    { DOMAIN_GROUP_RID_ADMINS       , "Domain Admins" },
+    { DOMAIN_GROUP_RID_USERS        , "Domain Users" },
+    { DOMAIN_GROUP_RID_GUESTS       , "Domain Guests" },
+    { 0                             , NULL }
+};
+
+int make_dom_gids(char *gids_str, DOM_GID **ppgids)
+{
+  char *ptr;
+  pstring s2;
+  int count;
+  DOM_GID *gids;
+
+  *ppgids = NULL;
+
+  DEBUG(4,("make_dom_gids: %s\n", gids_str));
+
+  if (gids_str == NULL || *gids_str == 0)
+    return 0;
+
+  for (count = 0, ptr = gids_str; 
+       next_token(&ptr, s2, NULL, sizeof(s2)); 
+       count++)
+    ;
+
+  gids = (DOM_GID *)malloc( sizeof(DOM_GID) * count );
+  if(!gids)
+  {
+    DEBUG(0,("make_dom_gids: malloc fail !\n"));
+    return 0;
+  }
+
+  for (count = 0, ptr = gids_str; 
+       next_token(&ptr, s2, NULL, sizeof(s2)) && 
+              count < LSA_MAX_GROUPS; 
+       count++) 
+  {
+    /* the entries are of the form GID/ATTR, ATTR being optional.*/
+    char *attr;
+    uint32 rid = 0;
+    int i;
+
+    attr = strchr(s2,'/');
+    if (attr)
+      *attr++ = 0;
+
+    if (!attr || !*attr)
+      attr = "7"; /* default value for attribute is 7 */
+
+    /* look up the RID string and see if we can turn it into a rid number */
+    for (i = 0; builtin_alias_rids[i].name != NULL; i++)
+    {
+      if (strequal(builtin_alias_rids[i].name, s2))
+      {
+        rid = builtin_alias_rids[i].rid;
+        break;
+      }
+    }
+
+    if (rid == 0)
+      rid = atoi(s2);
+
+    if (rid == 0)
+    {
+      DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n", s2, attr));
+      count--;
+    }
+    else
+    {
+      gids[count].g_rid = rid;
+      gids[count].attr  = atoi(attr);
+
+      DEBUG(5,("group id: %d attr: %d\n", gids[count].g_rid, gids[count].attr));
+    }
+  }
+
+  *ppgids = gids;
+  return count;
+}
+
+
+/*******************************************************************
+ gets a domain user's groups
+ ********************************************************************/
+void get_domain_user_groups(char *domain_groups, char *user)
+{
+       pstring tmp;
+
+       if (domain_groups == NULL || user == NULL) return;
+
+       /* any additional groups this user is in.  e.g power users */
+       pstrcpy(domain_groups, lp_domain_groups());
+
+       /* can only be a user or a guest.  cannot be guest _and_ admin */
+       if (user_in_list(user, lp_domain_guest_group()))
+       {
+               slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
+               pstrcat(domain_groups, tmp);
+
+               DEBUG(3,("domain guest group access %s granted\n", tmp));
+       }
+       else
+       {
+               slprintf(tmp, sizeof(tmp) -1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
+               pstrcat(domain_groups, tmp);
+
+               DEBUG(3,("domain group access %s granted\n", tmp));
+
+               if (user_in_list(user, lp_domain_admin_group()))
+               {
+                       slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
+                       pstrcat(domain_groups, tmp);
+
+                       DEBUG(3,("domain admin group access %s granted\n", tmp));
+               }
+       }
+}
+
+
+/*******************************************************************
+ lookup_group_name
+ ********************************************************************/
+uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type)
+{
+       int i = 0; 
+       (*type) = SID_NAME_DOM_GRP;
+
+       DEBUG(5,("lookup_group_name: rid: %d", rid));
+
+       while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
+       {
+               i++;
+       }
+
+       if (domain_group_rids[i].rid != 0)
+       {
+               fstrcpy(group_name, domain_group_rids[i].name);
+               DEBUG(5,(" = %s\n", group_name));
+               return 0x0;
+       }
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_alias_name
+ ********************************************************************/
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
+{
+       int i = 0; 
+       (*type) = SID_NAME_WKN_GRP;
+
+       DEBUG(5,("lookup_alias_name: rid: %d", rid));
+
+       while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
+       {
+               i++;
+       }
+
+       if (builtin_alias_rids[i].rid != 0)
+       {
+               fstrcpy(alias_name, builtin_alias_rids[i].name);
+               DEBUG(5,(" = %s\n", alias_name));
+               return 0x0;
+       }
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_name
+ ********************************************************************/
+uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type)
+{
+       struct sam_disp_info *disp_info;
+       int i = 0;
+       (*type) = SID_NAME_USER;
+
+       DEBUG(5,("lookup_user_name: rid: %d", rid));
+
+       /* look up the well-known domain user rids first */
+       while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
+       {
+               i++;
+       }
+
+       if (domain_user_rids[i].rid != 0)
+       {
+               fstrcpy(user_name, domain_user_rids[i].name);
+               DEBUG(5,(" = %s\n", user_name));
+               return 0x0;
+       }
+
+       /* ok, it's a user.  find the user account */
+       become_root(True);
+       disp_info = getsamdisprid(rid);
+       unbecome_root(True);
+
+       if (disp_info != NULL)
+       {
+               fstrcpy(user_name, disp_info->smb_name);
+               DEBUG(5,(" = %s\n", user_name));
+               return 0x0;
+       }
+
+       DEBUG(5,(" none mapped\n"));
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_group_rid
+ ********************************************************************/
+uint32 lookup_group_rid(char *group_name, uint32 *rid)
+{
+       char *grp_name;
+       int i = -1; /* start do loop at -1 */
+
+       do /* find, if it exists, a group rid for the group name*/
+       {
+               i++;
+               (*rid) = domain_group_rids[i].rid;
+               grp_name = domain_group_rids[i].name;
+
+       } while (grp_name != NULL && !strequal(grp_name, group_name));
+
+       return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_alias_rid
+ ********************************************************************/
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid)
+{
+       char *als_name;
+       int i = -1; /* start do loop at -1 */
+
+       do /* find, if it exists, a alias rid for the alias name*/
+       {
+               i++;
+               (*rid) = builtin_alias_rids[i].rid;
+               als_name = builtin_alias_rids[i].name;
+
+       } while (als_name != NULL && !strequal(als_name, alias_name));
+
+       return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_rid
+ ********************************************************************/
+uint32 lookup_user_rid(char *user_name, uint32 *rid)
+{
+       struct sam_passwd *sam_pass;
+       (*rid) = 0;
+
+       /* find the user account */
+       become_root(True);
+       sam_pass = getsam21pwnam(user_name);
+       unbecome_root(True);
+
+       if (sam_pass != NULL)
+       {
+               (*rid) = sam_pass->user_rid;
+               return 0x0;
+       }
+
+       return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
index e97ae1ee6eab1768a364b696ddc7b78b92659ef3..658cadc62574997d4d663157ec69f233f3ac9c78 100644 (file)
@@ -46,7 +46,7 @@ static void create_wks_info_100(WKS_INFO_100 *inf)
        pstrcpy (domain , lp_workgroup());
        strupper(domain);
 
-       make_wks_info_100(inf,
+       init_wks_info_100(inf,
                          0x000001f4, /* platform id info */
                          lp_major_announce_version(),
                          lp_minor_announce_version(),
@@ -69,7 +69,7 @@ static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
        DEBUG(5,("wks_query_info: %d\n", __LINE__));
 
        create_wks_info_100(&wks100);
-       make_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
+       init_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
 
        /* store the response in the SMB stream */
        wks_io_r_query_info("", &r_u, rdata, 0);
@@ -80,7 +80,7 @@ static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
 /*******************************************************************
  api_wks_query_info
  ********************************************************************/
-static void api_wks_query_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_wks_query_info( uint16 vuid, prs_struct *data,
                                     prs_struct *rdata )
 {
        WKS_Q_QUERY_INFO q_u;
@@ -90,6 +90,8 @@ static void api_wks_query_info( rpcsrv_struct *p, prs_struct *data,
 
        /* construct reply.  always indicate success */
        wks_reply_query_info(&q_u, rdata, 0x0);
+
+       return True;
 }
 
 
@@ -105,7 +107,7 @@ struct api_struct api_wks_cmds[] =
 /*******************************************************************
  receives a wkssvc pipe and responds.
  ********************************************************************/
-BOOL api_wkssvc_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data)
 {
        return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds, data);
 }
index effcecd0edd4d645952a58315cff9bd309ee601d..731eda4437d911e8df649fb7fa512acb4122041c 100644 (file)
@@ -2,8 +2,8 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    NT Domain Authentication SMB / MSRPC client
-   Copyright (C) Andrew Tridgell 1994-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    
    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
@@ -21,6 +21,7 @@
 */
 
 
+
 #ifdef SYSLOG
 #undef SYSLOG
 #endif
@@ -32,73 +33,18 @@ extern int DEBUGLEVEL;
 
 #define DEBUG_TESTING
 
-extern FILE* out_hnd;
-
-/****************************************************************************
-nt enumerate trusted domains
-****************************************************************************/
-void cmd_lsa_enum_trust_dom(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       uint32 num_doms = 0;
-       char **domains = NULL;
-       DOM_SID **sids = NULL;
-       uint32 enum_ctx = 0;
-       POLICY_HND lsa_pol;
-
-       BOOL res = True;
+extern struct cli_state *smb_cli;
+extern int smb_tidx;
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       DEBUG(4,("cmd_lsa_enum_trust_dom: server:%s\n", srv_name));
-
-       /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy( srv_name,
-                               &lsa_pol, False) : False;
-
-       do
-       {
-               /* send enum trusted domains query */
-               res = res ? lsa_enum_trust_dom( &lsa_pol,
-                                         &enum_ctx,
-                                         &num_doms, &domains, &sids) : False;
-
-       } while (res && enum_ctx != 0);
-
-       res = res ? lsa_close(&lsa_pol) : False;
-
-       if (res)
-       {
-               uint32 i;
-               DEBUG(5,("cmd_lsa_enum_trust_dom: query succeeded\n"));
-
-               report(out_hnd, "LSA Enumerate Trusted Domains\n");
-               for (i = 0; i < num_doms; i++)
-               {
-                       fstring sid;
-                       sid_to_string(sid, sids[i]);
-                       report(out_hnd, "Domain:\t%s\tSID:\t%s\n",
-                             domains[i], sid);
-               }
-       }
-       else
-       {
-               DEBUG(5,("cmd_lsa_enum_trust_dom: query failed\n"));
-       }
+extern FILE* out_hnd;
 
-       free_char_array(num_doms, domains);
-       free_sid_array(num_doms, sids);
-}
 
 /****************************************************************************
 nt lsa query
 ****************************************************************************/
-void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[])
+void cmd_lsa_query_info(struct client_info *info)
 {
        fstring srv_name;
-       POLICY_HND lsa_pol;
 
        BOOL res = True;
 
@@ -108,26 +54,37 @@ void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[])
        ZERO_STRUCT(info->dom.level5_sid);
 
        fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
+       fstrcat(srv_name, info->myhostname);
        strupper(srv_name);
 
        DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name));
 
+       DEBUG(5, ("cmd_lsa_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open LSARPC session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
+
        /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy( srv_name,
-                               &lsa_pol, False) : False;
+       res = res ? do_lsa_open_policy(smb_cli,
+                               srv_name,
+                               &info->dom.lsa_info_pol, False) : False;
 
        /* send client info query, level 3.  receive domain name and sid */
-       res = res ? lsa_query_info_pol( &lsa_pol, 0x03,
+       res = res ? do_lsa_query_info_pol(smb_cli, 
+                                         &info->dom.lsa_info_pol, 0x03,
                                          info->dom.level3_dom,
                                          &info->dom.level3_sid) : False;
 
        /* send client info query, level 5.  receive domain name and sid */
-       res = res ? lsa_query_info_pol( &lsa_pol, 0x05,
+       res = res ? do_lsa_query_info_pol(smb_cli,
+                               &info->dom.lsa_info_pol, 0x05,
                                info->dom.level5_dom,
                                &info->dom.level5_sid) : False;
 
-       res = res ? lsa_close(&lsa_pol) : False;
+       res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
@@ -135,25 +92,25 @@ void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[])
                fstring sid;
                DEBUG(5,("cmd_lsa_query_info: query succeeded\n"));
 
-               report(out_hnd, "LSA Query Info Policy\n");
+               fprintf(out_hnd, "LSA Query Info Policy\n");
 
                if (info->dom.level3_dom[0] != 0)
                {
                        sid_to_string(sid, &info->dom.level3_sid);
-                       report(out_hnd, "Domain Member     - Domain: %s SID: %s\n",
+                       fprintf(out_hnd, "Domain Member     - Domain: %s SID: %s\n",
                                info->dom.level3_dom, sid);
                        domain_something = True;
                }
                if (info->dom.level5_dom[0] != 0)
                {
                        sid_to_string(sid, &info->dom.level5_sid);
-                       report(out_hnd, "Domain Controller - Domain: %s SID: %s\n",
+                       fprintf(out_hnd, "Domain Controller - Domain: %s SID: %s\n",
                                info->dom.level5_dom, sid);
                        domain_something = True;
                }
                if (!domain_something)
                {
-                       report(out_hnd, "%s is not a Domain Member or Controller\n",
+                       fprintf(out_hnd, "%s is not a Domain Member or Controller\n",
                            info->dest_host);
                }
        }
@@ -164,111 +121,33 @@ void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[])
 }
 
 /****************************************************************************
-lookup names
+nt lsa query
 ****************************************************************************/
-void cmd_lsa_lookup_names(struct client_info *info, int argc, char *argv[])
+void cmd_lsa_lookup_sids(struct client_info *info)
 {
-       POLICY_HND lsa_pol;
        fstring temp;
        int i;
+       fstring sid_name;
        fstring srv_name;
-       int num_names = 0;
-       char **names;
-       DOM_SID *sids = NULL;
-       int num_sids = 0;
-#if 0
        DOM_SID sid[10];
        DOM_SID *sids[10];
-#endif
-       BOOL res = True;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       DEBUG(4,("cmd_lsa_lookup_names: server: %s\n", srv_name));
-
-       argc--;
-       argv++;
-
-       num_names = argc;
-       names = argv;
-
-       if (num_names <= 0)
-       {
-               report(out_hnd, "lookupnames <name> [<name> ...]\n");
-               return;
-       }
-
-       /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy( srv_name,
-                               &lsa_pol, True) : False;
-
-       /* send lsa lookup sids call */
-       res = res ? lsa_lookup_names( &lsa_pol,
-                                      num_names, names,
-                                      &sids, NULL, &num_sids) : False;
-
-       res = res ? lsa_close(&lsa_pol) : False;
-
-       if (res)
-       {
-               DEBUG(5,("cmd_lsa_lookup_names: query succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_lsa_lookup_names: query failed\n"));
-       }
-
-       if (sids != NULL)
-       {
-               report(out_hnd, "Lookup Names:\n");
-               for (i = 0; i < num_sids; i++)
-               {
-                       sid_to_string(temp, &sids[i]);
-                       report(out_hnd, "SID: %s -> %s\n", names[i], temp);
-#if 0
-                       if (sids[i] != NULL)
-                       {
-                               free(sids[i]);
-                       }
-#endif
-               }
-               free(sids);
-       }
-}
-
-/****************************************************************************
-lookup sids
-****************************************************************************/
-void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[])
-{
-       POLICY_HND lsa_pol;
-       int i;
-       pstring sid_name;
-       fstring srv_name;
-       DOM_SID **sids = NULL;
-       uint32 num_sids = 0;
+       int num_sids = 0;
        char **names = NULL;
        int num_names = 0;
 
        BOOL res = True;
 
        fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
+       fstrcat(srv_name, info->myhostname);
        strupper(srv_name);
 
        DEBUG(4,("cmd_lsa_lookup_sids: server: %s\n", srv_name));
 
-       argv++;
-       argc--;
-
-       while (argc > 0)
+       while (num_sids < 10 && next_token(NULL, temp, NULL, sizeof(temp)))
        {
-               DOM_SID sid;
-               if (strnequal("S-", argv[0], 2))
+               if (strnequal("S-", temp, 2))
                {
-                       fstrcpy(sid_name, argv[0]);
+                       fstrcpy(sid_name, temp);
                }
                else
                {
@@ -276,37 +155,42 @@ void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[])
 
                        if (sid_name[0] == 0)
                        {
-                               report(out_hnd, "please use lsaquery first or specify a complete SID\n");
+                               fprintf(out_hnd, "please use lsaquery first or specify a complete SID\n");
                                return;
                        }
                                
                        fstrcat(sid_name, "-");
-                       fstrcat(sid_name, argv[0]);
+                       fstrcat(sid_name, temp);
                }
-               string_to_sid(&sid, sid_name);
-               
-               add_sid_to_array(&num_sids, &sids, &sid);
-
-               argc--;
-               argv++;
+               init_dom_sid(&sid[num_sids], sid_name);
+               sids[num_sids] = &sid[num_sids];
+               num_sids++;
        }
 
        if (num_sids == 0)
        {
-               report(out_hnd, "lookupsid RID or SID\n");
+               fprintf(out_hnd, "lookupsid RID or SID\n");
                return;
        }
 
+       /* open LSARPC session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
+
        /* lookup domain controller; receive a policy handle */
-       res = res ? lsa_open_policy( srv_name,
-                               &lsa_pol, True) : False;
+       res = res ? do_lsa_open_policy(smb_cli,
+                               srv_name,
+                               &info->dom.lsa_info_pol, True) : False;
 
        /* send lsa lookup sids call */
-       res = res ? lsa_lookup_sids( &lsa_pol,
+       res = res ? do_lsa_lookup_sids(smb_cli, 
+                                      &info->dom.lsa_info_pol,
                                       num_sids, sids,
-                                      &names, NULL, &num_names) : False;
+                                      &names, &num_names) : False;
 
-       res = res ? lsa_close(&lsa_pol) : False;
+       res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
@@ -318,12 +202,11 @@ void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[])
        }
        if (names != NULL)
        {
-               report(out_hnd, "Lookup SIDS:\n");
+               fprintf(out_hnd,"Lookup SIDS:\n");
                for (i = 0; i < num_names; i++)
                {
-                       fstring temp;
                        sid_to_string(temp, sids[i]);
-                       report(out_hnd, "SID: %s -> %s\n", temp, names[i]);
+                       fprintf(out_hnd, "SID: %s -> %s\n", temp, names[i]);
                        if (names[i] != NULL)
                        {
                                free(names[i]);
@@ -331,47 +214,5 @@ void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[])
                }
                free(names);
        }
-
-       free_sid_array(num_sids, sids);
-}
-
-/****************************************************************************
-nt lsa query
-****************************************************************************/
-void cmd_lsa_query_secret(struct client_info *info, int argc, char *argv[])
-{
-       char *secret_name;
-       STRING2 secret;
-       NTTIME last_update;
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc > 2)
-       {
-               report(out_hnd, "querysecret <secret name>\n");
-               return;
-       }
-
-       secret_name = argv[1];
-
-       if (msrpc_lsa_query_secret(srv_name, secret_name, &secret, &last_update))
-       {
-               int i;
-               report(out_hnd, "\tValue       : ");
-               for (i = 0; i < secret.str_str_len; i++)
-               {
-                       report(out_hnd, "%02X", secret.buffer[i]);
-               }
-
-               report(out_hnd, "\n\tLast Updated: %s\n\n",
-                       http_timestring(nt_time_to_unix(&last_update)));
-       }
-       else
-       {
-               report(out_hnd, "LSA Query Secret: failed\n");
-       }
 }
 
index c518fbb9f5fe0dbfcb5bdbbe0de87b04b3aa38aa..2c8514b43e8def6fbf45b513d35e87033803ab67 100644 (file)
@@ -33,7 +33,7 @@ extern int DEBUGLEVEL;
 
 #define DEBUG_TESTING
 
-extern struct ntuser_creds *usr_creds;
+extern struct cli_state *smb_cli;
 
 extern FILE* out_hnd;
 
@@ -41,32 +41,16 @@ extern FILE* out_hnd;
 /****************************************************************************
 experimental nt login.
 ****************************************************************************/
-void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[])
+void cmd_netlogon_login_test(struct client_info *info)
 {
-#if 0
        extern BOOL global_machine_password_needs_changing;
-#endif
 
        fstring nt_user_name;
        fstring password;
        BOOL res = True;
        char *nt_password;
        unsigned char trust_passwd[16];
-       fstring trust_acct;
-       fstring domain;
-       char *p;
-
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       fstrcpy(domain, usr_creds->domain);
 
-       if (domain[0] == 0)
-       {
-               fstrcpy(domain, info->dom.level3_dom);
-       }
 #if 0
        /* machine account passwords */
        pstring new_mach_pwd;
@@ -75,80 +59,46 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[])
        new_mach_pwd[0] = 0;
 #endif
 
-       argc--;
-       argv++;
-
-       if (argc < 1)
+       if (!next_token(NULL, nt_user_name, NULL, sizeof(nt_user_name)))
        {
-               fstrcpy(nt_user_name, usr_creds->user_name);
+               fstrcpy(nt_user_name, smb_cli->user_name);
                if (nt_user_name[0] == 0)
                {
-                       report(out_hnd,"ntlogin: must specify username with anonymous connection\n");
-                       report(out_hnd,"ntlogin [[DOMAIN\\]user] [password]\n");
+                       fprintf(out_hnd,"ntlogin: must specify username with anonymous connection\n");
                        return;
                }
        }
-       else
-       {
-               fstrcpy(nt_user_name, argv[0]);
-       }
-
-       p = strchr(nt_user_name, '\\');
-       if (p != NULL)
-       {
-               fstrcpy(domain, nt_user_name);
-               p = strchr(domain, '\\');
-               if (p != NULL)
-               {
-                       *p = 0;
-                       fstrcpy(nt_user_name, p+1);
-               }
-               
-       }
 
-       if (domain[0] == 0)
+       if (next_token(NULL, password, NULL, sizeof(password)))
        {
-               report(out_hnd,"no domain specified.\n");
-       }
-
-       argc--;
-       argv++;
-
-       if (argc > 0)
-       {
-               nt_password = argv[0];
+               nt_password = password;
        }
        else
        {
                nt_password = getpass("Enter NT Login password:");
        }
 
-       DEBUG(5,("do_nt_login_test: username %s from: %s\n",
-                   nt_user_name, info->myhostname));
+       DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name));
 
-       fstrcpy(trust_acct, info->myhostname);
-       fstrcat(trust_acct, "$");
-
-       res = res ? trust_get_passwd(trust_passwd, domain, info->myhostname) : False;
+       res = res ? trust_get_passwd(trust_passwd, smb_cli->domain, info->myhostname) : False;
 
 #if 0
        /* check whether the user wants to change their machine password */
        res = res ? trust_account_check(info->dest_ip, info->dest_host,
-                                       info->myhostname, usr_creds->domain,
+                                       info->myhostname, smb_cli->domain,
                                        info->mach_acct, new_mach_pwd) : False;
 #endif
+       /* open NETLOGON session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON) : False;
 
-       res = res ? cli_nt_setup_creds(srv_name, info->myhostname,
-                                      trust_acct, 
-                                      trust_passwd, SEC_CHAN_WKSTA) == 0x0 : False;
+       res = res ? cli_nt_setup_creds(smb_cli, trust_passwd) : False;
 
-#if 0
        /* change the machine password? */
        if (global_machine_password_needs_changing)
        {
                unsigned char new_trust_passwd[16];
                generate_random_buffer(new_trust_passwd, 16, True);
-               res = res ? cli_nt_srv_pwset(srv_name, info->myhostname, new_trust_passwd, SEC_CHAN_WKSTA) : False;
+               res = res ? cli_nt_srv_pwset(smb_cli, new_trust_passwd) : False;
 
                if (res)
                {
@@ -157,102 +107,27 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[])
 
                memset(new_trust_passwd, 0, 16);
        }
-#endif
 
        memset(trust_passwd, 0, 16);
 
        /* do an NT login */
-       res = res ? cli_nt_login_interactive(srv_name, info->myhostname,
-                        usr_creds->domain, nt_user_name,
+       res = res ? cli_nt_login_interactive(smb_cli,
+                        smb_cli->domain, nt_user_name,
                         getuid(), nt_password,
                         &info->dom.ctr, &info->dom.user_info3) : False;
 
        /*** clear out the password ***/
        memset(password, 0, sizeof(password));
 
-#if 0
        /* ok!  you're logged in!  do anything you like, then... */
 
        /* do an NT logout */
-       res = res ? cli_nt_logoff(srv_name, info->myhostname, &info->dom.ctr) : False;
-#endif
+       res = res ? cli_nt_logoff(smb_cli, &info->dom.ctr) : False;
 
-       report(out_hnd,"cmd_nt_login: login (%s) test succeeded: %s\n",
-               nt_user_name, BOOLSTR(res));
-}
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
-/****************************************************************************
-experimental nt login.
-****************************************************************************/
-void cmd_netlogon_domain_test(struct client_info *info, int argc, char *argv[])
-{
-       char *nt_trust_dom;
-       BOOL res = True;
-       unsigned char trust_passwd[16];
-       fstring inter_dom_acct;
-
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd,"domtest: must specify domain name\n");
-               return;
-       }
-
-       nt_trust_dom = argv[1];
-
-       DEBUG(5,("do_nt_login_test: domain %s\n", nt_trust_dom));
-
-       fstrcpy(inter_dom_acct, nt_trust_dom);
-       fstrcat(inter_dom_acct, "$");
-
-       res = res ? trust_get_passwd(trust_passwd, usr_creds->domain, nt_trust_dom) : False;
-
-       res = res ? cli_nt_setup_creds(srv_name,
-                                      info->myhostname, inter_dom_acct,
-                                      trust_passwd, 
-                                      SEC_CHAN_DOMAIN) == 0x0 : False;
-
-       memset(trust_passwd, 0, 16);
-
-       report(out_hnd,"cmd_nt_login: credentials (%s) test succeeded: %s\n",
-               nt_trust_dom, BOOLSTR(res));
+       fprintf(out_hnd,"cmd_nt_login: login (%s) test succeeded: %s\n",
+               nt_user_name, BOOLSTR(res));
 }
 
-/****************************************************************************
-experimental SAM synchronisation.
-****************************************************************************/
-void cmd_sam_sync(struct client_info *info, int argc, char *argv[])
-{
-       SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS];
-       SAM_DELTA_CTR deltas[MAX_SAM_DELTAS];
-       uint32 num;
-       uchar trust_passwd[16];
-       fstring srv_name;
-       fstring trust_acct;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       fstrcpy(trust_acct, info->myhostname);
-       fstrcat(trust_acct, "$");
-
-       if (!trust_get_passwd(trust_passwd, usr_creds->domain, info->myhostname))
-       {
-               report(out_hnd, "cmd_sam_sync: no trust account password\n");
-               return;
-       }
-
-       if (net_sam_sync(srv_name, info->myhostname,
-               trust_acct, trust_passwd,
-           hdr_deltas, deltas, &num))
-       {
-               display_sam_sync(out_hnd, ACTION_HEADER   , hdr_deltas, deltas, num);
-               display_sam_sync(out_hnd, ACTION_ENUMERATE, hdr_deltas, deltas, num);
-               display_sam_sync(out_hnd, ACTION_FOOTER   , hdr_deltas, deltas, num);
-       }
-}
index 275db6e12be0b53d033336e6c14bb010419ac8ee..fcc12c530cc62258637602a543748daa211c7cb4 100644 (file)
@@ -2,8 +2,8 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    NT Domain Authentication SMB / MSRPC client
-   Copyright (C) Andrew Tridgell 1994-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    
    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
 
 extern int DEBUGLEVEL;
 
+extern struct cli_state *smb_cli;
+extern int smb_tidx;
+
 extern FILE* out_hnd;
 
 /*
  * keys.  of the form:
  * ----
  *
- * [HKLM]|[HKU]|[HKCR]\[parent_keyname]\[subkey]|[value]
+ * [HKLM]|[HKU]\[parent_keyname_components]\[subkey]|[value]
  *
  * reg_getsubkey() splits this down into:
- * [HKLM]|[HKU]|[HKCR]\[parent_keyname_components] and [subkey]|[value]
+ * [HKLM]|[HKU]\[parent_keyname_components] and [subkey]|[value]
  *
- * reg_connect() splits the left side down further into:
- * [HKLM]|[HKU]|[HKCR] and [parent_keyname_components].
+ * do_reg_connect() splits the left side down further into:
+ * [HKLM]|[HKU] and [parent_keyname_components].
  *
  * HKLM is short for HKEY_LOCAL_MACHINE
- * HKCR is short for HKEY_CLASSES_ROOT
  * HKU  is short for HKEY_USERS
  *
  * oh, and HKEY stands for "Hive Key".
  *
  */
 
-static void reg_display_key(int val, const char *full_keyname, int num)
-{
-       switch (val)
-       {
-               case 0:
-               {
-                       /* initialsation */
-                       report(out_hnd, "Key Name:\t%s\n", full_keyname);
-                       break;
-               }
-               case 1:
-               {
-                       /* subkeys initialisation */
-                       if (num > 0)
-                       {
-                               report(out_hnd,"Subkeys\n");
-                               report(out_hnd,"-------\n");
-                       }
-                       break;
-               }
-               case 2:
-               {
-                       /* values initialisation */
-                       if (num > 0)
-                       {
-                               report(out_hnd,"Key Values\n");
-                               report(out_hnd,"----------\n");
-                       }
-                       break;
-               }
-               case 3:
-               {
-                       /* clean-up */
-                       break;
-               }
-               default:
-               {
-                       break;
-               }
-       }
-}
-
-void split_server_keyname(char *srv_name, char *key, const char* arg)
-{
-       pstrcpy(key, arg);
-
-       if (strnequal("\\\\", key, 2))
-       {
-               char *p = strchr(&key[2], '\\');
-               if (p == NULL)
-               {
-                       key[0] = 0;
-                       return;
-               }
-
-               *p = 0;
-
-               fstrcpy(srv_name, key);
-               pstrcpy(key, &arg[strlen(srv_name)+1]);
-       }
-}
-
 /****************************************************************************
 nt registry enum
 ****************************************************************************/
-BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
-                               REG_FN(reg_fn),
-                               REG_KEY_FN(reg_key_fn),
-                               REG_VAL_FN(reg_val_fn))
+void cmd_reg_enum(struct client_info *info)
 {
        BOOL res = True;
        BOOL res1 = True;
@@ -129,7 +66,7 @@ BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
        int i;
 
        POLICY_HND key_pol;
-       POLICY_HND pol_con;
+       fstring full_keyname;
        fstring key_name;
 
        /*
@@ -153,36 +90,46 @@ BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
 
        uint32 unk_1a_response;
 
-       DEBUG(5, ("reg_enum_key: %s\n", full_keyname));
+       DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
+
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+       {
+               fprintf(out_hnd, "regenum <key_name>\n");
+               return;
+       }
+
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
 
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, full_keyname, key_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*key_name) != 0)
        {
                /* open an entry */
-               res1 = res  ? reg_open_entry(&pol_con,
+               res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         key_name, 0x02000000, &key_pol) : False;
        }
        else
        {
-               memcpy(&key_pol, &pol_con, sizeof(key_pol));
+               memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
        }
 
-       res1 = res1 ? reg_query_key(&key_pol,
+       res1 = res1 ? do_reg_query_key(smb_cli,
+                               &key_pol,
                                key_class, &max_class_len,
                                &num_subkeys, &max_subkeylen, &max_subkeysize,
                                &num_values, &max_valnamelen, &max_valbufsize,
                                &sec_desc, &mod_time) : False;
 
-       if (res1 && reg_fn != NULL)
+       if (res1 && num_subkeys > 0)
        {
-               reg_fn(0, full_keyname, 0);
-               reg_fn(1, full_keyname, num_subkeys);
+               fprintf(out_hnd,"Subkeys\n");
+               fprintf(out_hnd,"-------\n");
        }
 
-       for (i = 0; i < num_subkeys && reg_key_fn != NULL; i++)
+       for (i = 0; i < num_subkeys; i++)
        {
                /*
                 * enumerate key
@@ -194,33 +141,36 @@ BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
                time_t key_mod_time;
 
                /* unknown 1a it */
-               res2 = res1 ? reg_unknown_1a(&key_pol,
+               res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
                                        &unk_1a_response) : False;
 
                if (res2 && unk_1a_response != 5)
                {
-                       report(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+                       fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
                }
 
                /* enum key */
-               res2 = res2 ? reg_enum_key(&key_pol,
+               res2 = res2 ? do_reg_enum_key(smb_cli, &key_pol,
                                        i, enum_name,
                                        &enum_unk1, &enum_unk2,
                                        &key_mod_time) : False;
                
                if (res2)
                {
-                       reg_key_fn(full_keyname, enum_name, key_mod_time);
+                       display_reg_key_info(out_hnd, ACTION_HEADER   , enum_name, key_mod_time);
+                       display_reg_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time);
+                       display_reg_key_info(out_hnd, ACTION_FOOTER   , enum_name, key_mod_time);
                }
 
        }
 
-       if (reg_fn != NULL)
+       if (num_values > 0)
        {
-               reg_fn(2, full_keyname, num_values);
+               fprintf(out_hnd,"Key Values\n");
+               fprintf(out_hnd,"----------\n");
        }
 
-       for (i = 0; i < num_values && reg_val_fn != NULL; i++)
+       for (i = 0; i < num_values; i++)
        {
                /*
                 * enumerate key
@@ -231,191 +181,57 @@ BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
                fstring val_name;
 
                /* unknown 1a it */
-               res2 = res1 ? reg_unknown_1a(&key_pol,
+               res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
                                        &unk_1a_response) : False;
 
                if (res2 && unk_1a_response != 5)
                {
-                       report(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+                       fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
                }
 
                /* enum key */
-               res2 = res2 ? reg_enum_val(&key_pol,
+               res2 = res2 ? do_reg_enum_val(smb_cli, &key_pol,
                                        i, max_valnamelen, max_valbufsize,
                                        val_name, &val_type, &value) : False;
                
                if (res2)
                {
-                       reg_val_fn(full_keyname, val_name, val_type, &value);
+                       display_reg_value_info(out_hnd, ACTION_HEADER   , val_name, val_type, &value);
+                       display_reg_value_info(out_hnd, ACTION_ENUMERATE, val_name, val_type, &value);
+                       display_reg_value_info(out_hnd, ACTION_FOOTER   , val_name, val_type, &value);
                }
        }
 
-       if (res1 && reg_fn != NULL)
-       {
-               reg_fn(3, full_keyname, 0);
-       }
-
        /* close the handles */
        if ((*key_name) != 0)
        {
-               res1 = res1 ? reg_close(&key_pol) : False;
+               res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
        }
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
 
-       if (res && res1 && res2)
-       {
-               DEBUG(5,("msrpc_reg_enum_key: query succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("msrpc_reg_enum_key: query failed\n"));
-       }
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
-       return res1;
-}
-
-static void reg_display_key_info(const char *full_name,
-                               const char *name, time_t key_mod_time)
-{
-       display_reg_key_info(out_hnd, ACTION_HEADER   , name, key_mod_time);
-       display_reg_key_info(out_hnd, ACTION_ENUMERATE, name, key_mod_time);
-       display_reg_key_info(out_hnd, ACTION_FOOTER   , name, key_mod_time);
-}
-
-static void reg_display_val_info(const char *full_name,
-                               const char* name,
-                               uint32 type,
-                               const BUFFER2 *const value)
-{
-       display_reg_value_info(out_hnd, ACTION_HEADER   , name, type, value);
-       display_reg_value_info(out_hnd, ACTION_ENUMERATE, name, type, value);
-       display_reg_value_info(out_hnd, ACTION_FOOTER   , name, type, value);
-}
-
-/****************************************************************************
-nt registry enum
-****************************************************************************/
-void cmd_reg_enum(struct client_info *info, int argc, char *argv[])
-{
-       pstring full_keyname;
-
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd, "regenum <key_name>\n");
-               return;
-       }
-
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
-       (void)(msrpc_reg_enum_key(srv_name, full_keyname,
-                               reg_display_key,
-                               reg_display_key_info,
-                               reg_display_val_info));
-}
-
-/****************************************************************************
-nt registry query value info
-****************************************************************************/
-void cmd_reg_query_info(struct client_info *info, int argc, char *argv[])
-{
-       BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-
-       POLICY_HND key_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
-       fstring key_name;
-       fstring keyname;
-       fstring val_name;
-
-       /*
-        * query value info
-        */
-
-       BUFFER2 buf;
-       uint32 type;
-
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd, "regvalinfo value_name\n");
-               return;
-       }
-
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
-       reg_get_subkey(full_keyname, keyname, val_name);
-
-       if (keyname[0] == 0 || val_name[0] == 0)
-       {
-               report(out_hnd, "invalid value name\n");
-               return;
-       }
-       
-       /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, keyname, key_name,
-                               &pol_con) : False;
-
-       if ((*key_name) != 0)
-       {
-               /* open an entry */
-               res1 = res  ? reg_open_entry(&pol_con,
-                                key_name, 0x02000000, &key_pol) : False;
-       }
-       else
-       {
-               memcpy(&key_pol, &pol_con, sizeof(key_pol));
-       }
-
-       /* query it */
-       res2 = res1 ? reg_query_info(&key_pol,
-                               val_name, &type, &buf) : False;
-
-       if (res2)
-       {
-               reg_display_val_info(full_keyname, val_name, type, &buf);
-       }
-
-       /* close the handles */
-       if ((*key_name) != 0)
-       {
-               res1 = res1 ? reg_close(&key_pol) : False;
-       }
-       res  = res  ? reg_close(&pol_con) : False;
-
-       if (res2)
+       if (res && res1 && res2)
        {
-               DEBUG(5,("cmd_reg_query: query succeeded\n"));
+               DEBUG(5,("cmd_reg_enum: query succeeded\n"));
        }
        else
        {
-               DEBUG(5,("cmd_reg_query: query failed\n"));
+               DEBUG(5,("cmd_reg_enum: query failed\n"));
        }
 }
 
 /****************************************************************************
 nt registry query key
 ****************************************************************************/
-void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
+void cmd_reg_query_key(struct client_info *info)
 {
        BOOL res = True;
        BOOL res1 = True;
 
        POLICY_HND key_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring key_name;
 
        /*
@@ -433,36 +249,34 @@ void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
        uint32 sec_desc;
        NTTIME mod_time;
 
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
 
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regquery key_name\n");
+               fprintf(out_hnd, "regquery key_name\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
 
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, full_keyname, key_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*key_name) != 0)
        {
                /* open an entry */
-               res1 = res  ? reg_open_entry(&pol_con,
+               res1 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         key_name, 0x02000000, &key_pol) : False;
        }
        else
        {
-               memcpy(&key_pol, &pol_con, sizeof(key_pol));
+               memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
        }
 
-       res1 = res1 ? reg_query_key(&key_pol,
+       res1 = res1 ? do_reg_query_key(smb_cli,
+                               &key_pol,
                                key_class, &key_class_len,
                                &num_subkeys, &max_subkeylen, &max_subkeysize,
                                &num_values, &max_valnamelen, &max_valbufsize,
@@ -470,7 +284,8 @@ void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
 
        if (res1 && key_class_len != 0)
        {
-               res1 = res1 ? reg_query_key(&key_pol,
+               res1 = res1 ? do_reg_query_key(smb_cli,
+                               &key_pol,
                                key_class, &key_class_len,
                                &num_subkeys, &max_subkeylen, &max_subkeysize,
                                &num_values, &max_valnamelen, &max_valbufsize,
@@ -479,20 +294,23 @@ void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
 
        if (res1)
        {
-               report(out_hnd,"Registry Query Info Key\n");
-               report(out_hnd,"key class: %s\n", key_class);
-               report(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
-               report(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
-               report(out_hnd,"sec desc: 0x%x\n", sec_desc);
-               report(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
+               fprintf(out_hnd,"Registry Query Info Key\n");
+               fprintf(out_hnd,"key class: %s\n", key_class);
+               fprintf(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
+               fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
+               fprintf(out_hnd,"sec desc: 0x%x\n", sec_desc);
+               fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
        }
 
        /* close the handles */
        if ((*key_name) != 0)
        {
-               res1 = res1 ? reg_close(&key_pol) : False;
+               res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
        }
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res1)
        {
@@ -507,18 +325,18 @@ void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry create value
 ****************************************************************************/
-void cmd_reg_create_val(struct client_info *info, int argc, char *argv[])
+void cmd_reg_create_val(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
        BOOL res4 = True;
 
        POLICY_HND parent_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring keyname;
        fstring parent_name;
        fstring val_name;
+       fstring tmp;
        uint32 val_type;
        BUFFER3 value;
 
@@ -526,75 +344,75 @@ void cmd_reg_create_val(struct client_info *info, int argc, char *argv[])
        uint32 unk_0;
        uint32 unk_1;
        /* query it */
-       res1 = res1 ? reg_query_info(&val_pol,
+       res1 = res1 ? do_reg_query_info(smb_cli, &val_pol,
                                type, &unk_0, &unk_1) : False;
 #endif
 
-       fstring srv_name;
+       DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli->fd));
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 4)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regcreate <val_name> <val_type (1|3|4)> <val>\n");
-               report(out_hnd, "(val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
+               fprintf(out_hnd, "regcreate <val_name> <val_type> <val>\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
        reg_get_subkey(full_keyname, keyname, val_name);
 
-       argc--;
-       argv++;
-
        if (keyname[0] == 0 || val_name[0] == 0)
        {
-               report(out_hnd, "invalid key name\n");
+               fprintf(out_hnd, "invalid key name\n");
                return;
        }
        
-       if (argc < 2)
+       if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
+               fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
                return;
        }
 
-       argc--;
-       argv++;
-
-       val_type = atoi(argv[0]);
+       val_type = atoi(tmp);
 
        if (val_type != 1 && val_type != 3 && val_type != 4)
        {
-               report(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
+               fprintf(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
                return;
        }
 
-       argc--;
-       argv++;
+       if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
+               return;
+       }
 
        switch (val_type)
        {
                case 0x01: /* UNISTR */
                {
-                       make_buffer3_str(&value, argv[0], strlen(argv[0])+1);
+                       init_buffer3_str(&value, tmp, strlen(tmp)+1);
                        break;
                }
                case 0x03: /* BYTES */
                {
-                       make_buffer3_hex(&value, argv[0]);
+                       init_buffer3_hex(&value, tmp);
                        break;
                }
                case 0x04: /* DWORD */
                {
-                       make_buffer3_uint32(&value, get_number(argv[0]));
+                       uint32 tmp_val;
+                       if (strnequal(tmp, "0x", 2))
+                       {
+                               tmp_val = strtol(tmp, (char**)NULL, 16);
+                       }
+                       else
+                       {
+                               tmp_val = strtol(tmp, (char**)NULL, 10);
+                       }
+                       init_buffer3_uint32(&value, tmp_val);
                        break;
                }
                default:
                {
-                       report(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
+                       fprintf(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
                        return;
                }
        }
@@ -602,41 +420,47 @@ void cmd_reg_create_val(struct client_info *info, int argc, char *argv[])
        DEBUG(10,("key data:\n"));
        dump_data(10, (char *)value.buffer, value.buf_len);
 
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, keyname, parent_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, keyname, parent_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*val_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         parent_name, 0x02000000, &parent_pol) : False;
        }
        else
        {
-               memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
+               memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
        }
 
        /* create an entry */
-       res4 = res3 ? reg_create_val(&parent_pol,
+       res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
                                 val_name, val_type, &value) : False;
 
        /* flush the modified key */
-       res4 = res4 ? reg_flush_key(&parent_pol) : False;
+       res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
 
        /* close the val handle */
        if ((*val_name) != 0)
        {
-               res3 = res3 ? reg_close(&parent_pol) : False;
+               res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
        }
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
                DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
-               report(out_hnd,"OK\n");
+               fprintf(out_hnd,"OK\n");
        }
        else
        {
@@ -647,72 +471,71 @@ void cmd_reg_create_val(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry delete value
 ****************************************************************************/
-void cmd_reg_delete_val(struct client_info *info, int argc, char *argv[])
+void cmd_reg_delete_val(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
        BOOL res4 = True;
 
        POLICY_HND parent_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring keyname;
        fstring parent_name;
        fstring val_name;
 
-       fstring srv_name;
+       DEBUG(5, ("cmd_reg_delete_val: smb_cli->fd:%d\n", smb_cli->fd));
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regdelete <val_name>\n");
+               fprintf(out_hnd, "regdelete <val_name>\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
        reg_get_subkey(full_keyname, keyname, val_name);
 
        if (keyname[0] == 0 || val_name[0] == 0)
        {
-               report(out_hnd, "invalid key name\n");
+               fprintf(out_hnd, "invalid key name\n");
                return;
        }
        
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, keyname, parent_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, keyname, parent_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*val_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         parent_name, 0x02000000, &parent_pol) : False;
        }
        else
        {
-               memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
+               memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
        }
 
        /* delete an entry */
-       res4 = res3 ? reg_delete_val(&parent_pol, val_name) : False;
+       res4 = res3 ? do_reg_delete_val(smb_cli, &parent_pol, val_name) : False;
 
        /* flush the modified key */
-       res4 = res4 ? reg_flush_key(&parent_pol) : False;
+       res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
 
        /* close the key handle */
-       res3 = res3 ? reg_close(&parent_pol) : False;
+       res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
                DEBUG(5,("cmd_reg_delete_val: query succeeded\n"));
-               report(out_hnd,"OK\n");
+               fprintf(out_hnd,"OK\n");
        }
        else
        {
@@ -723,75 +546,74 @@ void cmd_reg_delete_val(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry delete key
 ****************************************************************************/
-void cmd_reg_delete_key(struct client_info *info, int argc, char *argv[])
+void cmd_reg_delete_key(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
        BOOL res4 = True;
 
        POLICY_HND parent_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring parent_name;
        fstring key_name;
        fstring subkey_name;
 
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       DEBUG(5, ("cmd_reg_delete_key: smb_cli->fd:%d\n", smb_cli->fd));
 
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regdeletekey <key_name>\n");
+               fprintf(out_hnd, "regdeletekey <key_name>\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
        reg_get_subkey(full_keyname, parent_name, subkey_name);
 
        if (parent_name[0] == 0 || subkey_name[0] == 0)
        {
-               report(out_hnd, "invalid key name\n");
+               fprintf(out_hnd, "invalid key name\n");
                return;
        }
        
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, parent_name, key_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, parent_name, key_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*key_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         key_name, 0x02000000, &parent_pol) : False;
        }
        else
        {
-               memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
+               memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
        }
 
        /* create an entry */
-       res4 = res3 ? reg_delete_key(&parent_pol, subkey_name) : False;
+       res4 = res3 ? do_reg_delete_key(smb_cli, &parent_pol, subkey_name) : False;
 
        /* flush the modified key */
-       res4 = res4 ? reg_flush_key(&parent_pol) : False;
+       res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
 
        /* close the key handle */
        if ((*key_name) != 0)
        {
-               res3 = res3 ? reg_close(&parent_pol) : False;
+               res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
        }
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
                DEBUG(5,("cmd_reg_delete_key: query succeeded\n"));
-               report(out_hnd,"OK\n");
+               fprintf(out_hnd,"OK\n");
        }
        else
        {
@@ -802,7 +624,7 @@ void cmd_reg_delete_key(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry create key
 ****************************************************************************/
-void cmd_reg_create_key(struct client_info *info, int argc, char *argv[])
+void cmd_reg_create_key(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
@@ -810,41 +632,30 @@ void cmd_reg_create_key(struct client_info *info, int argc, char *argv[])
 
        POLICY_HND parent_pol;
        POLICY_HND key_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring parent_key;
        fstring parent_name;
        fstring key_name;
        fstring key_class;
        SEC_ACCESS sam_access;
 
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd));
 
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regcreate <key_name> [key_class]\n");
+               fprintf(out_hnd, "regcreate <key_name> [key_class]\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
-
        reg_get_subkey(full_keyname, parent_key, key_name);
 
        if (parent_key[0] == 0 || key_name[0] == 0)
        {
-               report(out_hnd, "invalid key name\n");
+               fprintf(out_hnd, "invalid key name\n");
                return;
        }
        
-       if (argc > 2)
-       {
-               fstrcpy(key_class, argv[2]);
-       }
-       else
+       if (!next_token(NULL, key_class, NULL, sizeof(key_class)))
        {
                memset(key_class, 0, sizeof(key_class));
        }
@@ -852,44 +663,50 @@ void cmd_reg_create_key(struct client_info *info, int argc, char *argv[])
        /* set access permissions */
        sam_access.mask = SEC_RIGHTS_READ;
 
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, parent_key, parent_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, parent_key, parent_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*parent_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         parent_name, 0x02000000, &parent_pol) : False;
        }
        else
        {
-               memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
+               memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
        }
 
        /* create an entry */
-       res4 = res3 ? reg_create_key(&parent_pol,
+       res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol,
                                 key_name, key_class, &sam_access, &key_pol) : False;
 
        /* flush the modified key */
-       res4 = res4 ? reg_flush_key(&parent_pol) : False;
+       res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
 
        /* close the key handle */
-       res4 = res4 ? reg_close(&key_pol) : False;
+       res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False;
 
        /* close the key handle */
        if ((*parent_name) != 0)
        {
-               res3 = res3 ? reg_close(&parent_pol) : False;
+               res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
        }
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
                DEBUG(5,("cmd_reg_create_key: query succeeded\n"));
-               report(out_hnd,"OK\n");
+               fprintf(out_hnd,"OK\n");
        }
        else
        {
@@ -900,15 +717,14 @@ void cmd_reg_create_key(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry security info
 ****************************************************************************/
-void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[])
+void cmd_reg_test_key_sec(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
        BOOL res4 = True;
 
        POLICY_HND key_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring key_name;
 
        /*
@@ -916,84 +732,76 @@ void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[])
         */
 
        uint32 sec_buf_size;
-       SEC_DESC_BUF sec_buf;
-       uint32 sec_info = 0x7;
-
-       fstring srv_name;
+       SEC_DESC_BUF *psdb;
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
 
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "regtestkeysec <key_name>\n");
+               fprintf(out_hnd, "reggetsec <key_name>\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
 
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, full_keyname, key_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*key_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         key_name, 0x02000000, &key_pol) : False;
        }
        else
        {
-               memcpy(&key_pol, &pol_con, sizeof(key_pol));
+               memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
        }
 
        /* open an entry */
-       res3 = res ? reg_open_entry(&pol_con,
+       res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                 key_name, 0x02000000, &key_pol) : False;
 
        /* query key sec info.  first call sets sec_buf_size. */
-       sec_buf_size = 0;
-       ZERO_STRUCT(sec_buf);
 
-       res4 = res3 ? reg_get_key_sec(&key_pol,
-                               sec_info,
-                               &sec_buf_size, &sec_buf) : False;
+       sec_buf_size = 0;
+       res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
+                               &sec_buf_size, &psdb) : False;
        
-       if (res4)
-       {
-               free_sec_desc_buf(&sec_buf);
-       }
+       free_sec_desc_buf(&psdb);
 
-       res4 = res4 ? reg_get_key_sec(&key_pol,
-                               sec_info,
-                               &sec_buf_size, &sec_buf) : False;
+       res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
+                               &sec_buf_size, &psdb) : False;
 
-       if (res4 && sec_buf.len > 0 && sec_buf.sec != NULL)
+       if (res4 && psdb->len > 0 && psdb->sec != NULL)
        {
-               display_sec_desc(out_hnd, ACTION_HEADER   , sec_buf.sec);
-               display_sec_desc(out_hnd, ACTION_ENUMERATE, sec_buf.sec);
-               display_sec_desc(out_hnd, ACTION_FOOTER   , sec_buf.sec);
-
-               res4 = res4 ? reg_set_key_sec(&key_pol,
-                               sec_info, sec_buf_size, sec_buf.sec) : False;
+               display_sec_desc(out_hnd, ACTION_HEADER   , psdb->sec);
+               display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
+               display_sec_desc(out_hnd, ACTION_FOOTER   , psdb->sec);
 
-               free_sec_desc_buf(&sec_buf);
+               res4 = res4 ? do_reg_set_key_sec(smb_cli, &key_pol, psdb) : False;
        }
 
+       free_sec_desc_buf(&psdb);
+
        /* close the key handle */
        if ((*key_name) != 0)
        {
-               res3 = res3 ? reg_close(&key_pol) : False;
+               res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
        }
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
                DEBUG(5,("cmd_reg_test2: query succeeded\n"));
-               report(out_hnd,"Registry Test2\n");
+               fprintf(out_hnd,"Registry Test2\n");
        }
        else
        {
@@ -1004,15 +812,14 @@ void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 nt registry security info
 ****************************************************************************/
-void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[])
+void cmd_reg_get_key_sec(struct client_info *info)
 {
        BOOL res = True;
        BOOL res3 = True;
        BOOL res4 = True;
 
        POLICY_HND key_pol;
-       POLICY_HND pol_con;
-       pstring full_keyname;
+       fstring full_keyname;
        fstring key_name;
 
        /*
@@ -1020,76 +827,68 @@ void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[])
         */
 
        uint32 sec_buf_size;
-       SEC_DESC_BUF sec_buf;
-       uint32 sec_info = 0x7;
-
-       fstring srv_name;
+       SEC_DESC_BUF *psdb;
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
 
-       if (argc < 2)
+       if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
        {
-               report(out_hnd, "reggetsec <key_name>\n");
+               fprintf(out_hnd, "reggetsec <key_name>\n");
                return;
        }
 
-       split_server_keyname(srv_name, full_keyname, argv[1]);
+       /* open WINREG session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
 
        /* open registry receive a policy handle */
-       res = res ? reg_connect(srv_name, full_keyname, key_name,
-                               &pol_con) : False;
+       res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
+                               &info->dom.reg_pol_connect) : False;
 
        if ((*key_name) != 0)
        {
                /* open an entry */
-               res3 = res  ? reg_open_entry(&pol_con,
+               res3 = res  ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                         key_name, 0x02000000, &key_pol) : False;
        }
        else
        {
-               memcpy(&key_pol, &pol_con, sizeof(key_pol));
+               memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
        }
 
        /* open an entry */
-       res3 = res ? reg_open_entry(&pol_con,
+       res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
                                 key_name, 0x02000000, &key_pol) : False;
 
-       /* query key sec info.  first call sets sec_buf_size. */
+       /* Get the size. */
        sec_buf_size = 0;
-       ZERO_STRUCT(sec_buf);
-
-       res4 = res3 ? reg_get_key_sec(&key_pol,
-                               sec_info,
-                               &sec_buf_size, &sec_buf) : False;
+       res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
+                               &sec_buf_size, &psdb) : False;
        
-       if (res4)
-       {
-               free_sec_desc_buf(&sec_buf);
-       }
+       free_sec_desc_buf(&psdb);
 
-       res4 = res4 ? reg_get_key_sec(&key_pol,
-                               sec_info,
-                               &sec_buf_size, &sec_buf) : False;
+       res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
+                               &sec_buf_size, &psdb) : False;
 
-       if (res4 && sec_buf.len > 0 && sec_buf.sec != NULL)
+       if (res4 && psdb->len > 0 && psdb->sec != NULL)
        {
-               display_sec_desc(out_hnd, ACTION_HEADER   , sec_buf.sec);
-               display_sec_desc(out_hnd, ACTION_ENUMERATE, sec_buf.sec);
-               display_sec_desc(out_hnd, ACTION_FOOTER   , sec_buf.sec);
-
-               free(sec_buf.sec);
+               display_sec_desc(out_hnd, ACTION_HEADER   , psdb->sec);
+               display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
+               display_sec_desc(out_hnd, ACTION_FOOTER   , psdb->sec);
        }
 
+       free_sec_desc_buf(&psdb);
+
        /* close the key handle */
        if ((*key_name) != 0)
        {
-               res3 = res3 ? reg_close(&key_pol) : False;
+               res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
        }
 
        /* close the registry handles */
-       res  = res  ? reg_close(&pol_con) : False;
+       res  = res  ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res && res3 && res4)
        {
@@ -1100,75 +899,3 @@ void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[])
                DEBUG(5,("cmd_reg_get_key_sec: query failed\n"));
        }
 }
-
-/****************************************************************************
-nt registry shutdown
-****************************************************************************/
-void cmd_reg_shutdown(struct client_info *info, int argc, char *argv[])
-{
-       BOOL res = True;
-
-       fstring msg;
-       uint32 timeout = 20;
-       uint16 flgs = 0;
-       int opt;
-
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       while ((opt = getopt(argc, argv,"fim:t:r-")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'm':
-                       {
-                               safe_strcpy(msg, optarg, sizeof(msg)-1);
-                               break;
-                       }
-                       case 't':
-                       {
-                               timeout = atoi(optarg);
-                               break;
-                       }
-                       case 'r':
-                       {
-                               flgs |= 0x100;
-                               break;
-                       }
-                       case 'f':
-                       {
-                               flgs |= 0x100;
-                               break;
-                       }
-                       case '-':
-                       {
-                               if (strequal(optarg, "-reboot"))
-                               {
-                                       flgs |= 0x100;
-                               }
-                               if (strequal(optarg, "-force-close"))
-                               {
-                                       flgs |= 0x001;
-                               }
-                               break;
-                       }
-               }
-       }
-
-       /* create an entry */
-       res = res ? reg_shutdown(srv_name, msg, timeout, flgs) : False;
-
-       if (res)
-       {
-               DEBUG(5,("cmd_reg_shutdown: query succeeded\n"));
-               report(out_hnd,"OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_reg_shutdown: query failed\n"));
-               report(out_hnd,"Failed\n");
-       }
-}
index a03393fbbda58393b029286afebab8f3f6a651cf..023bf512e8a4144d893f8ba3baf0ce1b6436a5db 100644 (file)
@@ -2,8 +2,8 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    NT Domain Authentication SMB / MSRPC client
-   Copyright (C) Andrew Tridgell 1994-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    
    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
@@ -33,104 +33,15 @@ extern int DEBUGLEVEL;
 
 #define DEBUG_TESTING
 
-extern struct ntuser_creds *usr_creds;
+extern struct cli_state *smb_cli;
 
 extern FILE* out_hnd;
 
-static void sam_display_domain(const char *domain)
-{
-       report(out_hnd, "Domain Name: %s\n", domain);
-}
-
-static void sam_display_dom_info(const char* domain, const DOM_SID *sid,
-                               uint32 switch_value,
-                               SAM_UNK_CTR *ctr)
-{
-       fstring sidstr;
-       sid_to_string(sidstr, sid);
-       report(out_hnd, "Domain Name:\t%s\tSID:\t%s\n", domain, sidstr);
-       display_sam_unk_ctr(out_hnd, ACTION_HEADER   , switch_value, ctr);
-       display_sam_unk_ctr(out_hnd, ACTION_ENUMERATE, switch_value, ctr);
-       display_sam_unk_ctr(out_hnd, ACTION_FOOTER   , switch_value, ctr);
-}
-
-static void sam_display_alias_info(const char *domain, const DOM_SID *sid,
-                               uint32 alias_rid, 
-                               ALIAS_INFO_CTR *const ctr)
-{
-       display_alias_info_ctr(out_hnd, ACTION_HEADER   , ctr);
-       display_alias_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
-       display_alias_info_ctr(out_hnd, ACTION_FOOTER   , ctr);
-}
-
-static void sam_display_alias(const char *domain, const DOM_SID *sid,
-                               uint32 alias_rid, const char *alias_name)
-{
-       report(out_hnd, "Alias RID: %8x  Alias Name: %s\n",
-                         alias_rid, alias_name);
-}
-
-static void sam_display_alias_members(const char *domain, const DOM_SID *sid,
-                               uint32 alias_rid, const char *alias_name,
-                               uint32 num_names,
-                               DOM_SID *const *const sids,
-                               char *const *const name,
-                               uint8 *const type)
-{
-       display_alias_members(out_hnd, ACTION_HEADER   , num_names, name, type);
-       display_alias_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
-       display_alias_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
-}
-
-static void sam_display_group_info(const char *domain, const DOM_SID *sid,
-                               uint32 group_rid, 
-                               GROUP_INFO_CTR *const ctr)
-{
-       display_group_info_ctr(out_hnd, ACTION_HEADER   , ctr);
-       display_group_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
-       display_group_info_ctr(out_hnd, ACTION_FOOTER   , ctr);
-}
-
-static void sam_display_group(const char *domain, const DOM_SID *sid,
-                               uint32 group_rid, const char *group_name)
-{
-       report(out_hnd, "Group RID: %8x  Group Name: %s\n",
-                         group_rid, group_name);
-}
-
-static void sam_display_group_members(const char *domain, const DOM_SID *sid,
-                               uint32 group_rid, const char *group_name,
-                               uint32 num_names,
-                               const uint32 *rid_mem,
-                               char *const *const name,
-                               uint32 *const type)
-{
-       display_group_members(out_hnd, ACTION_HEADER   , num_names, name, type);
-       display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
-       display_group_members(out_hnd, ACTION_FOOTER   , num_names, name, type);
-}
-
-static void sam_display_user_info(const char *domain, const DOM_SID *sid,
-                               uint32 user_rid, 
-                               SAM_USER_INFO_21 *const usr)
-{
-       display_sam_user_info_21(out_hnd, ACTION_HEADER   , usr);
-       display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, usr);
-       display_sam_user_info_21(out_hnd, ACTION_FOOTER   , usr);
-}
-
-static void sam_display_user(const char *domain, const DOM_SID *sid,
-                               uint32 user_rid, const char *user_name)
-{
-       report(out_hnd, "User RID: %8x  User Name: %s\n",
-                       user_rid, user_name);
-}
-
 
 /****************************************************************************
 SAM password change
 ****************************************************************************/
-void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
+void cmd_sam_ntchange_pwd(struct client_info *info)
 {
        fstring srv_name;
        fstring domain;
@@ -146,8 +57,6 @@ void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
        uchar lm_hshhash[16];
        uchar lm_oldhash[16];
 
-       struct cli_connection *con = NULL;
-
        sid_to_string(sid, &info->dom.level5_sid);
        fstrcpy(domain, info->dom.level5_dom);
 
@@ -155,7 +64,7 @@ void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
        fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
-       report(out_hnd, "SAM NT Password Change\n");
+       fprintf(out_hnd, "SAM NT Password Change\n");
 
 #if 0
        struct pwd_info new_pwd;
@@ -164,13 +73,14 @@ void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
        new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
 
        nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
-       pwd_get_lm_nt_16(&(usr_creds->pwd), lm_oldhash, nt_oldhash );
+       pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
        make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
        make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
        E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
        E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
 
-       usr_creds->ntlmssp_flags = NTLMSSP_NEGOTIATE_UNICODE |
+       cli_nt_set_ntlmssp_flgs(smb_cli,
+                                   NTLMSSP_NEGOTIATE_UNICODE |
                                    NTLMSSP_NEGOTIATE_OEM |
                                    NTLMSSP_NEGOTIATE_SIGN |
                                    NTLMSSP_NEGOTIATE_SEAL |
@@ -178,29 +88,29 @@ void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
                                    NTLMSSP_NEGOTIATE_NTLM |
                                    NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
                                    NTLMSSP_NEGOTIATE_00001000 |
-                                   NTLMSSP_NEGOTIATE_00002000;
+                                   NTLMSSP_NEGOTIATE_00002000);
 
        /* open SAMR session.  */
-       res = res ? cli_connection_init(srv_name, PIPE_SAMR, &con) : False;
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
 
        /* establish a connection. */
-       res = res ? samr_unknown_38(con, srv_name) : False;
+       res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
 
        /* establish a connection. */
-       res = res ? samr_chgpasswd_user(con,
-                                          srv_name, usr_creds->user_name,
+       res = res ? do_samr_chgpasswd_user(smb_cli,
+                                          srv_name, smb_cli->user_name,
                                           nt_newpass, nt_hshhash,
                                           lm_newpass, lm_hshhash) : False;
        /* close the session */
-       cli_connection_unlink(con);
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
-               report(out_hnd, "NT Password changed OK\n");
+               fprintf(out_hnd, "NT Password changed OK\n");
        }
        else
        {
-               report(out_hnd, "NT Password change FAILED\n");
+               fprintf(out_hnd, "NT Password change FAILED\n");
        }
 }
 
@@ -208,9 +118,8 @@ void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 experimental SAM encryted rpc test connection
 ****************************************************************************/
-void cmd_sam_test(struct client_info *info, int argc, char *argv[])
+void cmd_sam_test(struct client_info *info)
 {
-       struct cli_connection *con = NULL;
        fstring srv_name;
        fstring domain;
        fstring sid;
@@ -220,9 +129,9 @@ void cmd_sam_test(struct client_info *info, int argc, char *argv[])
        fstrcpy(domain, info->dom.level5_dom);
 
 /*
-       if (sid1.num_auths == 0)
+       if (strlen(sid) == 0)
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
                return;
        }
 */
@@ -230,9 +139,10 @@ void cmd_sam_test(struct client_info *info, int argc, char *argv[])
        fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
-       report(out_hnd, "SAM Encryption Test\n");
+       fprintf(out_hnd, "SAM Encryption Test\n");
 
-       usr_creds->ntlmssp_flags = NTLMSSP_NEGOTIATE_UNICODE |
+       cli_nt_set_ntlmssp_flgs(smb_cli,
+                                   NTLMSSP_NEGOTIATE_UNICODE |
                                    NTLMSSP_NEGOTIATE_OEM |
                                    NTLMSSP_NEGOTIATE_SIGN |
                                    NTLMSSP_NEGOTIATE_SEAL |
@@ -240,13 +150,16 @@ void cmd_sam_test(struct client_info *info, int argc, char *argv[])
                                    NTLMSSP_NEGOTIATE_NTLM |
                                    NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
                                    NTLMSSP_NEGOTIATE_00001000 |
-                                   NTLMSSP_NEGOTIATE_00002000;
+                                   NTLMSSP_NEGOTIATE_00002000);
 
        /* open SAMR session.  */
-       res = res ? cli_connection_init(srv_name, PIPE_SAMR, &con) : False;
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+       /* establish a connection. */
+       res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
 
        /* close the session */
-       cli_connection_unlink(con);
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
@@ -258,2172 +171,510 @@ void cmd_sam_test(struct client_info *info, int argc, char *argv[])
        }
 }
 
+
 /****************************************************************************
-Lookup domain in SAM server.
+experimental SAM users enum.
 ****************************************************************************/
-void cmd_sam_lookup_domain(struct client_info *info, int argc, char *argv[])
+void cmd_sam_enum_users(struct client_info *info)
 {
        fstring srv_name;
-       char *domain;
-       fstring str_sid;
-       DOM_SID dom_sid;
+       fstring domain;
+       fstring sid;
+       DOM_SID sid1;
+       int user_idx;
        BOOL res = True;
-       POLICY_HND sam_pol;
+       BOOL request_user_info  = False;
+       BOOL request_group_info = False;
+       uint16 num_entries = 0;
+       uint16 unk_0 = 0x0;
+       uint16 acb_mask = 0;
+       uint16 unk_1 = 0x0;
+       uint32 admin_rid = 0x304; /* absolutely no idea. */
+       fstring tmp;
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       sid_to_string(sid, &info->dom.level5_sid);
+       fstrcpy(domain, info->dom.level5_dom);
 
-       if (argc < 2)
+       if (strlen(sid) == 0)
        {
-               report(out_hnd, "lookupdomain: <name>\n");
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
                return;
        }
 
-       domain = argv[1];
+       init_dom_sid(&sid1, sid);
 
-       report(out_hnd, "Lookup Domain in SAM Server\n");
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_query_lookup_domain( &sam_pol, domain, &dom_sid) : False;
-
-       res = res ? samr_close(&sam_pol) : False;
+       fstrcpy(srv_name, "\\\\");
+       fstrcat(srv_name, info->dest_host);
+       strupper(srv_name);
 
-       if (res)
+       /* a bad way to do token parsing... */
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               DEBUG(5,("cmd_sam_lookup_domain: succeeded\n"));
-
-               sid_to_string(str_sid, &dom_sid);
-               report(out_hnd, "%s SID: %s\n", domain, str_sid);
-               report(out_hnd, "Lookup Domain: OK\n");
+               request_user_info  |= strequal(tmp, "-u");
+               request_group_info |= strequal(tmp, "-g");
        }
-       else
+
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               DEBUG(5,("cmd_sam_lookup_domain: failed\n"));
-               report(out_hnd, "Lookup Domain: FAILED\n");
+               request_user_info  |= strequal(tmp, "-u");
+               request_group_info |= strequal(tmp, "-g");
        }
-}
 
-/****************************************************************************
-SAM delete alias member.
-****************************************************************************/
-void cmd_sam_del_aliasmem(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       POLICY_HND alias_pol;
-       BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       DOM_SID member_sid; 
-       uint32 alias_rid;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
+#ifdef DEBUG_TESTING
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
+       }
 
-       if (sid1.num_auths == 0)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
+               unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
        }
 
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
+       }
 
-       if (argc < 2)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               report(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
-               return;
+               unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
        }
+#endif
 
-       argc--;
-       argv++;
+       fprintf(out_hnd, "SAM Enumerate Users\n");
+       fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+                         info->myhostname, srv_name, domain, sid);
 
-       alias_rid = get_number(argv[0]);
+#ifdef DEBUG_TESTING
+       DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
+                 num_entries, unk_0, acb_mask, unk_1));
+#endif
 
-       report(out_hnd, "SAM Domain Alias Member\n");
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
 
        /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
+       res = res ? do_samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
 
        /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
+       res = res ? do_samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, admin_rid, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
 
-       /* connect to the domain */
-       res1 = res ? samr_open_alias( &pol_dom,
-                   0x000f001f, alias_rid, &alias_pol) : False;
+       /* read some users */
+       res = res ? do_samr_enum_dom_users(smb_cli, 
+                               &info->dom.samr_pol_open_domain,
+                   num_entries, unk_0, acb_mask, unk_1, 0xffff,
+                               &info->dom.sam, &info->dom.num_sam_entries) : False;
+
+       if (res && info->dom.num_sam_entries == 0)
+       {
+               fprintf(out_hnd, "No users\n");
+       }
 
-       while (argc > 0 && res2 && res1)
+       if (request_user_info || request_group_info)
        {
-               argc--;
-               argv++;
-               /* get a sid, delete a member from the alias */
-               res2 = res2 ? string_to_sid(&member_sid, argv[0]) : False;
-               res2 = res2 ? samr_del_aliasmem(&alias_pol, &member_sid) : False;
+               /* query all the users */
+               user_idx = 0;
 
-               if (res2)
+               while (res && user_idx < info->dom.num_sam_entries)
                {
-                       report(out_hnd, "SID deleted from Alias 0x%x: %s\n", alias_rid, argv[0]);
+                       uint32 user_rid = info->dom.sam[user_idx].smb_userid;
+                       SAM_USER_INFO_21 usr;
+
+                       fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
+                                         user_rid,
+                                         info->dom.sam[user_idx].acct_name);
+
+                       if (request_user_info)
+                       {
+                               /* send user info query, level 0x15 */
+                               if (get_samr_query_userinfo(smb_cli,
+                                                       &info->dom.samr_pol_open_domain,
+                                                       0x15, user_rid, &usr))
+                               {
+                                       display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
+                                       display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+                                       display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
+                               }
+                       }
+
+                       if (request_group_info)
+                       {
+                               uint32 num_groups;
+                               DOM_GID gid[LSA_MAX_GROUPS];
+
+                               /* send user group query */
+                               if (get_samr_query_usergroups(smb_cli,
+                                                       &info->dom.samr_pol_open_domain,
+                                                       user_rid, &num_groups, gid))
+                               {
+                                       display_group_rid_info(out_hnd, ACTION_HEADER   , num_groups, gid);
+                                       display_group_rid_info(out_hnd, ACTION_ENUMERATE, num_groups, gid);
+                                       display_group_rid_info(out_hnd, ACTION_FOOTER   , num_groups, gid);
+                               }
+                       }
+
+                       user_idx++;
                }
        }
 
-       res1 = res1 ? samr_close(&alias_pol) : False;
-       res  = res  ? samr_close(&pol_dom) : False;
-       res  = res  ? samr_close(&sam_pol) : False;
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_connect) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (info->dom.sam != NULL)
+       {
+               free(info->dom.sam);
+       }
 
-       if (res && res1 && res2)
+       if (res)
        {
-               DEBUG(5,("cmd_sam_del_aliasmem: succeeded\n"));
-               report(out_hnd, "Delete Domain Alias Member: OK\n");
+               DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
        }
        else
        {
-               DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
-               report(out_hnd, "Delete Domain Alias Member: FAILED\n");
+               DEBUG(5,("cmd_sam_enum_users: failed\n"));
        }
 }
 
+
 /****************************************************************************
-SAM delete alias.
+experimental SAM user query.
 ****************************************************************************/
-void cmd_sam_delete_dom_alias(struct client_info *info, int argc, char *argv[])
+void cmd_sam_query_user(struct client_info *info)
 {
        fstring srv_name;
        fstring domain;
-       char *name;
        fstring sid;
        DOM_SID sid1;
-       POLICY_HND alias_pol;
+       int user_idx = 0;  /* FIXME maybe ... */
        BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 alias_rid = 0;
-       char *names[1];
-       uint32 rid [MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       uint32 num_rids;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
+       uint32 admin_rid = 0x304; /* absolutely no idea. */
+       fstring rid_str ;
+       fstring info_str;
+       uint32 user_rid = 0;
+       uint32 info_level = 0x15;
+
+       SAM_USER_INFO_21 usr;
+
+       sid_to_string(sid, &info->dom.level5_sid);
        fstrcpy(domain, info->dom.level5_dom);
 
-       if (sid1.num_auths == 0)
+       if (strlen(sid) == 0)
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
                return;
        }
 
+       init_dom_sid(&sid1, sid);
+
        fstrcpy(srv_name, "\\\\");
        fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
-       if (argc < 2)
+       if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
+           next_token(NULL, info_str, NULL, sizeof(info_str)))
        {
-               report(out_hnd, "delalias <alias name>\n");
-               return;
+               user_rid   = (uint32)strtol(rid_str , (char**)NULL, 16);
+               info_level = (uint32)strtol(info_str, (char**)NULL, 10);
        }
 
-       name = argv[1];
+       fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
+                         user_rid, info_level);
+       fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+                         info->myhostname, srv_name, domain, sid);
 
-       report(out_hnd, "SAM Delete Domain Alias\n");
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
 
        /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
+       res = res ? do_samr_connect(smb_cli,
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
 
        /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
+       res = res ? do_samr_open_domain(smb_cli,
+                   &info->dom.samr_pol_connect, admin_rid, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
 
-       names[0] = name;
+       fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
+                         user_rid,
+                         info->dom.sam[user_idx].acct_name);
 
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
-                   1, names,
-                   &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
+       /* send user info query, level */
+       if (get_samr_query_userinfo(smb_cli,
+                                       &info->dom.samr_pol_open_domain,
+                                       info_level, user_rid, &usr))
        {
-               alias_rid = rid[0];
+               if (info_level == 0x15)
+               {
+                       display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
+                       display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+                       display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
+               }
        }
 
-       /* connect to the domain */
-       res1 = res1 ? samr_open_alias( &pol_dom,
-                   0x000f001f, alias_rid, &alias_pol) : False;
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_connect) : False;
 
-       res2 = res1 ? samr_delete_dom_alias(&alias_pol) : False;
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_open_domain) : False;
 
-       res1 = res1 ? samr_close(&alias_pol) : False;
-       res  = res  ? samr_close(&pol_dom) : False;
-       res  = res  ? samr_close(&sam_pol) : False;
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
-       if (res && res1 && res2)
+       if (res)
        {
-               DEBUG(5,("cmd_sam_delete_dom_alias: succeeded\n"));
-               report(out_hnd, "Delete Domain Alias: OK\n");
+               DEBUG(5,("cmd_sam_query_user: succeeded\n"));
        }
        else
        {
-               DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
-               report(out_hnd, "Delete Domain Alias: FAILED\n");
+               DEBUG(5,("cmd_sam_query_user: failed\n"));
        }
 }
 
+
 /****************************************************************************
-SAM add alias member.
+experimental SAM groups query.
 ****************************************************************************/
-void cmd_sam_add_aliasmem(struct client_info *info, int argc, char *argv[])
+void cmd_sam_query_groups(struct client_info *info)
 {
        fstring srv_name;
        fstring domain;
-       fstring tmp;
        fstring sid;
        DOM_SID sid1;
-       POLICY_HND alias_pol;
        BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       BOOL res3 = True;
-       BOOL res4 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 alias_rid;
-       char **names = NULL;
-       int num_names = 0;
-       DOM_SID *sids = NULL; 
-       int num_sids = 0;
-       int i;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-       POLICY_HND lsa_pol;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
+       fstring info_str;
+       uint32 switch_value = 2;
+       uint32 admin_rid = 0x304; /* absolutely no idea. */
+
+       sid_to_string(sid, &info->dom.level5_sid);
        fstrcpy(domain, info->dom.level5_dom);
 
-       if (sid1.num_auths == 0)
+       if (strlen(sid) == 0)
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
                return;
        }
 
+       init_dom_sid(&sid1, sid);
+
        fstrcpy(srv_name, "\\\\");
        fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
-       if (argc < 2)
+       if (next_token(NULL, info_str, NULL, sizeof(info_str)))
        {
-               report(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
-               return;
+               switch_value = (uint32)strtol(info_str, (char**)NULL, 10);
        }
-       
-       num_names = argc+1;
-       names = argv+1;
-
-       report(out_hnd, "SAM Domain Alias Member\n");
-
-       /* lookup domain controller; receive a policy handle */
-       res3 = res3 ? lsa_open_policy(srv_name,
-                               &lsa_pol, True) : False;
-
-       /* send lsa lookup sids call */
-       res4 = res3 ? lsa_lookup_names(&lsa_pol,
-                                      num_names, names, 
-                                      &sids, NULL, &num_sids) : False;
-
-       res3 = res3 ? lsa_close(&lsa_pol) : False;
-
-       res4 = num_sids < 2 ? False : res4;
-
-       if (res4)
-       {
-               /*
-                * accept domain sid or builtin sid
-                */
 
-               DOM_SID sid_1_5_20;
-               string_to_sid(&sid_1_5_20, "S-1-5-32");
-               sid_split_rid(&sids[0], &alias_rid);
+       fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value);
+       fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+                         info->myhostname, srv_name, domain, sid);
 
-               if (sid_equal(&sids[0], &sid_1_5_20))
-               {
-                       sid_copy(&sid1, &sid_1_5_20);
-               }
-               else if (!sid_equal(&sids[0], &sid1))
-               {       
-                       res4 = False;
-               }
-       }
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
 
        /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
+       res = res ? do_samr_connect(smb_cli, 
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
 
        /* connect to the domain */
-       res1 = res ? samr_open_alias( &pol_dom,
-                   0x000f001f, alias_rid, &alias_pol) : False;
+       res = res ? do_samr_open_domain(smb_cli, 
+                   &info->dom.samr_pol_connect, admin_rid, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
 
-       for (i = 1; i < num_sids && res2 && res1; i++)
-       {
-               /* add a member to the alias */
-               res2 = res2 ? samr_add_aliasmem(&alias_pol, &sids[i]) : False;
+       /* send a samr 0x8 command */
+       res = res ? do_samr_query_dom_info(smb_cli,
+                   &info->dom.samr_pol_open_domain, switch_value) : False;
 
-               if (res2)
-               {
-                       sid_to_string(tmp, &sids[i]);
-                       report(out_hnd, "SID added to Alias 0x%x: %s\n", alias_rid, tmp);
-               }
-       }
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_connect) : False;
 
-       res1 = res1 ? samr_close(&alias_pol) : False;
-       res  = res  ? samr_close(&pol_dom) : False;
-       res  = res  ? samr_close(&sam_pol) : False;
+       res = res ? do_samr_close(smb_cli, 
+                   &info->dom.samr_pol_open_domain) : False;
 
-       if (sids != NULL)
-       {
-               free(sids);
-       }
-       
-       free_char_array(num_names, names);
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
-       if (res && res1 && res2)
+       if (res)
        {
-               DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
-               report(out_hnd, "Add Domain Alias Member: OK\n");
+               DEBUG(5,("cmd_sam_query_groups: succeeded\n"));
        }
        else
        {
-               DEBUG(5,("cmd_sam_add_aliasmem: failed\n"));
-               report(out_hnd, "Add Domain Alias Member: FAILED\n");
+               DEBUG(5,("cmd_sam_query_groups: failed\n"));
        }
 }
 
 
-#if 0
 /****************************************************************************
-SAM create domain user.
+experimental SAM aliases query.
 ****************************************************************************/
-void cmd_sam_create_dom_trusting(struct client_info *info, int argc, char *argv[])
+void cmd_sam_enum_aliases(struct client_info *info)
 {
-       fstring local_domain;
-       fstring local_pdc;
-
-       char *trusting_domain;
-       char *trusting_pdc;
-       fstring password;
-
+       fstring srv_name;
+       fstring domain;
        fstring sid;
        DOM_SID sid1;
-       uint32 user_rid; 
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
+       BOOL res = True;
+       BOOL request_user_info  = False;
+       BOOL request_alias_info = False;
+       uint32 admin_rid = 0x304; /* absolutely no idea. */
+       fstring tmp;
 
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
+       uint32 num_aliases = 3;
+       uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS };
+       fstring alias_names [3];
+       uint32  num_als_usrs[3];
 
-       if (argc < 3)
+       sid_to_string(sid, &info->dom.level3_sid);
+       fstrcpy(domain, info->dom.level3_dom);
+#if 0
+       fstrcpy(sid   , "S-1-5-20");
+#endif
+       if (strlen(sid) == 0)
        {
-               report(out_hnd, "createtrusting: <Domain Name> <PDC Name> [password]\n");
+               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
                return;
        }
 
-       argc--;
-       argv++;
-
-       trusting_domain = argv[0];
-
-       argc--;
-       argv++;
-
-       trusting_pdc = argv[0];
-
-       argc--;
-       argv++;
-
-       if (argc > 0)
-       {
-               safe_strcpy(password, argv[0], sizeof(password)-1);
-       }
-       else
-       {
-               fstring pass_str;
-               char *pass;
-               slprintf(pass_str, sizeof(pass_str)-1, "Enter %s's Password:",
-                        user_name);
-               pass = (char*)getpass(pass_str);
-
-               if (pass != NULL)
-               {
-                       safe_strcpy(password, pass, sizeof(password)-1);
-                       set_passwd = True;
-               }
-       }
-       report(out_hnd, "SAM Create Domain Trusting Account\n");
-
-       if (msrpc_sam_create_dom_user(srv_name,
-                                     acct_name, ACB_WSTRUST, &user_rid))
-       {
-               report(out_hnd, "Create Domain User: OK\n");
-       }
-       else
-       {
-               report(out_hnd, "Create Domain User: FAILED\n");
-       }
-}
-#endif
-
-/****************************************************************************
-SAM create domain user.
-****************************************************************************/
-void cmd_sam_create_dom_user(struct client_info *info, int argc, char *argv[])
-{
-       fstring domain;
-       fstring acct_name;
-       fstring name;
-       fstring sid;
-       DOM_SID sid1;
-       uint32 user_rid; 
-       uint16 acb_info = ACB_NORMAL;
-       BOOL join_domain = False;
-       int opt;
-       char *password = NULL;
-       int plen = 0;
-       int len = 0;
-       UNISTR2 upw;
+       init_dom_sid(&sid1, sid);
 
-       fstring srv_name;
        fstrcpy(srv_name, "\\\\");
        fstrcat(srv_name, info->dest_host);
        strupper(srv_name);
 
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
+       /* a bad way to do token parsing... */
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
+               request_user_info  |= strequal(tmp, "-u");
+               request_alias_info |= strequal(tmp, "-g");
        }
 
-       if (argc < 2)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               report(out_hnd, "createuser: <acct name> [-i] [-s] [-j]\n");
-               return;
+               request_user_info  |= strequal(tmp, "-u");
+               request_alias_info |= strequal(tmp, "-g");
        }
 
-       argc--;
-       argv++;
+       fprintf(out_hnd, "SAM Enumerate Aliases\n");
+       fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+                         info->myhostname, srv_name, domain, sid);
 
-       safe_strcpy(acct_name, argv[0], sizeof(acct_name));
-       len = strlen(acct_name)-1;
-       if (acct_name[len] == '$')
-       {
-               safe_strcpy(name, argv[0], sizeof(name));
-               name[len] = 0;
-               acb_info = ACB_WSTRUST;
-       }
+       /* open SAMR session.  negotiate credentials */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
 
-       while ((opt = getopt(argc, argv,"isj")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'i':
-                       {
-                               acb_info = ACB_DOMTRUST;
-                               break;
-                       }
-                       case 's':
-                       {
-                               acb_info = ACB_SVRTRUST;
-                               break;
-                       }
-                       case 'j':
-                       {
-                               join_domain = True;
-                       }
-               }
-       }
+       /* establish a connection. */
+       res = res ? do_samr_connect(smb_cli,
+                               srv_name, 0x00000020,
+                               &info->dom.samr_pol_connect) : False;
+
+       /* connect to the domain */
+       res = res ? do_samr_open_domain(smb_cli,
+                   &info->dom.samr_pol_connect, admin_rid, &sid1,
+                   &info->dom.samr_pol_open_domain) : False;
+
+       /* send a query on the aliase */
+       res = res ? do_samr_query_unknown_12(smb_cli,
+                   &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid,
+                   &num_aliases, alias_names, num_als_usrs) : False;
 
-       if (join_domain && acb_info == ACB_NORMAL)
+       if (res)
        {
-               report(out_hnd, "can only join trust accounts to a domain\n");
-               return;
+               display_alias_name_info(out_hnd, ACTION_HEADER   , num_aliases, alias_names, num_als_usrs);
+               display_alias_name_info(out_hnd, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs);
+               display_alias_name_info(out_hnd, ACTION_FOOTER   , num_aliases, alias_names, num_als_usrs);
        }
 
-       report(out_hnd, "SAM Create Domain User\n");
-       report(out_hnd, "Domain: %s Name: %s ACB: %s\n",
-                         domain, acct_name,
-           pwdb_encode_acct_ctrl(acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+#if 0
+
+       /* read some users */
+       res = res ? do_samr_enum_dom_users(smb_cli,
+                               &info->dom.samr_pol_open_domain,
+                   num_entries, unk_0, acb_mask, unk_1, 0xffff,
+                               info->dom.sam, &info->dom.num_sam_entries) : False;
 
-       if (acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)
+       if (res && info->dom.num_sam_entries == 0)
        {
-               upw.uni_str_len = 12;
-               upw.uni_max_len = 12;
-               generate_random_buffer((uchar*)upw.buffer,
-                                      upw.uni_str_len*2, True);
-               password = (char*)upw.buffer;
-               plen = upw.uni_str_len * 2;
+               fprintf(out_hnd, "No users\n");
        }
 
-       if (msrpc_sam_create_dom_user(srv_name, &sid1,
-                                     acct_name, acb_info, password, plen,
-                                     &user_rid))
+       if (request_user_info || request_alias_info)
        {
-               report(out_hnd, "Create Domain User: OK\n");
+               /* query all the users */
+               user_idx = 0;
 
-               if (join_domain)
+               while (res && user_idx < info->dom.num_sam_entries)
                {
-                       uchar ntpw[16];
-                       
-                       nt_owf_genW(&upw, ntpw);
+                       uint32 user_rid = info->dom.sam[user_idx].smb_userid;
+                       SAM_USER_INFO_21 usr;
 
-                       strupper(domain);
-                       strupper(name);
+                       fprintf(out_hnd, "User RID: %8x  User Name: %s\n",
+                                         user_rid,
+                                         info->dom.sam[user_idx].acct_name);
 
-                       report(out_hnd, "Join %s to Domain %s", name, domain);
-                       if (create_trust_account_file(domain, name, ntpw))
+                       if (request_user_info)
                        {
-                               report(out_hnd, ": OK\n");
+                               /* send user info query, level 0x15 */
+                               if (get_samr_query_userinfo(smb_cli,
+                                                       &info->dom.samr_pol_open_domain,
+                                                       0x15, user_rid, &usr))
+                               {
+                                       display_sam_user_info_21(out_hnd, ACTION_HEADER   , &usr);
+                                       display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+                                       display_sam_user_info_21(out_hnd, ACTION_FOOTER   , &usr);
+                               }
                        }
-                       else
+
+                       if (request_alias_info)
                        {
-                               report(out_hnd, ": FAILED\n");
+                               uint32 num_aliases;
+                               DOM_GID gid[LSA_MAX_GROUPS];
+
+                               /* send user aliase query */
+                               if (get_samr_query_useraliases(smb_cli, 
+                                                       &info->dom.samr_pol_open_domain,
+                                                       user_rid, &num_aliases, gid))
+                               {
+                                       display_alias_info(out_hnd, ACTION_HEADER   , num_aliases, gid);
+                                       display_alias_info(out_hnd, ACTION_ENUMERATE, num_aliases, gid);
+                                       display_alias_info(out_hnd, ACTION_FOOTER   , num_aliases, gid);
+                               }
                        }
+
+                       user_idx++;
                }
        }
-       else
-       {
-               report(out_hnd, "Create Domain User: FAILED\n");
-       }
-}
+#endif
 
+       res = res ? do_samr_close(smb_cli, 
+                   &info->dom.samr_pol_connect) : False;
 
-/****************************************************************************
-SAM create domain alias.
-****************************************************************************/
-void cmd_sam_create_dom_alias(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       char *acct_name;
-       fstring acct_desc;
-       fstring sid;
-       DOM_SID sid1;
-       BOOL res = True;
-       BOOL res1 = True;
-       uint32 ace_perms = 0x02000000; /* permissions */
-       uint32 alias_rid; 
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
+       res = res ? do_samr_close(smb_cli,
+                   &info->dom.samr_pol_open_domain) : False;
 
-       if (sid1.num_auths == 0)
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
+       if (res)
        {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
+               DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
        }
-
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
+       else
        {
-               report(out_hnd, "createalias: <acct name> [acct description]\n");
+               DEBUG(5,("cmd_sam_enum_users: failed\n"));
        }
+}
 
-       acct_name = argv[1];
-
-       if (argc < 3)
-       {
-               acct_desc[0] = 0;
-       }
-       else
-       {
-               safe_strcpy(acct_desc, argv[2], sizeof(acct_desc)-1);
-       }
-
-       report(out_hnd, "SAM Create Domain Alias\n");
-       report(out_hnd, "Domain: %s Name: %s Description: %s\n",
-                         domain, acct_name, acct_desc);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
-
-       /* create a domain alias */
-       res1 = res ? create_samr_domain_alias( &pol_dom,
-                               acct_name, acct_desc, &alias_rid) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       if (res && res1)
-       {
-               DEBUG(5,("cmd_sam_create_dom_alias: succeeded\n"));
-               report(out_hnd, "Create Domain Alias: OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_create_dom_alias: failed\n"));
-               report(out_hnd, "Create Domain Alias: FAILED\n");
-       }
-}
-
-
-/****************************************************************************
-SAM delete group member.
-****************************************************************************/
-void cmd_sam_del_groupmem(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       POLICY_HND pol_grp;
-       BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 member_rid; 
-       uint32 group_rid;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
-               return;
-       }
-
-       argc--;
-       argv++;
-
-       group_rid = get_number(argv[0]);
-
-       report(out_hnd, "SAM Add Domain Group member\n");
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
-
-       /* connect to the domain */
-       res1 = res ? samr_open_group( &pol_dom,
-                   0x0000001f, group_rid, &pol_grp) : False;
-
-       while (argc > 0 && res2 && res1)
-       {
-               argc--;
-               argv++;
-
-               /* get a rid, delete a member from the group */
-               member_rid = get_number(argv[0]);
-               res2 = res2 ? samr_del_groupmem(&pol_grp, member_rid) : False;
-
-               if (res2)
-               {
-                       report(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
-               }
-       }
-
-       res1 = res1 ? samr_close(&pol_grp) : False;
-       res  = res  ? samr_close(&pol_dom) : False;
-       res  = res  ? samr_close(&sam_pol) : False;
-
-       if (res && res1 && res2)
-       {
-               DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
-               report(out_hnd, "Add Domain Group Member: OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
-               report(out_hnd, "Add Domain Group Member: FAILED\n");
-       }
-}
-
-
-/****************************************************************************
-SAM delete group.
-****************************************************************************/
-void cmd_sam_delete_dom_group(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       char *name;
-       fstring sid;
-       DOM_SID sid1;
-       POLICY_HND pol_grp;
-       BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 group_rid = 0;
-       char *names[1];
-       uint32 rid [MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       uint32 num_rids;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd, "delgroup <group name>\n");
-               return;
-       }
-
-       name = argv[1];
-
-       report(out_hnd, "SAM Delete Domain Group\n");
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
-
-       names[0] = name;
-
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
-                   1, names,
-                   &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
-       {
-               group_rid = rid[0];
-       }
-
-       /* connect to the domain */
-       res1 = res1 ? samr_open_group( &pol_dom,
-                   0x0000001f, group_rid, &pol_grp) : False;
-
-       res2 = res1 ? samr_delete_dom_group(&pol_grp) : False;
-
-       res1 = res1 ? samr_close(&pol_grp) : False;
-       res  = res  ? samr_close(&pol_dom) : False;
-       res  = res  ? samr_close(&sam_pol) : False;
-
-       if (res && res1 && res2)
-       {
-               DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
-               report(out_hnd, "Delete Domain Group: OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
-               report(out_hnd, "Delete Domain Group: FAILED\n");
-       }
-}
-
-
-/****************************************************************************
-SAM add group member.
-****************************************************************************/
-void cmd_sam_add_groupmem(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       POLICY_HND pol_grp;
-       BOOL res = True;
-       BOOL res1 = True;
-       BOOL res2 = True;
-       BOOL res3 = True;
-       BOOL res4 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 group_rid[1];
-       uint32 group_type[1];
-       char **names = NULL;
-       uint32 num_names = 0;
-       fstring group_name;
-       char *group_names[1];
-       uint32 rid [MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       uint32 num_rids;
-       uint32 num_group_rids;
-       uint32 i;
-       DOM_SID sid_1_5_20;
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-       POLICY_HND pol_blt;
-
-       string_to_sid(&sid_1_5_20, "S-1-5-32");
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 3)
-       {
-               report(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
-               return;
-       }
-       
-       argc--;
-       argv++;
-
-       group_names[0] = argv[0];
-
-       argc--;
-       argv++;
-
-       num_names = argc;
-       names = argv;
-
-       report(out_hnd, "SAM Add Domain Group member\n");
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res4 = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
-
-       /* connect to the domain */
-       res3 = res ? samr_open_domain( &sam_pol, ace_perms, &sid_1_5_20,
-                   &pol_blt) : False;
-
-       res2 = res4 ? samr_query_lookup_names( &pol_dom, 0x000003e8,
-                   1, group_names,
-                   &num_group_rids, group_rid, group_type) : False;
-
-       /* open the group */
-       res2 = res2 ? samr_open_group( &pol_dom,
-                   0x0000001f, group_rid[0], &pol_grp) : False;
-
-       if (!res2 || (group_type != NULL && group_type[0] == SID_NAME_UNKNOWN))
-       {
-               res2 = res3 ? samr_query_lookup_names( &pol_blt, 0x000003e8,
-                           1, group_names, 
-                           &num_group_rids, group_rid, group_type) : False;
-
-               /* open the group */
-               res2 = res2 ? samr_open_group( &pol_blt,
-                           0x0000001f, group_rid[0], &pol_grp) : False;
-       }
-
-       if (res2 && group_type[0] == SID_NAME_ALIAS)
-       {
-               report(out_hnd, "%s is a local alias, not a group.  Use addaliasmem command instead\n",
-                       group_name);
-               return;
-       }
-       res1 = res2 ? samr_query_lookup_names( &pol_dom, 0x000003e8,
-                   num_names, names,
-                   &num_rids, rid, type) : False;
-
-       if (num_rids == 0)
-       {
-               report(out_hnd, "Member names not known\n");
-       }
-       for (i = 0; i < num_rids && res2 && res1; i++)
-       {
-               if (type[i] == SID_NAME_UNKNOWN)
-               {
-                       report(out_hnd, "Name %s unknown\n", names[i]);
-               }
-               else
-               {
-                       if (samr_add_groupmem(&pol_grp, rid[i]))
-                       {
-                               report(out_hnd, "RID added to Group 0x%x: 0x%x\n",
-                                                group_rid[0], rid[i]);
-                       }
-               }
-       }
-
-       res1 = res ? samr_close(&pol_grp) : False;
-       res1 = res3 ? samr_close(&pol_blt) : False;
-       res1 = res4 ? samr_close(&pol_dom) : False;
-       res  = res ? samr_close(&sam_pol) : False;
-
-       free_char_array(num_names, names);
-       
-       if (res && res1 && res2)
-       {
-               DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
-               report(out_hnd, "Add Domain Group Member: OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_add_groupmem: failed\n"));
-               report(out_hnd, "Add Domain Group Member: FAILED\n");
-       }
-#if 0
-       if (group_rid != NULL)
-       {
-               free(group_rid);
-       }
-       if (group_type != NULL)
-       {
-               free(group_type);
-       }
-#endif
-}
-
-
-/****************************************************************************
-SAM create domain group.
-****************************************************************************/
-void cmd_sam_create_dom_group(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       char *acct_name;
-       fstring acct_desc;
-       fstring sid;
-       DOM_SID sid1;
-       BOOL res = True;
-       BOOL res1 = True;
-       uint32 ace_perms = 0x02000000; /* absolutely no idea. */
-       uint32 group_rid; 
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc < 2)
-       {
-               report(out_hnd, "creategroup: <acct name> [acct description]\n");
-       }
-
-       acct_name = argv[1];
-
-       if (argc < 3)
-       {
-               acct_desc[0] = 0;
-       }
-       else
-       {
-               safe_strcpy(acct_desc, argv[2], sizeof(acct_desc)-1);
-       }
-
-
-       report(out_hnd, "SAM Create Domain Group\n");
-       report(out_hnd, "Domain: %s Name: %s Description: %s\n",
-                         domain, acct_name, acct_desc);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
-                   &pol_dom) : False;
-
-       /* read some users */
-       res1 = res ? create_samr_domain_group( &pol_dom,
-                               acct_name, acct_desc, &group_rid) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       if (res && res1)
-       {
-               DEBUG(5,("cmd_sam_create_dom_group: succeeded\n"));
-               report(out_hnd, "Create Domain Group: OK\n");
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_create_dom_group: failed\n"));
-               report(out_hnd, "Create Domain Group: FAILED\n");
-       }
-}
-
-/****************************************************************************
-experimental SAM users enum.
-****************************************************************************/
-void cmd_sam_enum_users(struct client_info *info, int argc, char *argv[])
-{
-       BOOL request_user_info  = False;
-       BOOL request_group_info = False;
-       BOOL request_alias_info = False;
-       struct acct_info *sam = NULL;
-       uint32 num_sam_entries = 0;
-       int opt;
-
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       while ((opt = getopt(argc, argv, "uga")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'u':
-                       {
-                               request_user_info  = True;
-                               break;
-                       }
-                       case 'g':
-                       {
-                               request_group_info = True;
-                               break;
-                       }
-                       case 'a':
-                       {
-                               request_alias_info = True;
-                               break;
-                       }
-               }
-       }
-
-       report(out_hnd, "SAM Enumerate Users\n");
-
-       msrpc_sam_enum_users(srv_name, domain, &sid1,
-                   &sam, &num_sam_entries,
-                   sam_display_user,
-                   request_user_info  ? sam_display_user_info     : NULL,
-                   request_group_info ? sam_display_group_members : NULL,
-                   request_alias_info ? sam_display_group_members : NULL);
-
-       if (sam != NULL)
-       {
-               free(sam);
-       }
-}
-
-
-/****************************************************************************
-experimental SAM group query members.
-****************************************************************************/
-void cmd_sam_query_groupmem(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-
-       char *group_name;
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samgroupmem <name>\n");
-               return;
-       }
-
-       group_name = argv[1];
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Query Group: %s\n", group_name);
-       report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
-                         info->myhostname, srv_name, domain, sid_str);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
-                   &pol_dom) : False;
-
-       /* look up group rid */
-       names[0] = group_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
-       {
-               res1 = req_groupmem_info( &pol_dom,
-                               domain,
-                               &sid,
-                               rid[0],
-                               names[0],
-                               sam_display_group_members);
-       }
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               DEBUG(5,("cmd_sam_query_group: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_group: failed\n"));
-       }
-}
-
-
-/****************************************************************************
-experimental SAM group query.
-****************************************************************************/
-void cmd_sam_query_group(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-
-       char *group_name;
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samgroup <name>\n");
-               return;
-       }
-
-       group_name = argv[1];
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Query Group: %s\n", group_name);
-       report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
-                         info->myhostname, srv_name, domain, sid_str);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
-                   &pol_dom) : False;
-
-       /* look up group rid */
-       names[0] = group_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
-       {
-               res1 = query_groupinfo( &pol_dom,
-                               domain,
-                               &sid,
-                               rid[0],
-                               sam_display_group_info);
-       }
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               DEBUG(5,("cmd_sam_query_group: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_group: failed\n"));
-       }
-}
-
-
-/****************************************************************************
-experimental SAM user query.
-****************************************************************************/
-void cmd_sam_query_user(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-       int opt;
-
-       char *user_name;
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       BOOL request_user_info  = False;
-       BOOL request_group_info = False;
-       BOOL request_alias_info = False;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samuser <name> [-u] [-g] [-a]\n");
-               return;
-       }
-
-       user_name = argv[1];
-
-       argc--;
-       argv++;
-
-       while ((opt = getopt(argc, argv, "uga")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'u':
-                       {
-                               request_user_info  = True;
-                               break;
-                       }
-                       case 'g':
-                       {
-                               request_group_info = True;
-                               break;
-                       }
-                       case 'a':
-                       {
-                               request_alias_info = True;
-                               break;
-                       }
-               }
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Query User: %s\n", user_name);
-       report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
-                         info->myhostname, srv_name, domain, sid_str);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
-                   &pol_dom) : False;
-
-       /* look up user rid */
-       names[0] = user_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       /* send user info query */
-       if (res1 && num_rids == 1)
-       {
-               msrpc_sam_user( &pol_dom, NULL,
-                               domain,
-                               &sid, NULL,
-                               rid[0], names[0],
-                   sam_display_user,
-                   request_user_info  ? sam_display_user_info     : NULL,
-                   request_group_info ? sam_display_group_members : NULL,
-                   request_alias_info ? sam_display_group_members : NULL);
-       }
-       else
-       {
-               res1 = False;
-       }
-
-       res = res ? samr_close( &sam_pol) : False;
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               DEBUG(5,("cmd_sam_query_user: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_user: failed\n"));
-       }
-}
-
-
-/****************************************************************************
-experimental SAM user set.
-****************************************************************************/
-void cmd_sam_set_userinfo2(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-       int opt;
-       BOOL set_acb_bits = False;
-
-       fstring user_name;
-
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-       SAM_USER_INFO_16 usr16;
-       uint16 acb_set = 0x0;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samuserset2 <name> [-s <acb_bits>]\n");
-               return;
-       }
-
-       argc--;
-       argv++;
-
-       safe_strcpy(user_name, argv[0], sizeof(user_name));
-
-       while ((opt = getopt(argc, argv,"s:")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 's':
-                       {
-                               set_acb_bits = True;
-                               acb_set = get_number(optarg);
-                               break;
-                       }
-               }
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Set User Info: %s\n", user_name);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x02000000, &sid,
-                   &pol_dom) : False;
-
-       /* look up user rid */
-       names[0] = user_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       /* send set user info */
-       if (res1 && num_rids == 1 && get_samr_query_userinfo( &pol_dom,
-                                                   0x10, rid[0],
-                                                   (void*)&usr16))
-       {
-               void *usr = NULL;
-               uint32 switch_value = 0;
-
-               if (set_acb_bits)
-               {
-                       usr16.acb_info |= acb_set;
-               }
-
-               if (True)
-               {
-                       SAM_USER_INFO_16 *p = (SAM_USER_INFO_16 *)malloc(sizeof(SAM_USER_INFO_16));
-                       p->acb_info = usr16.acb_info;
-
-                       usr = (void*)p;
-                       switch_value = 16;
-               }
-               
-               if (usr != NULL)
-               {
-                       res1 = set_samr_set_userinfo2( &pol_dom,
-                                           switch_value, rid[0], usr);
-               }
-       }
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               report(out_hnd, "Set User Info: OK\n");
-               DEBUG(5,("cmd_sam_query_user: succeeded\n"));
-       }
-       else
-       {
-               report(out_hnd, "Set User Info: Failed\n");
-               DEBUG(5,("cmd_sam_query_user: failed\n"));
-       }
-}
-
-/****************************************************************************
-experimental SAM user set.
-****************************************************************************/
-void cmd_sam_set_userinfo(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-       int opt;
-       BOOL set_passwd = False;
-
-       fstring user_name;
-       fstring password;
-
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-       SAM_USER_INFO_21 usr21;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       argc--;
-       argv++;
-
-       if (argc == 0)
-       {
-               report(out_hnd, "samuserset <name> [-p password]\n");
-               return;
-       }
-
-       safe_strcpy(user_name, argv[0], sizeof(user_name));
-
-       if (argc == 1)
-       {
-               fstring pass_str;
-               char *pass;
-               slprintf(pass_str, sizeof(pass_str)-1, "Enter %s's Password:",
-                        user_name);
-               pass = (char*)getpass(pass_str);
-
-               if (pass != NULL)
-               {
-                       safe_strcpy(password, pass,
-                                   sizeof(password)-1);
-                       set_passwd = True;
-               }
-       }
-       else
-       {
-               while ((opt = getopt(argc, argv,"p:")) != EOF)
-               {
-                       switch (opt)
-                       {
-                               case 'p':
-                               {
-                                       set_passwd = True;
-                                       safe_strcpy(password, optarg,
-                                                   sizeof(password)-1);
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Set User Info: %s\n", user_name);
-       report(out_hnd, "Password: %s\n", password);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x02000000, &sid,
-                   &pol_dom) : False;
-
-       /* look up user rid */
-       names[0] = user_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       /* send set user info */
-       if (res1 && num_rids == 1 && get_samr_query_userinfo( &pol_dom,
-                                                   0x15, rid[0], &usr21))
-       {
-               void *usr = NULL;
-               uint32 switch_value = 0;
-               char pwbuf[516];
-
-               if (set_passwd)
-               {
-                       encode_pw_buffer(pwbuf, password,
-                                      strlen(password), True);
-               }
-
-               if (True)
-               {
-                       SAM_USER_INFO_24 *p = (SAM_USER_INFO_24*)malloc(sizeof(SAM_USER_INFO_24));
-                       make_sam_user_info24(p, pwbuf, strlen(password));
-
-                       usr = p;
-                       switch_value = 24;
-               }
-               
-               if (False)
-               {
-                       SAM_USER_INFO_23 *p = (SAM_USER_INFO_23*)malloc(sizeof(SAM_USER_INFO_23));
-                       /* send user info query, level 0x15 */
-                       make_sam_user_info23W(p,
-                               &usr21.logon_time, 
-                               &usr21.logoff_time, 
-                               &usr21.kickoff_time, 
-                               &usr21.pass_last_set_time, 
-                               &usr21.pass_can_change_time, 
-                               &usr21.pass_must_change_time, 
-
-                               &usr21.uni_user_name, 
-                               &usr21.uni_full_name,
-                               &usr21.uni_home_dir,
-                               &usr21.uni_dir_drive,
-                               &usr21.uni_logon_script,
-                               &usr21.uni_profile_path,
-                               &usr21.uni_acct_desc,
-                               &usr21.uni_workstations,
-                               &usr21.uni_unknown_str,
-                               &usr21.uni_munged_dial,
-
-                               0x0, 
-                               usr21.group_rid,
-                               usr21.acb_info, 
-
-                               0x09f827fa,
-                               usr21.logon_divs,
-                               &usr21.logon_hrs,
-                               usr21.unknown_5,
-                               pwbuf,
-                               usr21.unknown_6);
-
-                       usr = p;
-                       switch_value = 23;
-               }
-               if (usr != NULL)
-               {
-                       res1 = set_samr_set_userinfo( &pol_dom,
-                                           switch_value, rid[0], usr);
-               }
-       }
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               report(out_hnd, "Set User Info: OK\n");
-               DEBUG(5,("cmd_sam_query_user: succeeded\n"));
-       }
-       else
-       {
-               report(out_hnd, "Set User Info: Failed\n");
-               DEBUG(5,("cmd_sam_query_user: failed\n"));
-       }
-}
-
-static void sam_display_disp_info(const char* domain, const DOM_SID *sid,
-                               uint16 info, uint32 num,
-                               SAM_DISPINFO_CTR *ctr)
-                               
-{
-       report(out_hnd, "SAM Display Info for Domain %s\n", domain);
-
-       display_sam_disp_info_ctr(out_hnd, ACTION_HEADER   , info, num, ctr);
-       display_sam_disp_info_ctr(out_hnd, ACTION_ENUMERATE, info, num, ctr);
-       display_sam_disp_info_ctr(out_hnd, ACTION_FOOTER   , info, num, ctr);
-}
-
-/****************************************************************************
-experimental SAM query display info.
-****************************************************************************/
-void cmd_sam_query_dispinfo(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       uint16 switch_value = 1;
-       SAM_DISPINFO_CTR ctr;
-       SAM_DISPINFO_1 inf1;
-       uint32 num_entries;
-
-       sid_to_string(sid, &info->dom.level5_sid);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       string_to_sid(&sid1, sid);
-
-       if (sid1.num_auths == 0)
-       {
-               fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       if (argc > 1)
-       {
-               switch_value = strtoul(argv[1], (char**)NULL, 10);
-       }
-
-       ctr.sam.info1 = &inf1;
-
-       if (msrpc_sam_query_dispinfo( srv_name, domain, &sid1,
-                   switch_value, 
-                   &num_entries, &ctr, sam_display_disp_info))
-       {
-
-               DEBUG(5,("cmd_sam_query_dispinfo: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_dispinfo: failed\n"));
-       }
-}
-
-/****************************************************************************
-experimental SAM domain info query.
-****************************************************************************/
-void cmd_sam_query_dominfo(struct client_info *info, int argc, char *argv[])
-{
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       uint32 switch_value = 2;
-       SAM_UNK_CTR ctr;
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid, &info->dom.level5_sid);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       string_to_sid(&sid1, sid);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc > 1)
-       {
-               switch_value = strtoul(argv[1], (char**)NULL, 10);
-       }
-
-       if (sam_query_dominfo(srv_name, &sid1, switch_value, &ctr))
-       {
-               DEBUG(5,("cmd_sam_query_dominfo: succeeded\n"));
-               sam_display_dom_info(domain, &sid1, switch_value, &ctr);
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_dominfo: failed\n"));
-       }
-}
-
-/****************************************************************************
-experimental SAM alias query members.
-****************************************************************************/
-void cmd_sam_query_aliasmem(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-
-       char *alias_name;
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samaliasmem <name>\n");
-               return;
-       }
-
-       alias_name = argv[1];
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Query Alias: %s\n", alias_name);
-       report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
-                         info->myhostname, srv_name, domain, sid_str);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
-                   &pol_dom) : False;
-
-       /* look up alias rid */
-       names[0] = alias_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
-       {
-               res1 = req_aliasmem_info(srv_name,
-                               &pol_dom,
-                               domain,
-                               &sid,
-                               rid[0],
-                               names[0],
-                               sam_display_alias_members);
-       }
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               DEBUG(5,("cmd_sam_query_alias: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_alias: failed\n"));
-       }
-}
-
-
-/****************************************************************************
-experimental SAM alias query.
-****************************************************************************/
-void cmd_sam_query_alias(struct client_info *info, int argc, char *argv[])
-{
-       fstring srv_name;
-       fstring domain;
-       fstring sid_str;
-       DOM_SID sid;
-       BOOL res = True;
-       BOOL res1 = True;
-
-       char *alias_name;
-       char *names[1];
-       uint32 num_rids;
-       uint32 rid[MAX_LOOKUP_SIDS];
-       uint32 type[MAX_LOOKUP_SIDS];
-       POLICY_HND sam_pol;
-       POLICY_HND pol_dom;
-
-       fstrcpy(domain, info->dom.level5_dom);
-       sid_copy(&sid, &info->dom.level5_sid);
-
-       if (sid.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       if (argc < 2)
-       {
-               report(out_hnd, "samalias <name>\n");
-               return;
-       }
-
-       alias_name = argv[1];
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       sid_to_string(sid_str, &sid);
-
-       report(out_hnd, "SAM Query Alias: %s\n", alias_name);
-       report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
-                         info->myhostname, srv_name, domain, sid_str);
-
-       /* establish a connection. */
-       res = res ? samr_connect( srv_name, 0x02000000,
-                               &sam_pol) : False;
-
-       /* connect to the domain */
-       res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
-                   &pol_dom) : False;
-
-       /* look up alias rid */
-       names[0] = alias_name;
-       res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
-                                       1, names,
-                                       &num_rids, rid, type) : False;
-
-       if (res1 && num_rids == 1)
-       {
-               res1 = query_aliasinfo( &pol_dom,
-                               domain,
-                               &sid,
-                               rid[0],
-                               sam_display_alias_info);
-       }
-
-       res = res ? samr_close( &sam_pol) : False;
-
-       res = res ? samr_close( &pol_dom) : False;
-
-       if (res1)
-       {
-               DEBUG(5,("cmd_sam_query_alias: succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_sam_query_alias: failed\n"));
-       }
-}
-
-
-/****************************************************************************
-SAM aliases query.
-****************************************************************************/
-void cmd_sam_enum_aliases(struct client_info *info, int argc, char *argv[])
-{
-       BOOL request_member_info = False;
-       BOOL request_alias_info = False;
-       struct acct_info *sam = NULL;
-       uint32 num_sam_entries = 0;
-       int opt;
-
-       fstring domain;
-       fstring srv_name;
-       fstring sid;
-       DOM_SID sid1;
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       while ((opt = getopt(argc, argv, "ma")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'm':
-                       {
-                               request_member_info  = True;
-                               break;
-                       }
-                       case 'a':
-                       {
-                               request_alias_info = True;
-                               break;
-                       }
-               }
-       }
-
-       report(out_hnd, "SAM Enumerate Aliases\n");
-
-       msrpc_sam_enum_aliases(srv_name, domain, &sid1, 
-                   &sam, &num_sam_entries,
-                   sam_display_alias,
-                   request_alias_info  ? sam_display_alias_info    : NULL,
-                   request_member_info ? sam_display_alias_members : NULL);
-
-       if (sam != NULL)
-       {
-               free(sam);
-       }
-}
-
-/****************************************************************************
-experimental SAM groups enum.
-****************************************************************************/
-void cmd_sam_enum_groups(struct client_info *info, int argc, char *argv[])
-{
-       BOOL request_member_info = False;
-       BOOL request_group_info = False;
-       struct acct_info *sam = NULL;
-       uint32 num_sam_entries = 0;
-       int opt;
-
-       fstring srv_name;
-       fstring domain;
-       fstring sid;
-       DOM_SID sid1;
-       sid_copy(&sid1, &info->dom.level5_sid);
-       sid_to_string(sid, &sid1);
-       fstrcpy(domain, info->dom.level5_dom);
-
-       if (sid1.num_auths == 0)
-       {
-               report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
-               return;
-       }
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       while ((opt = getopt(argc, argv, "mg")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'm':
-                       {
-                               request_member_info  = True;
-                               break;
-                       }
-                       case 'g':
-                       {
-                               request_group_info = True;
-                               break;
-                       }
-               }
-       }
-
-       report(out_hnd, "SAM Enumerate Groups\n");
-
-       msrpc_sam_enum_groups(srv_name, domain, &sid1, 
-                   &sam, &num_sam_entries,
-                   sam_display_group,
-                   request_group_info  ? sam_display_group_info    : NULL,
-                   request_member_info ? sam_display_group_members : NULL);
-
-       if (sam != NULL)
-       {
-               free(sam);
-       }
-}
-
-/****************************************************************************
-experimental SAM domains enum.
-****************************************************************************/
-void cmd_sam_enum_domains(struct client_info *info, int argc, char *argv[])
-{
-       BOOL request_domain_info = False;
-       struct acct_info *sam = NULL;
-       uint32 num_sam_entries = 0;
-       int opt;
-
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, info->dest_host);
-       strupper(srv_name);
-
-       while ((opt = getopt(argc, argv, "i")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'i':
-                       {
-                               request_domain_info= True;
-                               break;
-                       }
-               }
-       }
-
-       report(out_hnd, "SAM Enumerate Domains\n");
-
-       msrpc_sam_enum_domains(srv_name,
-                   &sam, &num_sam_entries,
-                   request_domain_info ? NULL : sam_display_domain,
-                   request_domain_info ? sam_display_dom_info : NULL);
-
-       if (sam != NULL)
-       {
-               free(sam);
-       }
-}
 
index f0b10fe0d6ea3cecb1fddb6a58f3fe9835488ded..9deb9e801c6cc2274a62d0d551c44731ebef162f 100644 (file)
@@ -2,8 +2,8 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    NT Domain Authentication SMB / MSRPC client
-   Copyright (C) Andrew Tridgell 1994-1999
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    
    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
@@ -33,49 +33,50 @@ extern int DEBUGLEVEL;
 
 #define DEBUG_TESTING
 
+extern struct cli_state *smb_cli;
+
 extern FILE* out_hnd;
 
 
 /****************************************************************************
 server get info query
 ****************************************************************************/
-BOOL net_srv_get_info(struct client_info *info,
-               uint32 info_level,
-               SRV_INFO_CTR *ctr)
+void cmd_srv_query_info(struct client_info *info)
 {
        fstring dest_srv;
+       fstring tmp;
+       SRV_INFO_CTR ctr;
+       uint32 info_level = 101;
 
        BOOL res = True;
 
+       memset((char *)&ctr, '\0', sizeof(ctr));
+
        fstrcpy(dest_srv, "\\\\");
        fstrcat(dest_srv, info->dest_host);
        strupper(dest_srv);
 
-       DEBUG(4,("net_srv_get_info: server:%s info level: %d\n",
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+       {
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+       }
+
+       DEBUG(4,("cmd_srv_query_info: server:%s info level: %d\n",
                                dest_srv, (int)info_level));
 
-       /* send info level: receive requested info.  hopefully. */
-       res = res ? srv_net_srv_get_info(dest_srv, info_level, ctr) : False;
+       DEBUG(5, ("cmd_srv_query_info: smb_cli->fd:%d\n", smb_cli->fd));
 
-       return res;
-}
+       /* open LSARPC session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
 
-/****************************************************************************
-server get info query
-****************************************************************************/
-void cmd_srv_query_info(struct client_info *info, int argc, char *argv[])
-{
-       uint32 info_level = 101;
-       SRV_INFO_CTR ctr;
-
-       bzero(&ctr, sizeof(ctr));
+       /* send info level: receive requested info.  hopefully. */
+       res = res ? do_srv_net_srv_get_info(smb_cli,
+                               dest_srv, info_level, &ctr) : False;
 
-       if (argc > 1)
-       {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
-       }
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
-       if (net_srv_get_info(info, info_level, &ctr))
+       if (res)
        {
                DEBUG(5,("cmd_srv_query_info: query succeeded\n"));
 
@@ -89,83 +90,21 @@ void cmd_srv_query_info(struct client_info *info, int argc, char *argv[])
        }
 }
 
-/****************************************************************************
-server enum transports
-****************************************************************************/
-BOOL msrpc_srv_enum_tprt( const char* dest_srv,
-                               uint32 info_level,
-                               SRV_TPRT_INFO_CTR *ctr,
-                               TPRT_INFO_FN(tprt_fn))
-{
-       BOOL res = True;
-       BOOL res1 = True;
-
-       ENUM_HND hnd;
-
-       hnd.ptr_hnd = 1;
-       hnd.handle = 0;
-
-       /* enumerate transports on server */
-       res1 = res ? srv_net_srv_tprt_enum(dest_srv, 
-                   info_level, ctr, 0xffffffff, &hnd) : False;
-
-       tprt_fn(ctr);
-
-       free_srv_tprt_ctr(ctr);
-
-       return res1;
-}
-
-static void srv_display_tprt_ctr(const SRV_TPRT_INFO_CTR *ctr)
-{
-       display_srv_tprt_info_ctr(out_hnd, ACTION_HEADER   , ctr);
-       display_srv_tprt_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
-       display_srv_tprt_info_ctr(out_hnd, ACTION_FOOTER   , ctr);
-}
-
-/****************************************************************************
-server enum transports
-****************************************************************************/
-void cmd_srv_enum_tprt(struct client_info *info, int argc, char *argv[])
-{
-       fstring dest_srv;
-       SRV_TPRT_INFO_CTR ctr;
-       uint32 info_level = 0;
-
-       bzero(&ctr, sizeof(ctr));
-
-       fstrcpy(dest_srv, "\\\\");
-       fstrcat(dest_srv, info->dest_host);
-       strupper(dest_srv);
-
-       if (argc > 1)
-       {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
-       }
-
-       DEBUG(4,("cmd_srv_enum_tprt: server:%s info level: %d\n",
-                               dest_srv, (int)info_level));
-
-       /* enumerate transports on server */
-       msrpc_srv_enum_tprt(dest_srv, 
-                   info_level, &ctr, 
-                   srv_display_tprt_ctr);
-}
-
 /****************************************************************************
 server enum connections
 ****************************************************************************/
-void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[])
+void cmd_srv_enum_conn(struct client_info *info)
 {
        fstring dest_srv;
        fstring qual_srv;
+       fstring tmp;
        SRV_CONN_INFO_CTR ctr;
        ENUM_HND hnd;
        uint32 info_level = 0;
 
        BOOL res = True;
 
-       bzero(&ctr, sizeof(ctr));
+       memset((char *)&ctr, '\0', sizeof(ctr));
 
        fstrcpy(qual_srv, "\\\\");
        fstrcat(qual_srv, info->myhostname);
@@ -175,19 +114,25 @@ void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[])
        fstrcat(dest_srv, info->dest_host);
        strupper(dest_srv);
 
-       if (argc > 1)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
        {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        DEBUG(4,("cmd_srv_enum_conn: server:%s info level: %d\n",
                                dest_srv, (int)info_level));
 
+       DEBUG(5, ("cmd_srv_enum_conn: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open srvsvc session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
        hnd.ptr_hnd = 1;
        hnd.handle = 0;
 
        /* enumerate connections on server */
-       res = res ? srv_net_srv_conn_enum(dest_srv, qual_srv,
+       res = res ? do_srv_net_srv_conn_enum(smb_cli,
+                               dest_srv, qual_srv,
                    info_level, &ctr, 0xffffffff, &hnd) : False;
 
        if (res)
@@ -197,6 +142,9 @@ void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[])
                display_srv_conn_info_ctr(out_hnd, ACTION_FOOTER   , &ctr);
        }
 
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
        if (res)
        {
                DEBUG(5,("cmd_srv_enum_conn: query succeeded\n"));
@@ -210,43 +158,52 @@ void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 server enum shares
 ****************************************************************************/
-void cmd_srv_enum_shares(struct client_info *info, int argc, char *argv[])
+void cmd_srv_enum_shares(struct client_info *info)
 {
        fstring dest_srv;
-       SRV_SHARE_INFO_CTR ctr;
+       fstring tmp;
+       SRV_R_NET_SHARE_ENUM r_o;
        ENUM_HND hnd;
        uint32 info_level = 1;
 
        BOOL res = True;
 
-       bzero(&ctr, sizeof(ctr));
-
        fstrcpy(dest_srv, "\\\\");
        fstrcat(dest_srv, info->dest_host);
        strupper(dest_srv);
 
-       if (argc > 1)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
        {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        DEBUG(4,("cmd_srv_enum_shares: server:%s info level: %d\n",
                                dest_srv, (int)info_level));
 
+       DEBUG(5, ("cmd_srv_enum_shares: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open srvsvc session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
        hnd.ptr_hnd = 0;
        hnd.handle = 0;
 
        /* enumerate shares_files on server */
-       res = res ? srv_net_srv_share_enum(dest_srv, 
-                   info_level, &ctr, 0xffffffff, &hnd) : False;
+       res = res ? do_srv_net_srv_share_enum(smb_cli,
+                               dest_srv, 
+                   info_level, &r_o, 0xffffffff, &hnd) : False;
 
        if (res)
        {
-               display_srv_share_info_ctr(out_hnd, ACTION_HEADER   , &ctr);
-               display_srv_share_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
-               display_srv_share_info_ctr(out_hnd, ACTION_FOOTER   , &ctr);
+               display_srv_share_info_ctr(out_hnd, ACTION_HEADER   , &r_o.ctr);
+               display_srv_share_info_ctr(out_hnd, ACTION_ENUMERATE, &r_o.ctr);
+               display_srv_share_info_ctr(out_hnd, ACTION_FOOTER   , &r_o.ctr);
+               free_srv_r_net_share_enum(&r_o);
        }
 
+       /* close the session */
+       cli_nt_session_close(smb_cli);
+
        if (res)
        {
                DEBUG(5,("cmd_srv_enum_shares: query succeeded\n"));
@@ -260,42 +217,44 @@ void cmd_srv_enum_shares(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 server enum sessions
 ****************************************************************************/
-void cmd_srv_enum_sess(struct client_info *info, int argc, char *argv[])
+void cmd_srv_enum_sess(struct client_info *info)
 {
        fstring dest_srv;
+       fstring tmp;
        SRV_SESS_INFO_CTR ctr;
        ENUM_HND hnd;
        uint32 info_level = 0;
 
        BOOL res = True;
 
-       bzero(&ctr, sizeof(ctr));
+       memset((char *)&ctr, '\0', sizeof(ctr));
 
        fstrcpy(dest_srv, "\\\\");
        fstrcat(dest_srv, info->dest_host);
        strupper(dest_srv);
 
-       if (argc > 1)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
        {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        DEBUG(4,("cmd_srv_enum_sess: server:%s info level: %d\n",
                                dest_srv, (int)info_level));
 
+       DEBUG(5, ("cmd_srv_enum_sess: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open srvsvc session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
        hnd.ptr_hnd = 1;
        hnd.handle = 0;
 
        /* enumerate sessions on server */
-       res = res ? srv_net_srv_sess_enum(dest_srv, NULL, NULL,
-                                info_level, &ctr, 0x1000, &hnd) : False;
+       res = res ? do_srv_net_srv_sess_enum(smb_cli,
+                               dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
 
-       if (res)
-       {
-               display_srv_sess_info_ctr(out_hnd, ACTION_HEADER   , &ctr);
-               display_srv_sess_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
-               display_srv_sess_info_ctr(out_hnd, ACTION_FOOTER   , &ctr);
-       }
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
@@ -310,35 +269,42 @@ void cmd_srv_enum_sess(struct client_info *info, int argc, char *argv[])
 /****************************************************************************
 server enum files
 ****************************************************************************/
-void cmd_srv_enum_files(struct client_info *info, int argc, char *argv[])
+void cmd_srv_enum_files(struct client_info *info)
 {
        fstring dest_srv;
+       fstring tmp;
        SRV_FILE_INFO_CTR ctr;
        ENUM_HND hnd;
        uint32 info_level = 3;
 
        BOOL res = True;
 
-       bzero(&ctr, sizeof(ctr));
+       memset((char *)&ctr, '\0', sizeof(ctr));
 
        fstrcpy(dest_srv, "\\\\");
        fstrcat(dest_srv, info->dest_host);
        strupper(dest_srv);
 
-       if (argc > 1)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
        {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        DEBUG(4,("cmd_srv_enum_files: server:%s info level: %d\n",
                                dest_srv, (int)info_level));
 
+       DEBUG(5, ("cmd_srv_enum_files: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open srvsvc session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
        hnd.ptr_hnd = 1;
        hnd.handle = 0;
 
        /* enumerate files on server */
-       res = res ? srv_net_srv_file_enum(dest_srv, NULL, 0,
-                       info_level, &ctr, 0x1000, &hnd) : False;
+       res = res ? do_srv_net_srv_file_enum(smb_cli,
+                               dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
+
 
        if (res)
        {
@@ -347,39 +313,8 @@ void cmd_srv_enum_files(struct client_info *info, int argc, char *argv[])
                display_srv_file_info_ctr(out_hnd, ACTION_FOOTER   , &ctr);
        }
 
-       if (res)
-       {
-               DEBUG(5,("cmd_srv_enum_files: query succeeded\n"));
-       }
-       else
-       {
-               DEBUG(5,("cmd_srv_enum_files: query failed\n"));
-       }
-}
-
-/****************************************************************************
-display remote time
-****************************************************************************/
-void cmd_time(struct client_info *info, int argc, char *argv[])
-{
-       fstring dest_srv;
-       TIME_OF_DAY_INFO tod;
-       BOOL res = True;
-
-       fstrcpy(dest_srv, "\\\\");
-       fstrcat(dest_srv, info->dest_host);
-       strupper(dest_srv);
-
-       DEBUG(4,("cmd_time: server:%s\n", dest_srv));
-
-       /* enumerate files on server */
-       res = res ? srv_net_remote_tod(dest_srv, &tod) : False;
-
-       if (res)
-       {
-               fprintf(out_hnd, "\tRemote Time:\t%s\n\n",
-                       http_timestring(tod.elapsedt));
-       }
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
@@ -390,3 +325,4 @@ void cmd_time(struct client_info *info, int argc, char *argv[])
                DEBUG(5,("cmd_srv_enum_files: query failed\n"));
        }
 }
+
index 474c53f347ee8716ca4cdbe2dccab2ccab481422..0b8f469af372625d51857c29e5feedeaba92d0ec 100644 (file)
@@ -33,36 +33,48 @@ extern int DEBUGLEVEL;
 
 #define DEBUG_TESTING
 
+extern struct cli_state *smb_cli;
+
 extern FILE* out_hnd;
 
 
 /****************************************************************************
 workstation get info query
 ****************************************************************************/
-void cmd_wks_query_info(struct client_info *info, int argc, char *argv[])
+void cmd_wks_query_info(struct client_info *info)
 {
        fstring dest_wks;
+       fstring tmp;
        WKS_INFO_100 ctr;
        uint32 info_level = 100;
 
        BOOL res = True;
 
-       bzero(&ctr, sizeof(ctr));
+       memset((char *)&ctr, '\0', sizeof(ctr));
 
        fstrcpy(dest_wks, "\\\\");
        fstrcat(dest_wks, info->dest_host);
        strupper(dest_wks);
 
-       if (argc > 1)
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+               info_level = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        DEBUG(4,("cmd_wks_query_info: server:%s info level: %d\n",
                                dest_wks, info_level));
 
+       DEBUG(5, ("cmd_wks_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+
+       /* open LSARPC session. */
+       res = res ? cli_nt_session_open(smb_cli, PIPE_WKSSVC) : False;
+
        /* send info level: receive requested info.  hopefully. */
-       res = res ? wks_query_info( dest_wks, info_level, &ctr) : False;
+       res = res ? do_wks_query_info(smb_cli, 
+                               dest_wks, info_level, &ctr) : False;
+
+       /* close the session */
+       cli_nt_session_close(smb_cli);
 
        if (res)
        {
index 517697a8c5bbe3dfe53d0b55c39ebd110701d8a2..0750d8dbb8d3a250ec4c3550dc7fe2043ef143a1 100644 (file)
@@ -39,570 +39,137 @@ extern pstring user_socket_options;
 extern int DEBUGLEVEL;
 
 
+extern file_info def_finfo;
+
 #define CNV_LANG(s) dos2unix_format(s,False)
 #define CNV_INPUT(s) unix2dos_format(s,True)
 
 static int process_tok(fstring tok);
-static void cmd_help(struct client_info *info, int argc, char *argv[]);
-static void cmd_quit(struct client_info *info, int argc, char *argv[]);
-static void cmd_set (struct client_info *info, int argc, char *argv[]);
-static void cmd_net (struct client_info *info, int argc, char *argv[]);
-
-static struct ntuser_creds usr;
+static void cmd_help(struct client_info *info);
+static void cmd_quit(struct client_info *info);
 
-static struct client_info cli_info;
-
-static char  **cmd_argv = NULL;
-static uint32 cmd_argc = 0;
+static struct cli_state smbcli;
+struct cli_state *smb_cli = &smbcli;
 
 FILE *out_hnd;
 
-#define COMPL_NONE 0
-#define COMPL_REGKEY 1
-#define COMPL_SAMUSR 3
-#define COMPL_SAMGRP 4
-#define COMPL_SAMALS 5
-#define COMPL_SVCLST 6
-#define COMPL_PRTLST 7
-
 /****************************************************************************
- This defines the commands supported by this client
- ****************************************************************************/
-struct command_set commands[] = 
+initialise smb client structure
+****************************************************************************/
+void rpcclient_init(void)
 {
-       /*
-        * eventlog
-        */
-
-       {
-               "eventlog",
-               cmd_eventlog,
-               "list the events",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * service control
-        */
-
-       {
-               "svcenum",
-               cmd_svc_enum,
-               "[-i] Lists Services Manager",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       {
-               "svcinfo",
-               cmd_svc_info,
-               "<service> Service Information",
-               {COMPL_SVCLST, COMPL_NONE}
-       },
-
-       {
-               "svcstart",
-               cmd_svc_start,
-               "<service> [arg 0] [arg 1] ... Start Service",
-               {COMPL_SVCLST, COMPL_NONE}
-       },
-
-       {
-               "svcset",
-               cmd_svc_set,
-               "<service> Test Set Service",
-               {COMPL_SVCLST, COMPL_NONE}
-       },
-
-       {
-               "svcstop",
-               cmd_svc_stop,
-               "<service> Stop Service",
-               {COMPL_SVCLST, COMPL_NONE}
-       },
-
-       /*
-        * scheduler
-        */
-
-       {
-               "at",
-               cmd_at,
-               "Scheduler control (at /? for syntax)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * registry
-        */
-
-       {
-               "regenum",
-               cmd_reg_enum,
-               "<keyname> Registry Enumeration (keys, values)",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "regdeletekey",
-               cmd_reg_delete_key,
-               "<keyname> Registry Key Delete",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "regcreatekey",
-               cmd_reg_create_key,
-               "<keyname> [keyclass] Registry Key Create",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "shutdown",
-               cmd_reg_shutdown,
-               "[-m message] [-t timeout] [-r or --reboot] [-f or --force-close] Remote Shutdown",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "regqueryval",
-               cmd_reg_query_info,
-               "<valname> Registry Value Query",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "regquerykey",
-               cmd_reg_query_key,
-               "<keyname> Registry Key Query",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "regdeleteval",
-               cmd_reg_delete_val,
-               "<valname> Registry Value Delete",
-               {COMPL_REGKEY, COMPL_REGKEY}
-       },
-       {
-               "regcreateval",
-               cmd_reg_create_val,
-               "<valname> <valtype> <value> Registry Key Create",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "reggetsec",
-               cmd_reg_get_key_sec,
-               "<keyname> Registry Key Security",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-       {
-               "regtestsec",
-               cmd_reg_test_key_sec,
-               "<keyname> Test Registry Key Security",
-               {COMPL_REGKEY, COMPL_NONE}
-       },
-
-       /*
-        * printer testing
-        */
-
-       {
-               "spoolenum",
-               cmd_spoolss_enum_printers,
-               "Enumerate Printers",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "spooljobs",
-               cmd_spoolss_enum_jobs,
-               "<printer name> Enumerate Printer Jobs",
-               {COMPL_PRTLST, COMPL_NONE}
-       },
-       {
-               "spoolopen",
-               cmd_spoolss_open_printer_ex,
-               "<printer name> Spool Printer Open Test",
-               {COMPL_PRTLST, COMPL_NONE}
-       },
-       /*
-        * server
-        */
-       {
-               "time",
-               cmd_time,
-               "Display remote time",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "brsinfo",
-               cmd_brs_query_info,
-               "Browser Query Info",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "wksinfo",
-               cmd_wks_query_info,
-               "Workstation Query Info",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvinfo",
-               cmd_srv_query_info,
-               "Server Query Info",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvsessions",
-               cmd_srv_enum_sess,
-               "List sessions on a server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvshares",
-               cmd_srv_enum_shares,
-               "List shares on a server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvtransports",
-               cmd_srv_enum_tprt,
-               "List transports on a server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvconnections",
-               cmd_srv_enum_conn,
-               "List connections on a server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "srvfiles",
-               cmd_srv_enum_files,
-               "List files on a server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * lsa
-        */
-
-       {
-               "lsaquery",
-               cmd_lsa_query_info,
-               "Query Info Policy (domain member or server)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "lsaenumdomains",
-               cmd_lsa_enum_trust_dom,
-               "Enumerate Trusted Domains",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "lookupsids",
-               cmd_lsa_lookup_sids,
-               "Resolve names from SIDs",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "lookupnames",
-               cmd_lsa_lookup_names,
-               "Resolve SIDs from names",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "querysecret",
-               cmd_lsa_query_secret,
-               "LSA Query Secret (developer use)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * netlogon
-        */
-
-       {
-               "ntlogin",
-               cmd_netlogon_login_test,
-               "[[DOMAIN\\]username] [password] NT Domain login test",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "domtrust",
-               cmd_netlogon_domain_test,
-               "<domain> NT Inter-Domain test",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * sam
-        */
-
-       {
-               "lookupdomain",
-               cmd_sam_lookup_domain,
-               "Obtain SID for a local domain",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "enumusers",
-               cmd_sam_enum_users,
-               "SAM User Database Query (experimental!)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "addgroupmem",
-               cmd_sam_add_groupmem,
-               "<group rid> [user] [user] ... SAM Add Domain Group Member",
-               {COMPL_SAMGRP, COMPL_SAMUSR}
-       },
-
-       {
-               "addaliasmem",
-               cmd_sam_add_aliasmem,
-               "<alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member",
-               {COMPL_SAMALS, COMPL_NONE}
-       },
-       {
-               "delgroupmem",
-               cmd_sam_del_groupmem,
-               "<group rid> [user] [user] ... SAM Delete Domain Group Member",
-               {COMPL_SAMGRP, COMPL_SAMUSR}
-       },
-       {
-               "delaliasmem",
-               cmd_sam_del_aliasmem,
-               "<alias rid> [member sid1] [member sid2] ... SAM Delete Domain Alias Member",
-               {COMPL_SAMALS, COMPL_NONE}
-       },
-       {
-               "creategroup",
-               cmd_sam_create_dom_group,
-               "SAM Create Domain Group",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "createalias",
-               cmd_sam_create_dom_alias,
-               "SAM Create Domain Alias",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "createuser",
-               cmd_sam_create_dom_user,
-               "<username> SAM Create Domain User",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "delgroup",
-               cmd_sam_delete_dom_group,
-               "SAM Delete Domain Group",
-               {COMPL_SAMGRP, COMPL_NONE}
-       },
-       {
-               "delalias",
-               cmd_sam_delete_dom_alias,
-               "SAM Delete Domain Alias",
-               {COMPL_SAMALS, COMPL_NONE}
-       },
-       {
-               "ntpass",
-               cmd_sam_ntchange_pwd,
-               "NT SAM Password Change",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "samuserset2",
-               cmd_sam_set_userinfo2,
-               "<username> [-s acb_bits] SAM User Set Info 2 (experimental!)",
-               {COMPL_SAMUSR, COMPL_NONE}
-       },
-       {
-               "samuserset",
-               cmd_sam_set_userinfo,
-               "<username> [-p password] SAM User Set Info (experimental!)",
-               {COMPL_SAMUSR, COMPL_NONE}
-       },
-       {
-               "samuser",
-               cmd_sam_query_user,
-               "<username> [-g] [-u] [-a] SAM User Query (experimental!)",
-               {COMPL_SAMUSR, COMPL_NONE}
-       },
-       {
-               "samgroup",
-               cmd_sam_query_group,
-               "<groupname> SAM Group Query (experimental!)",
-               {COMPL_SAMGRP, COMPL_NONE}
-       },
-       {
-               "samalias",
-               cmd_sam_query_alias,
-               "<aliasname> SAM Alias Query",
-               {COMPL_SAMALS, COMPL_NONE}
-       },
-       {
-               "samaliasmem",
-               cmd_sam_query_aliasmem,
-               "<aliasname> SAM Alias Members",
-               {COMPL_SAMALS, COMPL_NONE}
-       },
-       {
-               "samgroupmem",
-               cmd_sam_query_groupmem,
-               "SAM Group Members",
-               {COMPL_SAMGRP, COMPL_NONE}
-       },
-       {
-               "samtest",
-               cmd_sam_test      ,
-               "SAM User Encrypted RPC test (experimental!)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "enumaliases",
-               cmd_sam_enum_aliases,
-               "SAM Aliases Database Query (experimental!)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "enumdomains",
-               cmd_sam_enum_domains,
-               "SAM Domains Database Query (experimental!)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "enumgroups",
-               cmd_sam_enum_groups,
-               "SAM Group Database Query (experimental!)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "dominfo",
-               cmd_sam_query_dominfo,
-               "SAM Query Domain Info",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "dispinfo",
-               cmd_sam_query_dispinfo,
-               "SAM Query Display Info",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "samsync",
-               cmd_sam_sync,
-               "SAM Synchronization Test (experimental)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /* maintenance */
-
-       {
-               "set",
-               cmd_set,
-               "run rpcclient inside rpcclient (change options etc.)",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       {
-               "net",
-               cmd_net,
-               "net use and net view",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       /*
-        * bye bye
-        */
-
-       {
-               "quit",
-               cmd_quit,
-               "logoff the server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "q",
-               cmd_quit,
-               "logoff the server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "exit",
-               cmd_quit,
-               "logoff the server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "bye",
-               cmd_quit,
-               "logoff the server",
-               {COMPL_NONE, COMPL_NONE}
-       },
-
-       /*
-        * eek!
-        */
+       memset((char *)smb_cli, '\0', sizeof(smb_cli));
+       cli_initialise(smb_cli);
+       smb_cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32;
+}
 
-       {
-               "help",
-               cmd_help,
-               "[command] give help on a command",
-               {COMPL_NONE, COMPL_NONE}
-       },
-       {
-               "?",
-               cmd_help,
-               "[command] give help on a command",
-               {COMPL_NONE, COMPL_NONE}
-       },
+/****************************************************************************
+make smb client connection
+****************************************************************************/
+static BOOL rpcclient_connect(struct client_info *info)
+{
+       struct nmb_name calling;
+       struct nmb_name called;
 
-       /*
-        * shell
-        */
+       make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope);
+       make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0            , scope);
 
+       if (!cli_establish_connection(smb_cli, 
+                                 info->dest_host, &info->dest_ip, 
+                                 &calling, &called,
+                                 info->share, info->svc_type,
+                                 False, True))
        {
-               "!",
-               NULL,
-               "run a shell command on the local system",
-               {COMPL_NONE, COMPL_NONE}
-       },
+               DEBUG(0,("rpcclient_connect: connection failed\n"));
+               cli_shutdown(smb_cli);
+               return False;
+       }
 
-       /*
-        * oop!
-        */
+       return True;
+}
 
-       {
-               "",
-               NULL,
-               NULL,
-               {COMPL_NONE, COMPL_NONE}
-       }
+/****************************************************************************
+stop the smb connection(s?)
+****************************************************************************/
+static void rpcclient_stop(void)
+{
+       cli_shutdown(smb_cli);
+}
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+struct
+{
+  char *name;
+  void (*fn)(struct client_info*);
+  char *description;
+} commands[] = 
+{
+  {"regenum",    cmd_reg_enum,         "<keyname> Registry Enumeration (keys, values)"},
+  {"regdeletekey",cmd_reg_delete_key,  "<keyname> Registry Key Delete"},
+  {"regcreatekey",cmd_reg_create_key,  "<keyname> [keyclass] Registry Key Create"},
+  {"regquerykey",cmd_reg_query_key,    "<keyname> Registry Key Query"},
+  {"regdeleteval",cmd_reg_delete_val,  "<valname> Registry Value Delete"},
+  {"regcreateval",cmd_reg_create_val,  "<valname> <valtype> <value> Registry Key Create"},
+  {"reggetsec",  cmd_reg_get_key_sec,  "<keyname> Registry Key Security"},
+  {"regtestsec", cmd_reg_test_key_sec, "<keyname> Test Registry Key Security"},
+  {"ntlogin",    cmd_netlogon_login_test, "[username] [password] NT Domain login test"},
+  {"wksinfo",    cmd_wks_query_info,   "Workstation Query Info"},
+  {"srvinfo",    cmd_srv_query_info,   "Server Query Info"},
+  {"srvsessions",cmd_srv_enum_sess,    "List sessions on a server"},
+  {"srvshares",  cmd_srv_enum_shares,  "List shares on a server"},
+  {"srvconnections",cmd_srv_enum_conn, "List connections on a server"},
+  {"srvfiles",   cmd_srv_enum_files,   "List files on a server"},
+  {"lsaquery",   cmd_lsa_query_info,   "Query Info Policy (domain member or server)"},
+  {"lookupsids", cmd_lsa_lookup_sids,  "Resolve names from SIDs"},
+  {"enumusers",  cmd_sam_enum_users,   "SAM User Database Query (experimental!)"},
+  {"ntpass",     cmd_sam_ntchange_pwd, "NT SAM Password Change"},
+  {"samuser",    cmd_sam_query_user,   "<username> SAM User Query (experimental!)"},
+  {"samtest",    cmd_sam_test      ,   "SAM User Encrypted RPC test (experimental!)"},
+  {"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"},
+#if 0
+  {"enumgroups", cmd_sam_enum_groups,  "SAM Group Database Query (experimental!)"},
+#endif
+  {"samgroups",  cmd_sam_query_groups, "SAM Group Database Query (experimental!)"},
+  {"quit",       cmd_quit,        "logoff the server"},
+  {"q",          cmd_quit,        "logoff the server"},
+  {"exit",       cmd_quit,        "logoff the server"},
+  {"bye",        cmd_quit,        "logoff the server"},
+  {"help",       cmd_help,        "[command] give help on a command"},
+  {"?",          cmd_help,        "[command] give help on a command"},
+  {"!",          NULL,            "run a shell command on the local system"},
+  {"",           NULL,            NULL}
 };
 
 
 /****************************************************************************
 do a (presumably graceful) quit...
 ****************************************************************************/
-static void cmd_quit(struct client_info *info, int argc, char *argv[])
+static void cmd_quit(struct client_info *info)
 {
+       rpcclient_stop();
 #ifdef MEM_MAN
        {
                extern FILE* dbf;
                smb_mem_write_status(dbf);
                smb_mem_write_errors(dbf);
                smb_mem_write_verbose(dbf);
-               dbgflush();
        }
 #endif
-       free_connections();
        exit(0);
 }
 
 /****************************************************************************
 help
 ****************************************************************************/
-static void cmd_help(struct client_info *info, int argc, char *argv[])
+static void cmd_help(struct client_info *info)
 {
   int i=0,j;
+  fstring buf;
 
-  if (argc > 1)
+  if (next_token(NULL,buf,NULL, sizeof(buf)))
     {
-      if ((i = process_tok(argv[1])) >= 0)
+      if ((i = process_tok(buf)) >= 0)
        fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);                    
     }
   else
@@ -620,7 +187,7 @@ static void cmd_help(struct client_info *info, int argc, char *argv[])
   lookup a command string in the list of commands, including 
   abbreviations
   ******************************************************************/
-static int process_tok(char *tok)
+static int process_tok(fstring tok)
 {
   int i = 0, matches = 0;
   int cmd=0;
@@ -651,917 +218,204 @@ static int process_tok(char *tok)
 }
 
 /****************************************************************************
-  turn command line into command argument array
+wait for keyboard activity, swallowing network packets
 ****************************************************************************/
-static BOOL get_cmd_args(char *line)
+static void wait_keyboard(struct cli_state *cli)
 {
-       char *ptr = line;
-       pstring tok;
-       cmd_argc = 0;
-       cmd_argv = NULL;
-
-       /* get the first part of the command */
-       if (!next_token(&ptr,tok,NULL, sizeof(tok)))
-       {
-               return False;
-       }
-
-       do
-       {
-               add_chars_to_array(&cmd_argc, &cmd_argv, tok);
-
-       } while (next_token(NULL, tok, NULL, sizeof(tok)));
-
-       return True;
+  fd_set fds;
+  struct timeval timeout;
+  
+  while (1) 
+    {
+      FD_ZERO(&fds);
+      FD_SET(cli->fd,&fds);
+      FD_SET(fileno(stdin),&fds);
+
+      timeout.tv_sec = 20;
+      timeout.tv_usec = 0;
+      sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
+      
+      if (FD_ISSET(fileno(stdin),&fds))
+       return;
+
+      /* We deliberately use receive_smb instead of
+         client_receive_smb as we want to receive
+         session keepalives and then drop them here.
+       */
+      if (FD_ISSET(cli->fd,&fds))
+       receive_smb(cli->fd,cli->inbuf,0);
+    }  
 }
 
-/* command options mask */
-static uint32 cmd_set_options = 0xffffffff;
-
 /****************************************************************************
   process commands from the client
 ****************************************************************************/
-static BOOL do_command(struct client_info *info, char *line)
+static void do_command(struct client_info *info, char *tok, char *line)
 {
        int i;
 
-       if (!get_cmd_args(line)) return False;
-
-       if (cmd_argc == 0)
+       if ((i = process_tok(tok)) >= 0)
        {
-               return False;
-       }
-
-       cmd_set_options = 0x0;
-
-       if ((i = process_tok(cmd_argv[0])) >= 0)
-       {
-               int argc = (int)cmd_argc;
-               char **argv = cmd_argv;
-               optind = 0;
-
-               commands[i].fn(info, argc, argv);
+               commands[i].fn(info);
        }
        else if (i == -2)
        {
-               fprintf(out_hnd, "%s: command abbreviation ambiguous\n",
-                                CNV_LANG(cmd_argv[0]));
+               fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok));
        }
        else
        {
-               fprintf(out_hnd, "%s: command not found\n",
-                                CNV_LANG(cmd_argv[0]));
+               fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok));
        }
-
-       free_char_array(cmd_argc, cmd_argv);
-
-       return True;
 }
 
-
 /****************************************************************************
   process commands from the client
 ****************************************************************************/
 static BOOL process( struct client_info *info, char *cmd_str)
-{
-       pstring line;
-       char *cmd = cmd_str;
-
-       if (cmd != NULL)
-       {
-               while (cmd[0] != '\0')
-               {
-                       char *p;
-
-                       if ((p = strchr(cmd, ';')) == 0)
-                       {
-                               strncpy(line, cmd, 999);
-                               line[1000] = '\0';
-                               cmd += strlen(cmd);
-                       }
-                       else
-                       {
-                               if (p - cmd > 999) p = cmd + 999;
-                               strncpy(line, cmd, p - cmd);
-                               line[p - cmd] = '\0';
-                               cmd = p + 1;
-                       }
-
-                       /* input language code to internal one */
-                       CNV_INPUT (line);
-
-                       if (!do_command(info, line)) continue;
-               }
-       }
-       else while (!feof(stdin))
-       {
-               pstring pline;
-               BOOL at_sym = False;
-               pline[0] = 0;
-               safe_strcat(pline, "[", sizeof(pline)-1);
-               if (usr.domain[0] != 0)
-               {
-                       safe_strcat(pline, usr.domain, sizeof(pline)-1);
-                       safe_strcat(pline, "\\", sizeof(pline)-1);
-                       at_sym = True;
-               }
-               if (usr.user_name[0] != 0)
-               {
-                       safe_strcat(pline, usr.user_name, sizeof(pline)-1);
-                       at_sym = True;
-               }
-               if (at_sym)
-               {
-                       safe_strcat(pline, "@", sizeof(pline)-1);
-               }
-       
-               safe_strcat(pline, cli_info.dest_host, sizeof(pline)-1);
-               safe_strcat(pline, "]$ ", sizeof(pline)-1);
-
-#ifndef HAVE_LIBREADLINE
-
-               /* display a prompt */
-               fprintf(out_hnd, "%s", CNV_LANG(pline));
-               fflush(out_hnd);
-
-               cli_use_wait_keyboard();
-
-               /* and get a response */
-               if (!fgets(line,1000,stdin))
-               {
-                       break;
-               }
-
-#else /* HAVE_LIBREADLINE */
-
-               if (!readline(pline))
-                   break;
-
-               /* Copy read line to samba buffer */
-
-               pstrcpy(line, rl_line_buffer);
-
-               /* Add to history */
-
-               if (strlen(line) > 0) 
-                   add_history(line);
-#endif
-               /* input language code to internal one */
-               CNV_INPUT (line);
-
-               /* special case - first char is ! */
-               if (*line == '!')
-               {
-                       system(line + 1);
-                       continue;
-               }
-
-               fprintf(out_hnd, "%s\n", line);
-
-               if (!do_command(info, line)) continue;
-       }
-
-       return(True);
-}
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
-  fprintf(out_hnd, "Usage: %s [password] [-S server] [-U user] -[W domain] [-l log] ",
-          pname);
-
-  fprintf(out_hnd, "\nVersion %s\n",VERSION);
-  fprintf(out_hnd, "\t-d debuglevel         set the debuglevel\n");
-  fprintf(out_hnd, "\t-S server             connect to \\\\server\\IPC$ \n");
-  fprintf(out_hnd, "\t-l log basename.      Basename for log/debug files\n");
-  fprintf(out_hnd, "\t-n netbios name.      Use this name as my netbios name\n");
-  fprintf(out_hnd, "\t-N                    don't ask for a password\n");
-  fprintf(out_hnd, "\t-m max protocol       set the max protocol level\n");
-  fprintf(out_hnd, "\t-I dest IP            use this IP to connect to\n");
-  fprintf(out_hnd, "\t-E                    write messages to stderr instead of stdout\n");
-  fprintf(out_hnd, "\t-U username           set the network username\n");
-  fprintf(out_hnd, "\t-U username%%pass      set the network username and password\n");
-  fprintf(out_hnd, "\t-W domain             set the domain name\n");
-  fprintf(out_hnd, "\t-c 'command string'   execute semicolon separated commands\n");
-  fprintf(out_hnd, "\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
-  fprintf(out_hnd, "\n");
-}
-
-#ifdef HAVE_LIBREADLINE
-
-/****************************************************************************
-GNU readline completion functions
-****************************************************************************/
-
-/* Complete a remote registry enum */
-
-static uint32 reg_list_len = 0;
-static char **reg_name = NULL;
-
-static void reg_init(int val, const char *full_keyname, int num)
-{
-       switch (val)
-       {
-               case 0:
-               {
-                       free_char_array(reg_list_len, reg_name);
-                       reg_list_len = 0;
-                       reg_name = NULL;
-                       break;
-               }
-               default:
-               {
-                       break;
-               }
-       }
-}
-
-static void reg_key_list(const char *full_name,
-                               const char *name, time_t key_mod_time)
-{
-       fstring key_name;
-       slprintf(key_name, sizeof(key_name)-1, "%s\\", name);
-       add_chars_to_array(&reg_list_len, &reg_name, key_name);
-}
-
-static void reg_val_list(const char *full_name,
-                               const char* name,
-                               uint32 type,
-                               const BUFFER2 *value)
-{
-       add_chars_to_array(&reg_list_len, &reg_name, name);
-}
-
-static char *complete_regenum(char *text, int state)
-{
-       pstring full_keyname;
-       static uint32 i = 0;
-    
-       if (state == 0)
-       {
-               fstring srv_name;
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, cli_info.dest_host);
-               strupper(srv_name);
-
-               if (cmd_argc >= 2 && cmd_argv != NULL && cmd_argv[1] != NULL)
-               {
-                       char *sep;
-                       split_server_keyname(srv_name, full_keyname,
-                                            cmd_argv[1]);
-
-                       sep = strrchr(full_keyname, '\\');
-                       if (sep != NULL)
-                       {
-                               *sep = 0;
-                       }
-               }
-
-               /* Iterate all keys / values */
-               if (!msrpc_reg_enum_key(srv_name, full_keyname,
-                                  reg_init, reg_key_list, reg_val_list))
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < reg_list_len; i++)
-       {
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, reg_name[i], strlen(text)))
-               {
-                       char *name = strdup(reg_name[i]);
-                       i++;
-                       return name;
-               }
-       }
-       
-       return NULL;
-}
-
-
-static char *complete_samenum_usr(char *text, int state)
-{
-       static uint32 i = 0;
-       static uint32 num_usrs = 0;
-       static struct acct_info *sam = NULL;
-    
-       if (state == 0)
-       {
-               fstring srv_name;
-               fstring domain;
-               fstring sid;
-               DOM_SID sid1;
-               sid_copy(&sid1, &cli_info.dom.level5_sid);
-               sid_to_string(sid, &sid1);
-               fstrcpy(domain, cli_info.dom.level5_dom);
-
-               if (sid1.num_auths == 0)
-               {
-                       return NULL;
-               }
-
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, cli_info.dest_host);
-               strupper(srv_name);
-
-               free(sam);
-               sam = NULL;
-               num_usrs = 0;
-
-               /* Iterate all users */
-               if (msrpc_sam_enum_users(srv_name, domain, &sid1, 
-                                  &sam, &num_usrs,
-                                  NULL, NULL, NULL, NULL) == 0)
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < num_usrs; i++)
-       {
-               char *usr_name = sam[i].acct_name;
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, usr_name, strlen(text)))
-               {
-                       char *name = strdup(usr_name);
-                       i++;
-                       return name;
-               }
-       }
-       
-       return NULL;
-}
-
-static char *complete_samenum_als(char *text, int state)
-{
-       static uint32 i = 0;
-       static uint32 num_als = 0;
-       static struct acct_info *sam = NULL;
-    
-       if (state == 0)
-       {
-               fstring srv_name;
-               fstring domain;
-               fstring sid;
-               DOM_SID sid1;
-               sid_copy(&sid1, &cli_info.dom.level5_sid);
-               sid_to_string(sid, &sid1);
-               fstrcpy(domain, cli_info.dom.level5_dom);
-
-               if (sid1.num_auths == 0)
-               {
-                       return NULL;
-               }
-
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, cli_info.dest_host);
-               strupper(srv_name);
-
-               free(sam);
-               sam = NULL;
-               num_als = 0;
-
-               /* Iterate all aliases */
-               if (msrpc_sam_enum_aliases(srv_name, domain, &sid1, 
-                                  &sam, &num_als,
-                                  NULL, NULL, NULL) == 0)
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < num_als; i++)
-       {
-               char *als_name = sam[i].acct_name;
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, als_name, strlen(text)))
-               {
-                       char *name = strdup(als_name);
-                       i++;
-                       return name;
-               }
-       }
-       
-       return NULL;
-}
-
-static char *complete_samenum_grp(char *text, int state)
-{
-       static uint32 i = 0;
-       static uint32 num_grps = 0;
-       static struct acct_info *sam = NULL;
-    
-       if (state == 0)
-       {
-               fstring srv_name;
-               fstring domain;
-               fstring sid;
-               DOM_SID sid1;
-               sid_copy(&sid1, &cli_info.dom.level5_sid);
-               sid_to_string(sid, &sid1);
-               fstrcpy(domain, cli_info.dom.level5_dom);
-
-               if (sid1.num_auths == 0)
-               {
-                       return NULL;
-               }
-
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, cli_info.dest_host);
-               strupper(srv_name);
-
-               free(sam);
-               sam = NULL;
-               num_grps = 0;
-
-               /* Iterate all groups */
-               if (msrpc_sam_enum_groups(srv_name,
-                                  domain, &sid1, 
-                                  &sam, &num_grps,
-                                  NULL, NULL, NULL) == 0)
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < num_grps; i++)
-       {
-               char *grp_name = sam[i].acct_name;
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, grp_name, strlen(text)))
-               {
-                       char *name = strdup(grp_name);
-                       i++;
-                       return name;
-               }
-       }
-       
-       return NULL;
-}
-
-static char *complete_svcenum(char *text, int state)
-{
-       static uint32 i = 0;
-       static uint32 num_svcs = 0;
-       static ENUM_SRVC_STATUS *svc = NULL;
-       fstring srv_name;
-
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, cli_info.dest_host);
-       strupper(srv_name);
-
-    
-       if (state == 0)
-       {
-               free(svc);
-               svc = NULL;
-               num_svcs = 0;
-
-               /* Iterate all users */
-               if (msrpc_svc_enum(srv_name, &svc, &num_svcs,
-                                  NULL, NULL) == 0)
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < num_svcs; i++)
-       {
-               fstring svc_name;
-               unistr_to_ascii(svc_name, svc[i].uni_srvc_name.buffer,
-                       sizeof(svc_name)-1);
-
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, svc_name, strlen(text)))
-               {
-                       char *name = strdup(svc_name);
-                       i++;
-                       return name;
-               }
-       }
-       
-       return NULL;
-}
-
-static char *complete_printersenum(char *text, int state)
-{
-       static uint32 i = 0;
-       static uint32 num = 0;
-       static PRINTER_INFO_1 **ctr = NULL;
-    
-       if (state == 0)
-       {
-               fstring srv_name;
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, cli_info.dest_host);
-               strupper(srv_name);
-
-               free_print1_array(num, ctr);
-               ctr = NULL;
-               num = 0;
-
-               /* Iterate all users */
-               if (!msrpc_spoolss_enum_printers(srv_name,
-                                  1, &num, (void***)&ctr,
-                                  NULL))
-               {
-                       return NULL;
-               }
-
-               i = 0;
-       }
-
-       for (; i < num; i++)
-       {
-               fstring name;
-               unistr_to_ascii(name, ctr[i]->name.buffer,
-                       sizeof(name)-1);
-
-               if (text == NULL || text[0] == 0 ||
-                   strnequal(text, name, strlen(text)))
-               {
-                       char *copy = strdup(name);
-                       i++;
-                       return copy;
-               }
-       }
-       
-       return NULL;
-}
-
-/* Complete an rpcclient command */
-
-static char *complete_cmd(char *text, int state)
-{
-    static int cmd_index;
-    char *name;
-
-    /* Initialise */
-
-    if (state == 0) {
-       cmd_index = 0;
-    }
-
-    /* Return the next name which partially matches the list of commands */
-    
-    while (strlen(name = commands[cmd_index++].name) > 0) {
-       if (strncmp(name, text, strlen(text)) == 0) {
-           return strdup(name);
-       }
-    }
-    
-    return NULL;
-}
-
-/* Main completion function */
-
-static char **completion_fn(char *text, int start, int end)
-{
-       pstring cmd_partial;
-       int cmd_index;
-       int num_words;
-
-    int i;
-    char lastch = ' ';
-
-       (void)get_cmd_args(rl_line_buffer);
-
-       safe_strcpy(cmd_partial, rl_line_buffer,
-                   MAX(sizeof(cmd_partial),end)-1);
-
-    /* Complete rpcclient command */
-
-    if (start == 0)
-       {
-       return completion_matches(text, complete_cmd);
-    }
-
-    /* Count # of words in command */
-    
-    num_words = 0;
-    for (i = 0; i <= end; i++) {
-       if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
-       {
-               num_words++;
-       }
-       lastch = rl_line_buffer[i];
-    }
-    
-    if (rl_line_buffer[end] == ' ')
-       num_words++;
-
-    /* Work out which command we are completing for */
-
-    for (cmd_index = 0; strcmp(commands[cmd_index].name, "") != 0; 
-        cmd_index++) {
-       
-       /* Check each command in array */
-       
-       if (strncmp(rl_line_buffer, commands[cmd_index].name,
-                   strlen(commands[cmd_index].name)) == 0) {
-           
-           /* Call appropriate completion function */
-
-      if (num_words == 2 || num_words == 3)
-      {
-        switch (commands[cmd_index].compl_args[num_words - 2])
-        {
-
-        case COMPL_SAMGRP:
-          return completion_matches(text, complete_samenum_grp);
-
-        case COMPL_SAMALS:
-          return completion_matches(text, complete_samenum_als);
-
-        case COMPL_SAMUSR:
-          return completion_matches(text, complete_samenum_usr);
-
-        case COMPL_SVCLST:
-          return completion_matches(text, complete_svcenum);
-
-        case COMPL_PRTLST:
-          return completion_matches(text, complete_printersenum);
-
-        case COMPL_REGKEY:
-          return completion_matches(text, complete_regenum);
-
-        default:
-            /* An invalid completion type */
-            break;
-        }
-      }
-       }
-    }
-
-    /* Eeek! */
-
-    return NULL;
-}
-
-/* To avoid filename completion being activated when no valid
-   completions are found, we assign this stub completion function
-   to the rl_completion_entry_function variable. */
-
-static char *complete_cmd_null(char *text, int state)
-{
-       return NULL;
-}
-
-#endif /* HAVE_LIBREADLINE */
-
-static void set_user_password(struct ntuser_creds *u,
-                               BOOL got_pass, char *password)
-{
-       /* set the password cache info */
-       if (got_pass)
-       {
-               if (password == NULL)
-               {
-                       pwd_set_nullpwd(&(u->pwd));
-               }
-               else
-               {
-                       /* generate 16 byte hashes */
-                       pwd_make_lm_nt_16(&(u->pwd), password);
-               }
-       }
-       else 
-       {
-               pwd_read(&(u->pwd), "Enter Password:", True);
-       }
-}
-
-static void cmd_net(struct client_info *info, int argc, char *argv[])
-{
-       int opt;
-       BOOL net_use = False;
-       BOOL net_use_add = True;
-       BOOL force_close = False;
-       struct ntuser_creds u;
-       fstring dest_host;
-       fstring srv_name;
-       BOOL null_pwd = False;
-       BOOL got_pwd = False;
-       pstring password;
-       extern struct ntuser_creds *usr_creds;
-
-       copy_nt_creds(&u, usr_creds);
-
-       pstrcpy(dest_host, cli_info.dest_host);
-       pstrcpy(u.user_name,optarg);
-       info->reuse = False;
-
-       if (argc <= 1)
-       {
-               report(out_hnd, "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
-               report(out_hnd, "net -u\n");
-       }
-
-       while ((opt = getopt(argc, argv, "udS:U:W:")) != EOF)
-       {
-               switch (opt)
-               {
-                       case 'u':
-                       {
-                               net_use = True;
-                               break;
-                       }
-
-                       case 'S':
-                       {
-                               pstrcpy(dest_host, optarg);
-                               break;
-                       }
-
-                       case 'U':
-                       {
-                               char *lp;
-                               pstrcpy(u.user_name,optarg);
-                               if ((lp=strchr(u.user_name,'%')))
-                               {
-                                       *lp = 0;
-                                       pstrcpy(password,lp+1);
-                                       memset(strchr(optarg,'%')+1,'X',
-                                              strlen(password));
-                                       got_pwd = True;
-                               }
-                               if (u.user_name[0] == 0 && password[0] == 0)
-                               {
-                                       null_pwd = True;
-                               }
-                               break;
-                       }
-
-                       case 'N':
-                       {
-                               null_pwd = True;
-                       }
-                       case 'W':
-                       {
-                               pstrcpy(u.domain,optarg);
-                               break;
-                       }
-
-                       case 'd':
-                       {
-                               net_use_add = False;
-                               break;
-                       }
-
-                       case 'f':
-                       {
-                               force_close = True;
-                               break;
-                       }
-
-                       default:
-                       {
-                               report(out_hnd, "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
-                               report(out_hnd, "net -u\n");
-                               break;
-                       }
-               }
-       }
-
-       if (strnequal("\\\\", dest_host, 2))
-       {
-               fstrcpy(srv_name, dest_host);
-       }
-       else
-       {
-               fstrcpy(srv_name, "\\\\");
-               fstrcat(srv_name, dest_host);
-       }
-       strupper(srv_name);
-
-       if (net_use)
-       {
-               int i;
-               uint32 num_uses;
-               struct use_info **use;
-               cli_net_use_enum(&num_uses, &use);
-
-               if (num_uses == 0)
-               {
-                       report(out_hnd, "No connections\n");
-               }
-               else
-               {
-                       report(out_hnd, "Connections:\n");
-
-                       for (i = 0; i < num_uses; i++)
-                       {
-                               if (use[i] != NULL && use[i]->connected)
-                               {
-                                       report(out_hnd, "Server:\t%s\t",
-                                                        use[i]->srv_name);
-                                       report(out_hnd, "User:\t%s\t",
-                                                        use[i]->user_name);
-                                       report(out_hnd, "Domain:\t%s\n",
-                                                        use[i]->domain);
-                               }
-                       }
-               }
-       }
-       else if (net_use_add)
+{
+       pstring line;
+       char *cmd = cmd_str;
+
+       if (cmd[0] != '\0') while (cmd[0] != '\0')
        {
-               if (null_pwd)
+               char *p;
+               fstring tok;
+
+               if ((p = strchr(cmd, ';')) == 0)
                {
-                       set_user_password(&u, True, NULL);
+                       strncpy(line, cmd, 999);
+                       line[1000] = '\0';
+                       cmd += strlen(cmd);
                }
                else
                {
-                       set_user_password(&u, got_pwd, password);
+                       if (p - cmd > 999) p = cmd + 999;
+                       strncpy(line, cmd, p - cmd);
+                       line[p - cmd] = '\0';
+                       cmd = p + 1;
                }
 
-               /* paranoia: destroy the local copy of the password */
-               bzero(password, sizeof(password)); 
-
-               report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
-                                srv_name, u.user_name, u.domain);
-               report(out_hnd, "Connection:\t");
+               /* input language code to internal one */
+               CNV_INPUT (line);
 
-               if (cli_net_use_add(srv_name, &u, True, info->reuse) != NULL)
-               {
-                       report(out_hnd, "OK\n");
-               }
-               else
+               /* get the first part of the command */
                {
-                       report(out_hnd, "FAILED\n");
+                       char *ptr = line;
+                       if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
                }
+
+               do_command(info, tok, line);
        }
-       else
+       else while (!feof(stdin))
        {
-               BOOL closed;
-               report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
-                                srv_name, u.user_name, u.domain);
-               report(out_hnd, "Connection:\t");
+               fstring tok;
+
+               /* display a prompt */
+               fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir));
+               fflush(out_hnd);
 
-               if (!cli_net_use_del(srv_name, &u, force_close, &closed))
+#ifdef CLIX
+               line[0] = wait_keyboard(smb_cli);
+               /* this might not be such a good idea... */
+               if ( line[0] == EOF)
                {
-                       report(out_hnd, ": Does not exist\n");
+                       break;
                }
-               else if (force_close && closed)
+#else
+               wait_keyboard(smb_cli);
+#endif
+
+               /* and get a response */
+#ifdef CLIX
+               fgets( &line[1],999, stdin);
+#else
+               if (!fgets(line,1000,stdin))
                {
-                       report(out_hnd, ": Forcibly terminated\n");
+                       break;
                }
-               else if (closed)
+#endif
+
+               /* input language code to internal one */
+               CNV_INPUT (line);
+
+               /* special case - first char is ! */
+               if (*line == '!')
                {
-                       report(out_hnd, ": Terminated\n");
+                       system(line + 1);
+                       continue;
                }
-               else
+
+               fprintf(out_hnd, "%s\n", line);
+
+               /* get the first part of the command */
                {
-                       report(out_hnd, ": Unlinked\n");
+                       char *ptr = line;
+                       if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
                }
+
+               do_command(info, tok, line);
        }
 
-       /* paranoia: destroy the local copy of the password */
-       bzero(password, sizeof(password)); 
+       return(True);
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+  fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
+          pname);
+
+  fprintf(out_hnd, "\nVersion %s\n",VERSION);
+  fprintf(out_hnd, "\t-d debuglevel         set the debuglevel\n");
+  fprintf(out_hnd, "\t-l log basename.      Basename for log/debug files\n");
+  fprintf(out_hnd, "\t-n netbios name.      Use this name as my netbios name\n");
+  fprintf(out_hnd, "\t-N                    don't ask for a password\n");
+  fprintf(out_hnd, "\t-m max protocol       set the max protocol level\n");
+  fprintf(out_hnd, "\t-I dest IP            use this IP to connect to\n");
+  fprintf(out_hnd, "\t-E                    write messages to stderr instead of stdout\n");
+  fprintf(out_hnd, "\t-U username           set the network username\n");
+  fprintf(out_hnd, "\t-W workgroup          set the workgroup name\n");
+  fprintf(out_hnd, "\t-c command string     execute semicolon separated commands\n");
+  fprintf(out_hnd, "\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
+  fprintf(out_hnd, "\n");
 }
 
-#define CMD_STR 0x1
-#define CMD_DBF 0x2
-#define CMD_SVC 0x4
-#define CMD_TERM 0x8
-#define CMD_PASS 0x10
-#define CMD_USER 0x20
-#define CMD_NOPW 0x40
-#define CMD_DBLV 0x80
-#define CMD_HELP 0x100
-#define CMD_SOCK 0x200
-#define CMD_IFACE 0x400
-#define CMD_DOM 0x800
-#define CMD_IP 0x1000
-#define CMD_HOST 0x2000
-#define CMD_NAME 0x4000
-#define CMD_DBG 0x8000
-#define CMD_SCOPE 0x10000
-#define CMD_INTER 0x20000
-
-static void cmd_set(struct client_info *info, int argc, char *argv[])
+enum client_action
+{
+       CLIENT_NONE,
+       CLIENT_IPC,
+       CLIENT_SVC
+};
+
+/****************************************************************************
+  main program
+****************************************************************************/
+ int main(int argc,char *argv[])
 {
        BOOL interactive = True;
-       char *cmd_str = NULL;
+
        int opt;
        extern FILE *dbf;
        extern char *optarg;
+       extern int optind;
        static pstring servicesf = CONFIGFILE;
        pstring term_code;
+       char *p;
+       BOOL got_pass = False;
+       char *cmd_str="";
+       mode_t myumask = 0755;
+       enum client_action cli_action = CLIENT_NONE;
+
+       struct client_info cli_info;
+
        pstring password; /* local copy only, if one is entered */
-       info->reuse = False;
+
+       out_hnd = stdout;
+       fstrcpy(debugf, argv[0]);
+
+       rpcclient_init();
 
 #ifdef KANJI
        pstrcpy(term_code, KANJI);
@@ -1569,29 +423,138 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
        *term_code = 0;
 #endif /* KANJI */
 
+       DEBUGLEVEL = 2;
+
+       cli_info.put_total_size = 0;
+       cli_info.put_total_time_ms = 0;
+       cli_info.get_total_size = 0;
+       cli_info.get_total_time_ms = 0;
+
+       cli_info.dir_total = 0;
+       cli_info.newer_than = 0;
+       cli_info.archive_level = 0;
+       cli_info.print_mode = 1;
+
+       cli_info.translation = False;
+       cli_info.recurse_dir = False;
+       cli_info.lowercase = False;
+       cli_info.prompt = True;
+       cli_info.abort_mget = True;
+
+       cli_info.dest_ip.s_addr = 0;
+       cli_info.name_type = 0x20;
+
+       pstrcpy(cli_info.cur_dir , "\\");
+       pstrcpy(cli_info.file_sel, "");
+       pstrcpy(cli_info.base_dir, "");
+       pstrcpy(smb_cli->domain, "");
+       pstrcpy(smb_cli->user_name, "");
+       pstrcpy(cli_info.myhostname, "");
+       pstrcpy(cli_info.dest_host, "");
+
+       pstrcpy(cli_info.svc_type, "A:");
+       pstrcpy(cli_info.share, "");
+       pstrcpy(cli_info.service, "");
+
+       ZERO_STRUCT(cli_info.dom.level3_sid);
+       ZERO_STRUCT(cli_info.dom.level5_sid);
+       fstrcpy(cli_info.dom.level3_dom, "");
+       fstrcpy(cli_info.dom.level5_dom, "");
+
+       smb_cli->nt_pipe_fnum   = 0xffff;
+
+       TimeInit();
+       charset_initialise();
+
+       myumask = umask(0);
+       umask(myumask);
+
+       if (!get_myname(global_myname))
+       {
+               fprintf(stderr, "Failed to get my hostname.\n");
+       }
+
+       if (getenv("USER"))
+       {
+               pstrcpy(smb_cli->user_name,getenv("USER"));
+
+               /* modification to support userid%passwd syntax in the USER var
+               25.Aug.97, jdblair@uab.edu */
+
+               if ((p=strchr(smb_cli->user_name,'%')))
+               {
+                       *p = 0;
+                       pstrcpy(password,p+1);
+                       got_pass = True;
+                       memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+               }
+               strupper(smb_cli->user_name);
+       }
+
+       password[0] = 0;
+
+       /* modification to support PASSWD environmental var
+          25.Aug.97, jdblair@uab.edu */
+       if (getenv("PASSWD"))
+       {
+               pstrcpy(password,getenv("PASSWD"));
+       }
+
+       if (*smb_cli->user_name == 0 && getenv("LOGNAME"))
+       {
+               pstrcpy(smb_cli->user_name,getenv("LOGNAME"));
+               strupper(smb_cli->user_name);
+       }
+
+       if (argc < 2)
+       {
+               usage(argv[0]);
+               exit(1);
+       }
 
-       if (argc > 1 && *argv[1] != '-')
+       if (*argv[1] != '-')
        {
+
+               pstrcpy(cli_info.service, argv[1]);  
+               /* Convert any '/' characters in the service name to '\' characters */
+               string_replace( cli_info.service, '/','\\');
+               argc--;
+               argv++;
+
+               fprintf(out_hnd, "service: %s\n", cli_info.service);
+
+               if (count_chars(cli_info.service,'\\') < 3)
+               {
+                       usage(argv[0]);
+                       printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
+                       exit(1);
+               }
+
+               /*
+               if (count_chars(cli_info.service,'\\') > 3)
+               {
+                       usage(pname);
+                       printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
+                       exit(1);
+               }
+               */
+
                if (argc > 1 && (*argv[1] != '-'))
                {
-                       cmd_set_options |= CMD_PASS;
+                       got_pass = True;
                        pstrcpy(password,argv[1]);  
                        memset(argv[1],'X',strlen(argv[1]));
                        argc--;
                        argv++;
                }
+
+               cli_action = CLIENT_SVC;
        }
 
-       while ((opt = getopt(argc, argv, "Rs:B:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+       while ((opt = getopt(argc, argv,"s:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
        {
                switch (opt)
                {
-                       case 'R':
-                       {
-                               info->reuse = True;
-                               break;
-                       }
-
                        case 'm':
                        {
                                /* FIXME ... max_protocol seems to be funny here */
@@ -1604,29 +567,20 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
 
                        case 'O':
                        {
-                               cmd_set_options |= CMD_SOCK;
                                pstrcpy(user_socket_options,optarg);
                                break;  
                        }
 
                        case 'S':
                        {
-                               cmd_set_options |= CMD_HOST;
                                pstrcpy(cli_info.dest_host,optarg);
                                strupper(cli_info.dest_host);
-                               break;
-                       }
-
-                       case 'B':
-                       {
-                               cmd_set_options |= CMD_IFACE;
-                               iface_set_default(NULL,optarg,NULL);
+                               cli_action = CLIENT_IPC;
                                break;
                        }
 
                        case 'i':
                        {
-                               cmd_set_options |= CMD_SCOPE;
                                pstrcpy(scope, optarg);
                                break;
                        }
@@ -1634,43 +588,34 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
                        case 'U':
                        {
                                char *lp;
-                               cmd_set_options |= CMD_USER;
-                               pstrcpy(usr.user_name,optarg);
-                               if ((lp=strchr(usr.user_name,'%')))
+                               pstrcpy(smb_cli->user_name,optarg);
+                               if ((lp=strchr(smb_cli->user_name,'%')))
                                {
                                        *lp = 0;
                                        pstrcpy(password,lp+1);
-                                       cmd_set_options |= CMD_PASS;
+                                       got_pass = True;
                                        memset(strchr(optarg,'%')+1,'X',strlen(password));
                                }
-                               if (usr.user_name[0] == 0 && password[0] == 0)
-                               {
-                                       cmd_set_options |= CMD_NOPW;
-                               }
                                break;
                        }
 
                        case 'W':
                        {
-                               cmd_set_options |= CMD_DOM;
-                               pstrcpy(usr.domain,optarg);
+                               pstrcpy(smb_cli->domain,optarg);
                                break;
                        }
 
                        case 'E':
                        {
-                               cmd_set_options |= CMD_DBG;
                                dbf = stderr;
                                break;
                        }
 
                        case 'I':
                        {
-                               cmd_set_options |= CMD_IP;
                                cli_info.dest_ip = *interpret_addr2(optarg);
                                if (zero_ip(cli_info.dest_ip))
                                {
-                                       free_connections();
                                        exit(1);
                                }
                                break;
@@ -1678,20 +623,18 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
 
                        case 'n':
                        {
-                               cmd_set_options |= CMD_NAME;
                                fstrcpy(global_myname, optarg);
                                break;
                        }
 
                        case 'N':
                        {
-                               cmd_set_options |= CMD_NOPW | CMD_PASS;
+                               got_pass = True;
                                break;
                        }
 
                        case 'd':
                        {
-                               cmd_set_options |= CMD_DBLV;
                                if (*optarg == 'A')
                                        DEBUGLEVEL = 10000;
                                else
@@ -1701,7 +644,6 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
 
                        case 'l':
                        {
-                               cmd_set_options |= CMD_INTER;
                                slprintf(debugf, sizeof(debugf)-1,
                                         "%s.client", optarg);
                                interactive = False;
@@ -1710,221 +652,121 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
 
                        case 'c':
                        {
-                               cmd_set_options |= CMD_STR | CMD_PASS;
                                cmd_str = optarg;
+                               got_pass = True;
                                break;
                        }
 
                        case 'h':
                        {
-                               cmd_set_options |= CMD_HELP;
                                usage(argv[0]);
+                               exit(0);
                                break;
                        }
 
                        case 's':
                        {
-                               cmd_set_options |= CMD_SVC;
                                pstrcpy(servicesf, optarg);
                                break;
                        }
 
                        case 't':
                        {
-                               cmd_set_options |= CMD_TERM;
                                pstrcpy(term_code, optarg);
                                break;
                        }
 
                        default:
                        {
-                               cmd_set_options |= CMD_HELP;
                                usage(argv[0]);
+                               exit(1);
                                break;
                        }
                }
        }
 
-       DEBUG(10,("cmd_set: options: %x\n", cmd_set_options));
-
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_HELP))
-       {
-               return;
-       }
-
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER))
-       {
-               setup_logging(debugf, interactive);
-               reopen_logs();
-       }
+       setup_logging(debugf, interactive);
 
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_NOPW))
+       if (cli_action == CLIENT_NONE)
        {
-               set_user_password(&usr, True, NULL);
-       }
-       else if (IS_BITS_SET_ALL(cmd_set_options, CMD_PASS))
-       {
-               set_user_password(&usr, True, password);
+               usage(argv[0]);
+               exit(1);
        }
 
-       /* paranoia: destroy the local copy of the password */
-       bzero(password, sizeof(password)); 
-
        strupper(global_myname);
        fstrcpy(cli_info.myhostname, global_myname);
 
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_SVC))
-       {
-               if (!lp_load(servicesf,True, False, False))
-               {
-                       fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
-               }
-
-       }
+       DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
 
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER))
+       if (!lp_load(servicesf,True, False, False))
        {
-               load_interfaces();
+               fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
        }
 
-       if (cmd_str != NULL)
-       {
-               process(&cli_info, cmd_str);
-       }
-}
+       codepage_initialise(lp_client_code_page());
 
-static void read_user_env(struct ntuser_creds *u)
-{
-       pstring password;
+       if (*smb_cli->domain == 0) pstrcpy(smb_cli->domain,lp_workgroup());
 
-       password[0] = 0;
+       load_interfaces();
 
-       if (getenv("USER"))
+       if (cli_action == CLIENT_IPC)
        {
-               char *p;
-               pstrcpy(u->user_name,getenv("USER"));
+               pstrcpy(cli_info.share, "IPC$");
+               pstrcpy(cli_info.svc_type, "IPC");
+       }
 
-               /* modification to support userid%passwd syntax in the USER var
-               25.Aug.97, jdblair@uab.edu */
+       fstrcpy(cli_info.mach_acct, cli_info.myhostname);
+       strupper(cli_info.mach_acct);
+       fstrcat(cli_info.mach_acct, "$");
 
-               if ((p=strchr(u->user_name,'%')))
+       /* set the password cache info */
+       if (got_pass)
+       {
+               if (password[0] == 0)
                {
-                       *p = 0;
-                       pstrcpy(password,p+1);
-                       memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+                       pwd_set_nullpwd(&(smb_cli->pwd));
+               }
+               else
+               {
+                       pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
                }
-               strupper(u->user_name);
-       }
-
-       /* modification to support PASSWD environmental var
-          25.Aug.97, jdblair@uab.edu */
-       if (getenv("PASSWD"))
-       {
-               pstrcpy(password,getenv("PASSWD"));
        }
-
-       if (*u->user_name == 0 && getenv("LOGNAME"))
+       else 
        {
-               pstrcpy(u->user_name,getenv("LOGNAME"));
-               strupper(u->user_name);
+               pwd_read(&(smb_cli->pwd), "Enter Password:", True);
        }
 
-       set_user_password(u, True, password);
-
        /* paranoia: destroy the local copy of the password */
-       bzero(password, sizeof(password)); 
-}
-
-void readline_init(void)
-{
-#ifdef HAVE_LIBREADLINE
-
-       /* Initialise GNU Readline */
-       
-       rl_readline_name = "rpcclient";
-       rl_attempted_completion_function = completion_fn;
-       rl_completion_entry_function = (Function *)complete_cmd_null;
-       
-       /* Initialise history list */
-       
-       using_history();
-
-#else
-       int x;
-       x = 0; /* stop compiler warnings */
-#endif /* HAVE_LIBREADLINE */
-}
-
-/****************************************************************************
-  main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
-       extern struct ntuser_creds *usr_creds;
-       mode_t myumask = 0755;
-
-       DEBUGLEVEL = 2;
-
-       usr.ntlmssp_flags = 0x0;
-
-       usr_creds = &usr;
-       out_hnd = stdout;
-       fstrcpy(debugf, argv[0]);
-
-       init_policy_hnd(64);
-
-       pstrcpy(usr.domain, "");
-       pstrcpy(usr.user_name, "");
-
-       pstrcpy(cli_info.myhostname, "");
-       pstrcpy(cli_info.dest_host, "");
-       cli_info.dest_ip.s_addr = 0;
-
-       ZERO_STRUCT(cli_info.dom.level3_sid);
-       ZERO_STRUCT(cli_info.dom.level5_sid);
-       fstrcpy(cli_info.dom.level3_dom, "");
-       fstrcpy(cli_info.dom.level5_dom, "");
-
-       readline_init();
-       TimeInit();
-       charset_initialise();
-       init_connections();
+       memset((char *)password, '\0', sizeof(password)); 
 
-       myumask = umask(0);
-       umask(myumask);
+       /* establish connections.  nothing to stop these being re-established. */
+       rpcclient_connect(&cli_info);
 
-       if (!get_myname(global_myname, NULL))
+       DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
+       if (smb_cli->fd <= 0)
        {
-               fprintf(stderr, "Failed to get my hostname.\n");
+               fprintf(stderr, "warning: connection could not be established to %s<%02x>\n",
+                                cli_info.dest_host, cli_info.name_type);
+               fprintf(stderr, "this version of smbclient may crash if you proceed\n");
+               exit(-1);
        }
 
-       if (argc < 2)
+       switch (cli_action)
        {
-               usage(argv[0]);
-               free_connections();
-               exit(1);
-       }
-
-       read_user_env(&usr);
-
-       cmd_set_options &= ~CMD_HELP;
-       cmd_set_options &= ~CMD_NOPW;
-
-       cmd_set(&cli_info, argc, argv);
+               case CLIENT_IPC:
+               {
+                       process(&cli_info, cmd_str);
+                       break;
+               }
 
-       if (IS_BITS_SET_ALL(cmd_set_options, CMD_HELP))
-       {
-               free_connections();
-               exit(0);
+               default:
+               {
+                       fprintf(stderr, "unknown client action requested\n");
+                       break;
+               }
        }
 
-       codepage_initialise(lp_client_code_page());
-
-       DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
-
-       process(&cli_info, NULL);
-
-       free_connections();
+       rpcclient_stop();
 
        return(0);
 }
index 22771ce5a075f2c6b89e3fababfe84633a12c1e4..69cca942953e24771e388df1381e3b7e9836288e 100755 (executable)
@@ -26,10 +26,16 @@ for p in $*; do
  p2=`basename $p`
  echo Installing $p as $BINDIR/$p2
  if [ -f $BINDIR/$p2 ]; then
+   rm -f $BINDIR/$p2.old
    mv $BINDIR/$p2 $BINDIR/$p2.old
  fi
  cp $p $BINDIR/
  chmod $INSTALLPERMS $BINDIR/$p2
+
+ # this is a special case, mount needs this in a specific location
+ if [ $p2 = smbmount ]; then
+   ln -sf $BINDIR/$p2 /sbin/mount.smbfs
+ fi
 done
 
 
@@ -43,4 +49,3 @@ binaries, man pages and shell scripts.
 EOF
 
 exit 0
-
index 87b0ef1a8ab9849bc37c088bead7373e4f0dd5de..d0c5bf8ecc9970f4a4c733c2cea7deec34bccf0d 100755 (executable)
@@ -21,8 +21,14 @@ fi
 done
 
 for p in $*; do
- echo Creating codepage file $CODEPAGEDIR/codepage.$p
- $BINDIR/make_smbcodepage c $p ${srcdir}/codepages/codepage_def.$p $CODEPAGEDIR/codepage.$p
+ if [ -f ${srcdir}/codepages/codepage_def.$p ]; then
+   echo Creating codepage file $CODEPAGEDIR/codepage.$p
+   $BINDIR/make_smbcodepage c $p ${srcdir}/codepages/codepage_def.$p $CODEPAGEDIR/codepage.$p
+ fi
+ if [ -f ${srcdir}/codepages/CP${p}.TXT ]; then
+   echo Creating unicode map $CODEPAGEDIR/unicode_map.$p
+   $BINDIR/make_unicodemap $p ${srcdir}/codepages/CP${p}.TXT $CODEPAGEDIR/unicode_map.$p
+ fi
 done
 
 
index 6d55317e9e1a1f8fe126597d1537c9c734c71b96..bff5423e7cb3b52c52cd59e8495b1a2a7434d569 100755 (executable)
@@ -25,6 +25,7 @@ for p in $*; do
   p2=`basename $p`
   echo Installing $BINDIR/$p2
   if [ -f $BINDIR/$p2 ]; then
+    rm -f $BINDIR/$p2.old
     mv $BINDIR/$p2 $BINDIR/$p2.old
   fi
   cp $p $BINDIR/
index cc2ab943d9a1a0ed92d103d0d8d492c66bcaf00a..ab760cb545b5858246e7dcefe6b6bd407ef94547 100755 (executable)
@@ -6,7 +6,7 @@ SRCDIR=$2/
 
 echo Installing SWAT in $SWATDIR
 
-echo Installing the Samba Web Admisistration Tool
+echo Installing the Samba Web Administration Tool
 
 for d in $SWATDIR $SWATDIR/help $SWATDIR/images $SWATDIR/include; do
 if [ ! -d $d ]; then
index c943224fe5b964dea1cb28069c700bf44b8f97ba..d0abaab7aec32310cc85f7849236099e2307f17a 100755 (executable)
@@ -55,16 +55,8 @@ do
                                exit 1
                        fi
                        cp $bn.html ../htmldocs || echo "Cannot create $YODLDIR/../htmldocs/$bn.html"
-#
-# Copy to SWAT directory.
-#
-                       if [ $bn = "smb.conf.5" ]; then
-                               rm -f ../../swat/help/smb.conf.5.html || echo "Cannot remove ../../swat/help/smb.conf.5.html"
-
-                               cp $bn.html ../../swat/help || echo "Cannot copy smb.conf.5.html to ../../swat/help/smb.conf.5.html"
-                       fi
                        rm -f $bn.html
-                       ;;
+               ;;
                *)
 #
 # Non man-page YODL docs - just make html and text.
index b286e1f7dbbbbc21f7da68541c6fa09a893b9685..923624c3a261aaef060427864d4cf12b3e651322 100644 (file)
@@ -90,23 +90,15 @@ END {
 
 {
   gotstart = 0;
-  if( $0 ~ /^connection_struct|^LOCAL_GRP|^DOMAIN_GRP|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
+  if( $0 ~ /^connection_struct|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
     gotstart = 1;
   }
 
-  if( $0 ~ /^JOB_INFO_1|^JOB_INFO_2/ ) {
+  if( $0 ~ /^LOCAL_GRP|^DOMAIN_GRP|^SMB_STRUCT_DIRENT|^SEC_ACL|^SEC_DESC|^SEC_DESC_BUF|^DOM_SID/ ) {
     gotstart = 1;
   }
 
-  if( $0 ~ /^PRINTER_INFO_1|^PRINTER_INFO_2/ ) {
-    gotstart = 1;
-  }
-
-  if( $0 ~ /^UNISTR2|^LOCAL_GRP|^DOMAIN_GRP|^DOM_SID|^SEC_DESC/ ) {
-    gotstart = 1;
-  }
-
-  if( $0 ~ /^const|^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT|dbg_Token/ ) {
+  if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
     gotstart = 1;
   }
   if(!gotstart) {
index f04eddc32badc49717b01c72ad8d215a4652ad34..cf3ff0ebe686257bafa864333b19a45753c746f5 100644 (file)
@@ -30,7 +30,9 @@ username=$LOGNAME           # Default: same user name as in *nix
 verbose="2>/dev/null"        # Default: no echo to stdout
 log="-d 2"
 newer=""
+newerarg=""
 blocksize=""
+blocksizearg=""
 clientargs="-c 'tarmode full'"
 tarcmd="c"
 tarargs=""
@@ -62,7 +64,7 @@ Options:         (Description)                 (Default)
   exit $ex
 }
 
-echo Params count: $#
+echo Params count: $#
 
 # DEC OSF AKA Digital UNIX does not seem to return a value in OPTIND if 
 # there are no command line params, so protect us against that ...
@@ -97,7 +99,7 @@ while getopts riavl:b:d:N:s:p:x:u:Xt: c; do
    N) # compare with a file, test if [n]ewer
       if [ -f $OPTARG ]; then
        newer=$OPTARG
-        tarargs=${tarargs}N
+       newerarg="N"
       else
        echo >&2 $0: Warning, $OPTARG not found
       fi
@@ -115,7 +117,7 @@ while getopts riavl:b:d:N:s:p:x:u:Xt: c; do
        *)      echo >&2 "$0: Error, block size not numeric: -b $OPTARG"
                exit 1
       esac
-      tarargs=${tarargs}b
+      blocksizearg="b"
       ;;
    p) # specify [p]assword to use
       password="$OPTARG"
@@ -155,7 +157,8 @@ if [ -z "$verbose" ]; then
       echo "blocksize is $blocksize"
 fi
 
+tarargs=${tarargs}${blocksizearg}${newerarg}
+
 eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \
 -E -N $log -D "'$cdcmd'" ${clientargs} \
 -T${tarcmd}${tarargs} $blocksize $newer $tapefile '${1+"$@"}' $verbose
-
index 32b6d010a4f2a850f59ba3eb2db9a5a679800d44..16882be2bbebfd50591a0c5c5166715eec93d2ed 100644 (file)
@@ -211,18 +211,16 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
   for(i = blr->lock_num; 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);
   }
 
@@ -313,7 +311,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;
@@ -401,18 +399,15 @@ 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),
                 &eclass, &ecode))
@@ -526,6 +521,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 3d31db7fb58bed1c14160dbb064d30d86eb79ac5..b86091e773fa28bb3f9fd757444a2179f6657909 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;
+  void *dirp;
   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,("findpty: Unable to create master/slave pty pair.\n"));
       /* Stop fd leak on error. */
@@ -80,14 +76,14 @@ static int findpty(char **slave)
       return (master);
     }
   }
-#else /* HAVE_GRANTPT */
+#endif /* HAVE_GRANTPT */
+
   fstrcpy( line, "/dev/ptyXX" );
 
-  dirp = opendir("/dev");
+  dirp = OpenDir(NULL, "/dev", False);
   if (!dirp)
     return(-1);
-  while ((dentry = readdir(dirp)) != NULL) {
-    dpname = dentry->d_name;
+  while ((dpname = ReadDirName(dirp)) != NULL) {
     if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
       DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) );
       line[8] = dpname[3];
@@ -96,13 +92,12 @@ static int findpty(char **slave)
         DEBUG(3,("pty: opened %s\n", line ) );
         line[5] = 't';
         *slave = line;
-        closedir(dirp);
+        CloseDir(dirp);
         return (master);
       }
     }
   }
-  closedir(dirp);
-#endif /* HAVE_GRANTPT */
+  CloseDir(dirp);
   return (-1);
 }
 
@@ -110,9 +105,9 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
 {
   int slave;
   struct termios stermios;
-  const struct passwd *pass = Get_Pwnam(name,True);
-  int gid;
-  int uid;
+  struct passwd *pass = Get_Pwnam(name,True);
+  gid_t gid;
+  uid_t uid;
 
   if (pass == NULL) {
     DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n",
@@ -122,11 +117,8 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
 
   gid = pass->pw_gid;
   uid = pass->pw_uid;
-#ifdef HAVE_SETRESUID
-  setresuid(0,0,0);
-#else 
-  setuid(0);
-#endif
+
+  gain_root_privilege();
 
   /* Start new session - gets rid of controlling terminal. */
   if (setsid() < 0) {
@@ -186,19 +178,7 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
 
   /* make us completely into the right uid */
   if (!as_root) {
-#ifdef HAVE_SETRESUID
-         setresgid(0,0,0);
-         setresuid(0,0,0);
-         setresgid(gid,gid,gid);
-         setresuid(uid,uid,uid);      
-#else      
-         setuid(0);
-         seteuid(0);
-         setgid(gid);
-         setegid(gid);
-         setuid(uid);
-         seteuid(uid);
-#endif
+         become_user_permanently(uid, gid);
   }
 
   DEBUG(10, ("Invoking '%s' as password change program.\n", passwordprogram));
@@ -211,92 +191,91 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
   return(True);
 }
 
-static int expect(int master,char *expected,char *buf)
+static int expect(int master, char *issue, char *expected)
 {
-  int n, m;
-  n = 0;
-  buf[0] = 0;
-  while (1) {
-    if (n >= BUFSIZE-1) {
-      return False;
-    }
+       pstring buffer;
+       int attempts, timeout, nread, len;
+       BOOL match = False;
 
-    /* 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;
+       for (attempts = 0; attempts < 2; attempts++)
+       {
+               if (!strequal(issue, "."))
+               {
+                       if (lp_passwd_chat_debug())
+                               DEBUG(100, ("expect: sending [%s]\n", issue));
 
-    n += m;
-    buf[n] = 0;
+                       write(master, issue, strlen(issue));
+               }
 
-    {
-      pstring s1,s2;
-      pstrcpy(s1,buf);
-      pstrcpy(s2,expected);
-      if (do_match(s1, s2, False))
-       return(True);
-    }
-  }
+               if (strequal(expected, "."))
+                       return True;
+
+               timeout = 2000;
+               nread = 0;
+               buffer[nread] = 0;
+
+               while ((len = read_with_timeout(master, buffer + nread, 1,
+                                sizeof(buffer) - nread - 1, timeout)) > 0)
+               {
+                       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;
+               }
+       }
+
+       return match;
 }
 
 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");
+       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 void writestring(int fd,char *s)
+static int talktochild(int master, char *seq)
 {
-  int l;
-  
-  l = strlen (s);
-  write (fd, s, l);
-}
+       int count = 0;
+       fstring issue, expected;
 
+       fstrcpy(issue, ".");
 
-static int talktochild(int master, char *chatsequence)
-{
-  char buf[BUFSIZE];
-  int count=0;
-  char *ptr=chatsequence;
-  fstring chatbuf;
-
-  *buf = 0;
-  sleep(1);
-
-  while (next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) {
-    BOOL ok=True;
-    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) {
-      DEBUG(3,("response %d incorrect\n",count));
-      return(False);
-    }
+       while (next_token(&seq, expected, NULL, sizeof(expected)))
+       {
+               pwd_sub(expected);
+               count++;
 
-    if (!next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) break;
-    pwd_sub(chatbuf);
-    if (!strequal(chatbuf,"."))
-      writestring(master,chatbuf);
+               if (!expect(master, issue, expected))
+               {
+                       DEBUG(3,("Response %d incorrect\n", count));
+                       return False;
+               }
 
-    if (lp_passwd_chat_debug())
-      DEBUG(100,("talktochild: sendbuf=[%s]\n",chatbuf));
-  }
+               if (!next_token(&seq, issue, NULL, sizeof(issue)))
+                       fstrcpy(issue, ".");
 
-  if (count<1) return(False);
+               pwd_sub(issue);
+       }
 
-  return (True);
+       return (count > 0);
 }
 
-
 static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root)
 {
   char *slavedev;
@@ -311,9 +290,17 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
     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);
   }
 
@@ -324,12 +311,26 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
       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) {
@@ -362,8 +363,12 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
     DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,(int)getuid(),(int)getgid()));
     chstat = 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)
@@ -376,8 +381,8 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
 {
   pstring passwordprogram;
   pstring chatsequence;
-  int i;
-  int len;
+  size_t i;
+  size_t len;
 
   strlower(name); 
   DEBUG(3,("Password change for user: %s\n",name));
@@ -388,9 +393,10 @@ BOOL chgpasswd(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 */
     }
   
@@ -435,13 +441,14 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
     }
   }
 
-  string_sub(passwordprogram,"%u",name);
-  all_string_sub(passwordprogram,"%o",oldpass);
-  all_string_sub(passwordprogram,"%n",newpass);
+  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);
-  all_string_sub(chatsequence,"%o",oldpass);
-  all_string_sub(chatsequence,"%n",newpass);
+  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(passwordprogram,name,chatsequence, as_root));
 }
 
@@ -531,7 +538,7 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2
 
   if (smbpw->acct_ctrl & ACB_DISABLED)
   {
-    DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->unix_name));
+    DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->smb_name));
     return False;
   }
 
@@ -573,14 +580,6 @@ BOOL pass_oem_change(char *user,
                                       &sampw, 
                                       new_passwd, sizeof(new_passwd));
 
-       /* now we check to see if we are actually allowed to change the
-          password. */
-          
-       if (ret && (sampw->acct_ctrl & ACB_PWLOCK))
-       {
-               ret = False;
-       }
-       
        /* 
         * At this point we have the new case-sensitive plaintext
         * password in the fstring new_passwd. If we wanted to synchronise
@@ -621,12 +620,12 @@ BOOL check_oem_password(char *user,
        static uchar null_pw[16];
        static uchar null_ntpw[16];
        struct smb_passwd *smbpw = NULL;
+       int new_pw_len;
        uchar new_ntp16[16];
        uchar unenc_old_ntpw[16];
        uchar new_p16[16];
        uchar unenc_old_pw[16];
        char no_pw[2];
-       uint32 len;
 
        BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);
 
@@ -683,11 +682,35 @@ BOOL check_oem_password(char *user,
         */
        SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True);
 
-       if (!decode_pw_buffer(lmdata, new_passwd, new_passwd_size, &len))
+       /* 
+        * The length of the new password is in the last 4 bytes of
+        * the data buffer.
+        */
+
+       new_pw_len = IVAL(lmdata, 512);
+       if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
        {
+               DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
                return False;
        }
 
+       if (nt_pass_set)
+       {
+               /*
+                * nt passwords are in unicode
+                */
+               int uni_pw_len = new_pw_len;
+               char *pw;
+               new_pw_len /= 2;
+               pw = dos_unistrn2((uint16*)(&lmdata[512-uni_pw_len]), new_pw_len);
+               memcpy(new_passwd, pw, new_pw_len+1);
+       }
+       else
+       {
+               memcpy(new_passwd, &lmdata[512-new_pw_len], new_pw_len);
+               new_passwd[new_pw_len] = '\0';
+       }
+
        /*
         * To ensure we got the correct new password, hash it and
         * use it as a key to test the passed old password.
index c37c2ceab2de15176e2d33ac53449c7ba3424375..d06cb3b5bbdf80a5d44f7859e15138c06ec4c2b5 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,14 +89,16 @@ 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;
        int token;
-    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);
 
@@ -119,7 +113,10 @@ void close_file(files_struct *fsp, BOOL normal_close)
                del_share_mode(token, fsp);
        }
 
-       if(fd_attempt_close(fsp) == 0)
+       if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+               release_file_oplock(fsp);
+
+       if(fd_attempt_close(fsp->fd_ptr,&err) == 0)
                last_reference = True;
 
     fsp->fd_ptr = NULL;
@@ -129,7 +126,7 @@ void close_file(files_struct *fsp, BOOL normal_close)
 
        /* NT uses smbclose to start a print - weird */
        if (normal_close && fsp->print_file)
-               print_file(conn, SNUM(conn), fsp);
+               print_file(conn, fsp);
 
        /* check for magic scripts */
        if (normal_close) {
@@ -144,7 +141,8 @@ void close_file(files_struct *fsp, BOOL normal_close)
     if (normal_close && last_reference && delete_on_close) {
         DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
            fsp->fsp_name));
-               if(fsp->conn->vfs_ops.unlink(dos_to_unix(fsp->fsp_name, False)) != 0) {
+               if(dos_unlink(fsp->fsp_name) != 0) {
+
           /*
            * This call can potentially fail as another smbd may have
            * had the file open with delete on close set and deleted
@@ -157,30 +155,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.
         */
@@ -190,5 +204,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 db6c66f1d51cd32f568f8a9b7dc49c316c938e8f..393a3e7372ffe8fe6cc663cd45830e2824aaa844 100644 (file)
@@ -34,7 +34,7 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
        struct connect_record crec;
        pstring fname;
        int fd;
-       int mypid = getpid();
+       pid_t mypid = getpid();
        int i;
 
        DEBUG(3,("Yielding connection to %s\n",name));
@@ -42,7 +42,7 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
        if (max_connections <= 0)
                return(True);
 
-       bzero(&crec,sizeof(crec));
+       memset((char *)&crec,'\0',sizeof(crec));
 
        pstrcpy(fname,lp_lockdir());
        trim_string(fname,"","/");
@@ -85,7 +85,7 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
                return(False);
        }
 
-       bzero((void *)&crec,sizeof(crec));
+       memset((void *)&crec,'\0',sizeof(crec));
   
        /* remove our mark */
        if (sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
@@ -154,7 +154,7 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
                return False;
        }
 
-       total_recs = file_size(fname) / sizeof(crec);
+       total_recs = get_file_size(fname) / sizeof(crec);
                        
        /* find a free spot */
        for (i=0;i<max_connections;i++) {
@@ -168,10 +168,10 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
                if (Clear && crec.pid && !process_exists(crec.pid)) {
                        if(sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec)) {
               DEBUG(0,("claim_connection: ERROR: sys_lseek failed to seek \
-to %d\n", i*sizeof(crec) ));
+to %d\n", (int)(i*sizeof(crec)) ));
               continue;
             }
-                       bzero((void *)&crec,sizeof(crec));
+                       memset((void *)&crec,'\0',sizeof(crec));
                        write(fd, &crec,sizeof(crec));
                        if (foundi < 0) foundi = i;
                        continue;
@@ -192,7 +192,7 @@ to %d\n", i*sizeof(crec) ));
        }      
        
        /* fill in the crec */
-       bzero((void *)&crec,sizeof(crec));
+       memset((void *)&crec,'\0',sizeof(crec));
        crec.magic = 0x280267;
        crec.pid = getpid();
        if (conn) {
index 8cba8d0644a81b7a76028a24c567ceb81200345c..86a155f5267348ea4a55343ed8da4b7922717f90 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,7 +190,9 @@ 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;
@@ -219,7 +226,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 +241,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 b7ae2af47cb867c5b194efc274b389dc5adfa416..28faa9a06b7eea04f31eb95e48b9265235304b19 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)
+
+static dptr_struct *dptr_get(int key, BOOL forclose)
 {
-       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);
+  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 dir path for a dir index
+ 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.
+****************************************************************************/
+
 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,103 @@ 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);
+
+    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);
 
-  /* 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) {
+        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) {
 
-  /* 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;
+      /*
+       * 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);
+
+      /* 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);
+
+  dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
 
-  if (dirptrs[i].valid)
-    dptr_close(i);
+  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 */
 
-  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;
+  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));
@@ -364,20 +518,22 @@ BOOL dptr_fill(char *buf1,unsigned int key)
 
 
 /****************************************************************************
-return True is the offset is at zero
+ Return True if the offset is at zero.
 ****************************************************************************/
+
 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
+ 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 +548,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 +564,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 +575,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 +596,71 @@ 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 (dos_stat(pathreal,&sbuf) != 0) 
+      {
+        DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+        continue;
+      }
+
+      if (check_descend && !strequal(fname,".") && !strequal(fname,".."))
+        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;
-         }
+      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));
+      }
 
-         *size = sbuf.st_size;
-         *date = sbuf.st_mtime;
+      *size = sbuf.st_size;
+      *date = sbuf.st_mtime;
 
-         DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
+      DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
          
-         found = True;
-       }
+      found = True;
     }
+  }
 
   return(found);
 }
@@ -512,25 +678,26 @@ typedef struct
 
 
 /*******************************************************************
-open a directory
+ Open a directory.
 ********************************************************************/
+
 void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
 {
   Dir *dirp;
   char *n;
-  DIR *p = conn->vfs_ops.opendir(name);
+  DIR *p = dos_opendir(name);
   int used=0;
 
   if (!p) return(NULL);
   dirp = (Dir *)malloc(sizeof(Dir));
   if (!dirp) {
-    conn->vfs_ops.closedir(p);
+    closedir(p);
     return(NULL);
   }
   dirp->pos = dirp->numentries = dirp->mallocsize = 0;
   dirp->data = dirp->current = NULL;
 
-  while ((n = vfs_readdirname(conn, p)))
+  while ((n = dos_readdirname(p)))
   {
     int l = strlen(n)+1;
 
@@ -554,14 +721,15 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
     dirp->numentries++;
   }
 
-  conn->vfs_ops.closedir(p);
+  closedir(p);
   return((void *)dirp);
 }
 
 
 /*******************************************************************
-close a directory
+ Close a directory.
 ********************************************************************/
+
 void CloseDir(void *p)
 {
   Dir *dirp = (Dir *)p;
@@ -571,8 +739,9 @@ void CloseDir(void *p)
 }
 
 /*******************************************************************
-read from a directory
+ Read from a directory.
 ********************************************************************/
+
 char *ReadDirName(void *p)
 {
   char *ret;
@@ -589,8 +758,9 @@ char *ReadDirName(void *p)
 
 
 /*******************************************************************
-seek a dir
+ Seek a dir.
 ********************************************************************/
+
 BOOL SeekDir(void *p,int pos)
 {
   Dir *dirp = (Dir *)p;
@@ -608,8 +778,9 @@ BOOL SeekDir(void *p,int pos)
 }
 
 /*******************************************************************
-tell a dir position
+ Tell a dir position.
 ********************************************************************/
+
 int TellDir(void *p)
 {
   Dir *dirp = (Dir *)p;
index e6f1dc72064bcc253a802f560596a89566b8fcda..27393fe1c6c9b452ca7229d41ffa63058dc73b58 100644 (file)
@@ -50,7 +50,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode)
        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));
+    result &= lp_dir_mask(SNUM(conn));
     /* Add in force bits */
     result |= lp_force_dir_mode(SNUM(conn));
   } else { 
@@ -64,7 +64,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode)
       result |= S_IXOTH;  
  
     /* Apply mode mask */
-    result &= lp_create_mode(SNUM(conn));
+    result &= lp_create_mask(SNUM(conn));
     /* Add in force bits */
     result |= lp_force_create_mode(SNUM(conn));
   }
@@ -148,7 +148,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
 
   if (!st) {
     st = &st1;
-    if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1);
+    if (dos_stat(fname,st)) return(-1);
   }
 
   if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
@@ -179,14 +179,12 @@ 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(fname,unixmode));
+  return(dos_chmod(fname,unixmode));
 }
 
 
@@ -202,7 +200,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
 
   errno = 0;
 
-  if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0)
+  if(dos_utime(fname, times) == 0)
     return 0;
 
   if((errno != EPERM) && (errno != EACCES))
@@ -217,7 +215,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
      (as DOS does).
    */
 
-  if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0)
+  if(dos_stat(fname,&sb) != 0)
     return -1;
 
   /* Check if we have write access. */
@@ -230,7 +228,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
                         current_user.ngroups,current_user.groups)))) {
                  /* We are allowed to become root and change the filetime. */
                  become_root(False);
-                 ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times);
+                 ret = dos_utime(fname, times);
                  unbecome_root(False);
          }
   }
@@ -251,9 +249,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..8b48a921fde35e7eccb10db0ee420d91e691f6d3 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
@@ -36,7 +37,19 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
   if (fsp->print_file && lp_postscript(fsp->conn->service))
     offset = 3;
 
-  seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET);
+  seek_ret = sys_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) ));
@@ -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,40 +106,64 @@ 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);
+    readret = read(fsp->fd_ptr->fd,data,n);
     if (readret > 0) ret += readret;
   }
 
   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,488 @@ 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) {
+
+    if (sys_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, &token) == 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, token, 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, token);
+  }
+
+  /* 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 file_size)
+{
+  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 = file_size;
+  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 file_size)
+{
+  if(fsp->wcp) {
+    flush_write_cache(fsp, SIZECHANGE_FLUSH);
+    fsp->wcp->file_size = file_size;
+  }
+}
+
+/*******************************************************************
+ 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 sync_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);
+      fsync(fsp->fd_ptr->fd);
+    }
 #endif
 }
index 1d9c5ef754e6a0733f6945ebe91ee3600c68d0f4..64f63805f3250dc32b74897f45aaed351599d59b 100644 (file)
@@ -26,7 +26,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 +96,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,
@@ -230,9 +234,7 @@ 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( char *name, char *dirpath, char **start, SMB_STRUCT_STAT *pst)
 {
   stat_cache_entry *scp;
   stat_cache_entry *longest_hit = NULL;
@@ -285,7 +287,7 @@ static BOOL stat_cache_lookup(struct connection_struct *conn, char *name,
    * and then promote it to the top.
    */
 
-  if(conn->vfs_ops.stat(longest_hit->translated_name, pst) != 0) {
+  if(dos_stat( longest_hit->translated_name, pst) != 0) {
     /*
      * Discard this entry.
      */
@@ -309,35 +311,6 @@ static BOOL stat_cache_lookup(struct connection_struct *conn, char *name,
   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);
-}
-
 /****************************************************************************
 This routine is called to convert names from the dos namespace to unix
 namespace. It needs to handle any case conversions, mangling, format
@@ -359,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
@@ -443,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);
   }
@@ -463,7 +435,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
 
   pstrcpy(orig_path, name);
 
-  if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
+  if(stat_cache_lookup( name, dirpath, &start, &st)) {
     if(pst)
       *pst = st;
     return True;
@@ -473,7 +445,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
    * stat the name - if it exists then we are all done!
    */
 
-  if (conn->vfs_ops.stat(name,&st) == 0) {
+  if (dos_stat(name,&st) == 0) {
     stat_cache_add(orig_path, name);
     DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
     if(pst)
@@ -481,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));
 
@@ -492,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,'*'))
@@ -541,8 +511,7 @@ BOOL unix_convert(char *name,connection_struct *conn,
       /* 
        * Check if the name exists up to this point.
        */
-
-      if (conn->vfs_ops.stat(name, &st) == 0) {
+      if (dos_stat(name, &st) == 0) {
         /*
          * It exists. it must either be a directory or this must be
          * the last part of the path for it to be OK.
@@ -694,7 +663,7 @@ BOOL check_name(char *name,connection_struct *conn)
   if (!lp_symlinks(SNUM(conn)))
     {
       SMB_STRUCT_STAT statbuf;
-      if ( (conn->vfs_ops.lstat(dos_to_unix(name,False),&statbuf) != -1) &&
+      if ( (dos_lstat(name,&statbuf) != -1) &&
           (S_ISLNK(statbuf.st_mode)) )
         {
           DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
@@ -758,7 +727,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))
index 7f4533e7ae78ef10044a4ea2269e8c4c122b3d4c..d6203580cf54f563a5c79c3f24315ff113d0eeec 100644 (file)
@@ -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)) {
+                       sync_file(conn,fsp);
                }
        }
 }
 
+
 /****************************************************************************
 free up a fd_ptr
 ****************************************************************************/
index 0be558848ab5a4c32a939b1041bb409ddf12be03..4dadfaa9396e62a07a14849a85364c498b243f33 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* this module is retired, it is moved to lib/domain_namemap.c */
+#ifdef USING_GROUPNAME_MAP
+
+#include "includes.h"
+extern int DEBUGLEVEL;
+extern DOM_SID global_sam_sid;
+
+
+/**************************************************************************
+ Groupname map functionality. The code loads a groupname map file and
+ (currently) loads it into a linked list. This is slow and memory
+ hungry, but can be changed into a more efficient storage format
+ if the demands on it become excessive.
+***************************************************************************/
+
+typedef struct groupname_map {
+   ubi_slNode next;
+
+   char *windows_name;
+   DOM_SID windows_sid;
+   char *unix_name;
+   gid_t unix_gid;
+} groupname_map_entry;
+
+static ubi_slList groupname_map_list;
+
+/**************************************************************************
+ Delete all the entries in the groupname map list.
+***************************************************************************/
+
+static void delete_groupname_map_list(void)
+{
+  groupname_map_entry *gmep;
+
+  while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
+    if(gmep->windows_name)
+      free(gmep->windows_name);
+    if(gmep->unix_name)
+      free(gmep->unix_name);
+    free((char *)gmep);
+  }
+}
+
+/**************************************************************************
+ Load a groupname map file. Sets last accessed timestamp.
+***************************************************************************/
+
+void load_groupname_map(void)
+{
+  static time_t groupmap_file_last_modified = (time_t)0;
+  static BOOL initialized = False;
+  char *groupname_map_file = lp_groupname_map();
+  SMB_STRUCT_STAT st;
+  FILE *fp;
+  char *s;
+  pstring buf;
+  groupname_map_entry *new_ep;
+
+  if(!initialized) {
+    ubi_slInitList( &groupname_map_list );
+    initialized = True;
+  }
+
+  if (!*groupname_map_file)
+    return;
+
+  if(sys_stat(groupname_map_file, &st) != 0) {
+    DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
+               groupname_map_file, strerror(errno) ));
+    return;
+  }
+
+  /*
+   * Check if file has changed.
+   */
+  if( st.st_mtime <= groupmap_file_last_modified)
+    return;
+
+  groupmap_file_last_modified = st.st_mtime;
+
+  /*
+   * Load the file.
+   */
+
+  fp = sys_fopen(groupname_map_file,"r");
+  if (!fp) {
+    DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
+          groupname_map_file, strerror(errno)));
+    return;
+  }
+
+  /*
+   * Throw away any previous list.
+   */
+  delete_groupname_map_list();
+
+  DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
+
+  while((s=fgets_slash(buf,sizeof(buf),fp))!=NULL) {
+    pstring unixname;
+    pstring windows_name;
+    struct group *gptr;
+    DOM_SID tmp_sid;
+
+    DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
+
+    if (!*s || strchr("#;",*s))
+      continue;
+
+    if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
+      continue;
+
+    if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
+      continue;
+
+    trim_string(unixname, " ", " ");
+    trim_string(windows_name, " ", " ");
+
+    if (!*windows_name)
+      continue;
+
+    if(!*unixname)
+      continue;
+
+    DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
+             unixname, windows_name));
+
+    /*
+     * Attempt to get the unix gid_t for this name.
+     */
+
+    if((gptr = (struct group *)getgrnam(unixname)) == NULL) {
+      DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\
+Error was %s.\n", unixname, strerror(errno) ));
+      continue;
+    }
+
+    /*
+     * Now map to an NT SID.
+     */
+
+    if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
+      /*
+       * It's not a well known name, convert the UNIX gid_t
+       * to a rid within this domain SID.
+       */
+      tmp_sid = global_sam_sid;
+      tmp_sid.sub_auths[tmp_sid.num_auths++] = 
+                    pdb_gid_to_group_rid((gid_t)gptr->gr_gid);
+    }
+
+    /*
+     * Create the list entry and add it onto the list.
+     */
+
+    if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
+      DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
+      fclose(fp);
+      return;
+    } 
+
+    new_ep->unix_gid = gptr->gr_gid;
+    new_ep->windows_sid = tmp_sid;
+    new_ep->windows_name = strdup( windows_name );
+    new_ep->unix_name = strdup( unixname );
+
+    if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
+      DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
+      fclose(fp);
+      if(new_ep->windows_name != NULL)
+        free(new_ep->windows_name);
+      if(new_ep->unix_name != NULL)
+        free(new_ep->unix_name);
+      free((char *)new_ep);
+      return;
+    }
+    memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
+
+    ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
+  }
+
+  DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
+           ubi_slCount(&groupname_map_list)));
+           
+  fclose(fp);
+}
+
+/***********************************************************
+ Lookup a SID entry by gid_t.
+************************************************************/
+
+void map_gid_to_sid( gid_t gid, DOM_SID *psid)
+{
+  groupname_map_entry *gmep;
+
+  /*
+   * Initialize and load if not already loaded.
+   */
+  load_groupname_map();
+
+  for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
+       gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
+
+    if( gmep->unix_gid == gid) {
+      *psid = gmep->windows_sid;
+      DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
+               gmep->unix_name, gmep->windows_name ));
+      return;
+    }
+  }
+
+  /*
+   * If there's no map, convert the UNIX gid_t
+   * to a rid within this domain SID.
+   */
+  *psid = global_sam_sid;
+  psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
+
+  return;
+}
+#else /* USING_GROUPNAME_MAP */
+ void load_groupname_map(void) {;}
+#endif /* USING_GROUPNAME_MAP */
index eeb367bcb5c70e9867c5717123e67285d453b734..4e9418fa94006814b51431181ed9ac732be62971 100644 (file)
@@ -61,7 +61,6 @@ extern fstring global_myworkgroup;
 
 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,
@@ -82,7 +81,7 @@ static int CopyExpanded(connection_struct *conn,
        if (!src || !dst || !n || !(*dst)) return(0);
 
        StrnCpy(buf,src,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       pstring_sub(buf,"%S",lp_servicename(snum));
        standard_sub(conn,buf);
        StrnCpy(*dst,buf,*n);
        l = strlen(*dst) + 1;
@@ -95,7 +94,7 @@ static int CopyAndAdvance(char** dst, char* src, int* n)
 {
   int l;
   if (!src || !dst || !n || !(*dst)) return(0);
-  StrnCpy(*dst,src,*n);
+  StrnCpy(*dst,src,*n-1);
   l = strlen(*dst) + 1;
   (*dst) += l;
   (*n) -= l;
@@ -107,7 +106,7 @@ static int StrlenExpanded(connection_struct *conn, int snum, char* s)
        pstring buf;
        if (!s) return(0);
        StrnCpy(buf,s,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       pstring_sub(buf,"%S",lp_servicename(snum));
        standard_sub(conn,buf);
        return strlen(buf) + 1;
 }
@@ -117,7 +116,7 @@ static char* Expand(connection_struct *conn, int snum, char* s)
        static pstring buf;
        if (!s) return(NULL);
        StrnCpy(buf,s,sizeof(buf)/2);
-       string_sub(buf,"%S",lp_servicename(snum));
+       pstring_sub(buf,"%S",lp_servicename(snum));
        standard_sub(conn,buf);
        return &buf[0];
 }
@@ -139,70 +138,69 @@ static BOOL prefix_ok(char *str,char *prefix)
  cause of some of the ipc problems being experienced.  lkcl26dec97
 
  ******************************************************************/
+
 static void copy_trans_params_and_data(char *outbuf, int align,
-                               struct mem_buf *rparam, struct mem_buf *rdata,
-                               int param_offset, int data_offset,
-                               int param_len, int data_len)
+                               char *rparam, int param_offset, int param_len,
+                               char *rdata, int data_offset, int data_len)
 {
        char *copy_into = smb_buf(outbuf)+1;
 
+       if(param_len < 0)
+               param_len = 0;
+
+       if(data_len < 0)
+               data_len = 0;
+
        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) mem_buf_copy(copy_into, rparam, param_offset, param_len);
+       if (param_len)
+               memcpy(copy_into, &rparam[param_offset], param_len);
+
        copy_into += param_len + align;
-       if (data_len ) mem_buf_copy(copy_into, rdata , data_offset , data_len);
+
+       if (data_len )
+               memcpy(copy_into, &rdata[data_offset], data_len);
 }
 
 /****************************************************************************
-  send a trans reply
-  ****************************************************************************/
+ Send a trans reply.
+ ****************************************************************************/
+
 static void send_trans_reply(char *outbuf,
-                               struct mem_buf *rdata,
-                               struct mem_buf *rparam,
-                               uint16 *setup, int lsetup, int max_data_ret)
+                               char *rparam, int rparam_len,
+                               char *rdata, int rdata_len,
+                               BOOL buffer_too_large)
 {
-       int i;
        int this_ldata,this_lparam;
-       int tot_data=0,tot_param=0;
+       int tot_data_sent = 0;
+       int tot_param_sent = 0;
        int align;
 
-       int ldata  = rdata  ? mem_buf_len(rdata ) : 0;
-       int lparam = rparam ? mem_buf_len(rparam) : 0;
-
-       BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+       int ldata  = rdata  ? rdata_len : 0;
+       int lparam = rparam ? rparam_len : 0;
 
        if (buffer_too_large)
-       {
-               DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
-               ldata = max_data_ret;
-       }
+               DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));
 
-       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); /* hack */
+       this_ldata  = MIN(ldata,max_send - (500+this_lparam));
 
        align = ((this_lparam)%4);
 
-       set_message(outbuf,10+lsetup,1+align+this_ldata+this_lparam,True);
+       set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
 
        if (buffer_too_large)
        {
-               if (global_client_caps & CAP_STATUS32)
-               {
-                       /* 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 {
-                       SCVAL(outbuf, smb_rcls, ERRDOS);
-                       SSVAL(outbuf, smb_err, ERRmoredata);
-               }
+               /* 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, 0x80000000 | NT_STATUS_ACCESS_VIOLATION);
        }
 
        copy_trans_params_and_data(outbuf, align,
-                                  rparam     , rdata,
-                                  tot_param  , tot_data,
-                                  this_lparam, this_ldata);
+                                                               rparam, tot_param_sent, this_lparam,
+                                                               rdata, tot_data_sent, this_ldata);
 
        SSVAL(outbuf,smb_vwv0,lparam);
        SSVAL(outbuf,smb_vwv1,ldata);
@@ -212,46 +210,46 @@ static void send_trans_reply(char *outbuf,
        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_vwv9,0);
 
        show_msg(outbuf);
        send_smb(Client,outbuf);
 
-       tot_data = this_ldata;
-       tot_param = this_lparam;
+       tot_data_sent = this_ldata;
+       tot_param_sent = this_lparam;
 
-       while (tot_data < ldata || tot_param < lparam)
+       while (tot_data_sent < ldata || tot_param_sent < 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_sent, max_send - 500); /* hack */
+               this_ldata  = MIN(ldata -tot_data_sent, max_send - (500+this_lparam));
+
+               if(this_lparam < 0)
+                       this_lparam = 0;
+
+               if(this_ldata < 0)
+                       this_ldata = 0;
 
                align = (this_lparam%4);
 
                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);
+                                                                       rparam, tot_param_sent, this_lparam,
+                                                                       rdata, tot_data_sent, 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_vwv5,tot_param_sent);
                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_vwv8,tot_data_sent);
                SSVAL(outbuf,smb_vwv9,0);
 
                show_msg(outbuf);
                send_smb(Client,outbuf);
 
-               tot_data  += this_ldata;
-               tot_param += this_lparam;
+               tot_data_sent  += this_ldata;
+               tot_param_sent += this_lparam;
        }
 }
 
@@ -378,7 +376,10 @@ va_dcl
 #endif
   stringneeded = -1;
 
-  if (!p->curpos) return(0);
+  if (!p->curpos) {
+    va_end(args);
+    return(0);
+  }
 
   switch( *p->curpos++ ) {
   case 'W':                    /* word (2 byte) */
@@ -400,7 +401,7 @@ va_dcl
     needed = get_counter(&p->curpos);
     {
       char *s = va_arg(args,char*);
-      if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
+      if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed-1);
     }
     break;
   case 'z':                    /* offset to zero terminated string (4 byte) */
@@ -656,7 +657,7 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
       return;
     }
 
-    bzero(p, 8192*sizeof(char));
+    memset(p, '\0',8192*sizeof(char));
     q=p;
 
     /* lookup the long printer driver name in the file description */
@@ -809,8 +810,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
   print_queue_struct *queue=NULL;
   print_status_struct status;
   
-  bzero(&status,sizeof(status));
-  bzero(&desc,sizeof(desc));
+  memset((char *)&status,'\0',sizeof(status));
+  memset((char *)&desc,'\0',sizeof(desc));
  
   p = skip_string(p,1);
   uLevel = SVAL(p,0);
@@ -823,7 +824,20 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
  
   /* check it's a supported varient */
   if (!prefix_ok(str1,"zWrLh")) return False;
-  if (!check_printq_info(&desc,uLevel,str2,str3)) 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)) {
@@ -908,13 +922,26 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
   int* subcntarr = NULL;
   int queuecnt, subcnt=0, succnt=0;
  
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(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;
+  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))
@@ -1057,7 +1084,7 @@ static int get_server_info(uint32 servertype,
       (*servers) = (struct srv_info_struct *)
        Realloc(*servers,sizeof(**servers)*alloced);
       if (!(*servers)) return(0);
-      bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
+      memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
     }
     s = &(*servers)[count];
     
@@ -1297,7 +1324,7 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
 
   *rdata_len = fixed_len + string_len;
   *rdata = REALLOC(*rdata,*rdata_len);
-  bzero(*rdata,*rdata_len);
+  memset(*rdata,'\0',*rdata_len);
   
   p2 = (*rdata) + fixed_len;   /* auxilliary data (strings) will go here */
   p = *rdata;
@@ -1355,7 +1382,6 @@ static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *pa
   if (!prefix_ok(str1,"zWrLeh")) return False;
   
   *rdata_len = 0;
-  *rdata = NULL;
   
   *rparam_len = 8;
   *rparam = REALLOC(*rparam,*rparam_len);
@@ -1650,6 +1676,8 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
 
   p = skip_string(p,1);
 
+  memset(pass1,'\0',sizeof(pass1));
+  memset(pass2,'\0',sizeof(pass2));
   memcpy(pass1,p,16);
   memcpy(pass2,p+16,16);
 
@@ -1680,7 +1708,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
    * Older versions of Windows seem to do this.
    */
 
-  if (password_ok(user, pass1,strlen(pass1),NULL, NULL) &&
+  if (password_ok(user, pass1,strlen(pass1),NULL) &&
       chgpasswd(user,pass1,pass2,False))
   {
     SSVAL(*rparam,0,NERR_Success);
@@ -1703,8 +1731,8 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
     }
   }
 
-  bzero(pass1,sizeof(fstring));
-  bzero(pass2,sizeof(fstring));         
+  memset((char *)pass1,'\0',sizeof(fstring));
+  memset((char *)pass2,'\0',sizeof(fstring));   
         
   return(True);
 }
@@ -2005,7 +2033,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
                                    !become_service(fconn,True))
                                        break;
              
-                               if (conn->vfs_ops.rename(dos_to_unix(fsp->fsp_name,False),name) == 0) {
+                               if (dos_rename(fsp->fsp_name,name) == 0) {
                                        string_set(&fsp->fsp_name,name);
                                }
                                break;
@@ -2091,7 +2119,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
       pstring comment;
       uint32 servertype= lp_default_server_announce();
 
-      pstrcpy(comment,lp_serverstring());
+      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++)
@@ -2450,7 +2478,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
                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, lp_logon_path());
+               pstrcpy(p2, lp_logon_home());
                p2 = skip_string(p2,1);
                SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
                pstrcpy(p2,"");
@@ -2486,12 +2514,15 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
                SSVAL(p,42,
                conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
                SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
-               pstrcpy(p2,lp_logon_path());
+               pstrcpy(p2,lp_logon_home());
                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 */
+               SIVAL(p,54,PTR_DIFF(p2,*rdata));                /* script_path */
+               pstrcpy(p2,lp_logon_script());
+               standard_sub( conn, p2 );             
+               p2 = skip_string(p2,1);
                if (uLevel == 2)
                {
                        SIVAL(p,60,0);          /* auth_flags */
@@ -2590,12 +2621,11 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
   int uLevel;
   struct pack_desc desc;
   char* name;
-  char* logon_script;
 
   uLevel = SVAL(p,0);
   name = p + 2;
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
 
@@ -2636,9 +2666,12 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
 
 /* JHT - By calling lp_logon_script() and standard_sub() we have */
 /* made sure all macros are fully substituted and available */
-    logon_script = lp_logon_script();
-    standard_sub( conn, logon_script );
-    PACKS(&desc,"z", logon_script);            /* script path */
+    {
+      pstring logon_script;
+      pstrcpy(logon_script,lp_logon_script());
+      standard_sub( conn, logon_script );
+      PACKS(&desc,"z", logon_script);          /* script path */
+    }
 /* End of JHT mods */
 
     PACKI(&desc,"D",0x00000000);               /* reserved */
@@ -2706,8 +2739,8 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
 
   uLevel = SVAL(p,2);
 
-  bzero(&desc,sizeof(desc));
-  bzero(&status,sizeof(status));
+  memset((char *)&desc,'\0',sizeof(desc));
+  memset((char *)&status,'\0',sizeof(status));
 
   DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
 
@@ -2767,8 +2800,8 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
   print_queue_struct *queue=NULL;
   print_status_struct status;
 
-  bzero(&desc,sizeof(desc));
-  bzero(&status,sizeof(status));
+  memset((char *)&desc,'\0',sizeof(desc));
+  memset((char *)&status,'\0',sizeof(status));
 
   p = skip_string(p,1);
   uLevel = SVAL(p,0);
@@ -2880,7 +2913,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
   struct pack_desc desc;
   int snum;
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   p = skip_string(p,1);
   uLevel = SVAL(p,0);
@@ -2939,7 +2972,7 @@ static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,
   struct pack_desc desc;
   int services = lp_numservices();
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   uLevel = SVAL(p,0);
 
@@ -2994,7 +3027,7 @@ static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *para
   int succnt;
   struct pack_desc desc;
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   uLevel = SVAL(p,0);
 
@@ -3038,7 +3071,7 @@ static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param
   int succnt;
   struct pack_desc desc;
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   uLevel = SVAL(p,0);
 
@@ -3083,7 +3116,7 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
   int succnt;
   struct pack_desc desc;
 
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
 
   uLevel = SVAL(p,0);
 
@@ -3094,7 +3127,7 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
   if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
 
   if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
-  bzero(&desc,sizeof(desc));
+  memset((char *)&desc,'\0',sizeof(desc));
   desc.base = *rdata;
   desc.buflen = mdrcnt;
   desc.format = str2;
@@ -3117,35 +3150,48 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,
   return(True);
 }
 
-static void api_rpc_trans_reply(char *outbuf,
-                               pipes_struct *p)
+/****************************************************************************
+ Start the first part of an RPC reply which began with an SMBtrans request.
+****************************************************************************/
+
+static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
 {
-       send_trans_reply(outbuf, p->rsmb_pdu.data, NULL, NULL, 0, p->file_offset);
+       char *rdata = malloc(p->max_trans_reply);
+       int data_len;
 
-       if (mem_buf_len(p->rsmb_pdu.data) <= p->file_offset)
-       {
-               /* all of data was sent: no need to wait for SMBreadX calls */
-               mem_free_data(p->rsmb_pdu.data);
+       if(rdata == NULL) {
+               DEBUG(0,("api_rpc_trans_reply: malloc fail.\n"));
+               return False;
        }
+
+       if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
+               free(rdata);
+               return False;
+       }
+
+       send_trans_reply(outbuf, NULL, 0, rdata, data_len, (int)prs_offset(&p->rdata) > data_len);
+
+       free(rdata);
+       return True;
 }
 
 /****************************************************************************
  WaitNamedPipeHandleState 
 ****************************************************************************/
-static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param)
+
+static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
 {
        uint16 priority;
 
-       if (!param) return False;
+       if (!param || param_len < 2)
+               return False;
 
-       priority = param[0] + (param[1] << 8);
+       priority = SVAL(param,0);
        DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority));
 
-       if (wait_rpc_pipe_hnd_state(p, priority))
-       {
+       if (wait_rpc_pipe_hnd_state(p, priority)) {
                /* now send the reply */
-               send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset);
-
+               send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
                return True;
        }
        return False;
@@ -3155,20 +3201,20 @@ static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param)
 /****************************************************************************
  SetNamedPipeHandleState 
 ****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
+
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
 {
        uint16 id;
 
-       if (!param) return False;
+       if (!param || param_len < 2)
+               return False;
 
-       id = param[0] + (param[1] << 8);
+       id = SVAL(param,0);
        DEBUG(4,("SetNamedPipeHandleState to code %x\n", id));
 
-       if (set_rpc_pipe_hnd_state(p, id))
-       {
+       if (set_rpc_pipe_hnd_state(p, id)) {
                /* now send the reply */
-               send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset);
-
+               send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
                return True;
        }
        return False;
@@ -3176,111 +3222,93 @@ static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
 
 
 /****************************************************************************
when no reply is generated, indicate unsupported.
When no reply is generated, indicate unsupported.
  ****************************************************************************/
+
 static BOOL api_no_reply(char *outbuf, int max_rdata_len)
 {
-       struct mem_buf rparam;
-
-       mem_init(&rparam, 0);
-       mem_alloc_data(&rparam, 4);
-
-       rparam.offset.start = 0;
-       rparam.offset.end   = 4;
+       char rparam[4];
 
        /* unsupported */
-       SSVAL(rparam.data,0,NERR_notsupported);
-       SSVAL(rparam.data,2,0); /* converter word */
+       SSVAL(rparam,0,NERR_notsupported);
+       SSVAL(rparam,2,0); /* converter word */
 
        DEBUG(3,("Unsupported API fd command\n"));
 
        /* now send the reply */
-       send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len);
-
-       mem_free_data(&rparam);
+       send_trans_reply(outbuf, rparam, 4, NULL, 0, False);
 
-       return(-1);
+       return -1;
 }
 
 /****************************************************************************
-  handle remote api calls delivered to a named pipe already opened.
-  ****************************************************************************/
+ 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)
 {
-       BOOL reply    = False;
-
-       uint16 pnum;
-       uint16 subcommand;
+       BOOL reply = False;
        pipes_struct *p = NULL;
+       int pnum;
+       int subcommand;
 
        DEBUG(5,("api_fd_reply\n"));
 
        /* First find out the name of this file. */
-       if (suwcnt != 2)
-       {
+       if (suwcnt != 2) {
                DEBUG(0,("Unexpected named pipe transaction.\n"));
                return(-1);
        }
 
        /* Get the file handle and hence the file name. */
-       pnum = setup[1];
-       subcommand = setup[0];
-       p = get_rpc_pipe(pnum);
+       /* 
+        * NB. The setup array has already been transformed
+        * via SVAL and so is in gost byte order.
+        */
+       pnum = ((int)setup[1]) & 0xFFFF;
+       subcommand = ((int)setup[0]) & 0xFFFF;
 
-       if (p != NULL)
-       {
-               DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
-                                 subcommand, p->name, pnum));
+       if(!(p = get_rpc_pipe(pnum))) {
+               DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+               return api_no_reply(outbuf, mdrcnt);
+       }
 
-               /* record maximum data length that can be transmitted in an SMBtrans */
-               p->file_offset          = mdrcnt;
-               p->prev_pdu_file_offset = 0;
+       DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum));
 
-                DEBUG(10,("api_fd_reply: p:%p file_offset: %d\n",
-                           p, p->file_offset));
+       /* record maximum data length that can be transmitted in an SMBtrans */
+       p->max_trans_reply = mdrcnt;
 
-               switch (subcommand)
-               {
-                       case 0x26:
-                       {
-                               reply = rpc_to_smb(p, data, tdscnt);
-                               if (reply)
-                               {
-                                       api_rpc_trans_reply(outbuf, p);
-                               }
-                               break;
-                       }
-                       case 0x53:
-                       {
-                               /* Wait Named Pipe Handle state */
-                               reply = api_WNPHS(outbuf, p, params);
-                               break;
-                       }
-                       case 0x01:
-                       {
-                               /* Set Named Pipe Handle state */
-                               reply = api_SNPHS(outbuf, p, params);
-                               break;
-                       }
-               }
-       }
-       else
-       {
-               DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+       DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply));
+
+       switch (subcommand) {
+       case 0x26:
+               /* dce/rpc command */
+               reply = rpc_command(p, data, tdscnt);
+               if (reply)
+                       reply = api_rpc_trans_reply(outbuf, p);
+               break;
+       case 0x53:
+               /* Wait Named Pipe Handle state */
+               reply = api_WNPHS(outbuf, p, params, tpscnt);
+               break;
+       case 0x01:
+               /* Set Named Pipe Handle state */
+               reply = api_SNPHS(outbuf, p, params, tpscnt);
+               break;
        }
 
        if (!reply)
-       {
                return api_no_reply(outbuf, mdrcnt);
-       }
+
        return -1;
 }
 
 /****************************************************************************
-  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,
@@ -3300,8 +3328,9 @@ static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *
 
 
 /****************************************************************************
-  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,
@@ -3364,14 +3393,13 @@ struct
 
 
 /****************************************************************************
-  handle remote api calls
-  ****************************************************************************/
+ Handle remote api calls
+ ****************************************************************************/
+
 static 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;
-  struct mem_buf rdata_buf;
-  struct mem_buf rparam_buf;
   char *rdata = NULL;
   char *rparam = NULL;
   int rdata_len = 0;
@@ -3379,7 +3407,10 @@ static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data
   BOOL reply=False;
   int i;
 
-  SMB_ASSERT(params != 0);
+  if (!params) {
+         DEBUG(0,("ERROR: NULL params in api_reply()\n"));
+         return 0;
+  }
 
   api_command = SVAL(params,0);
 
@@ -3389,15 +3420,20 @@ static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data
           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)
-      {
+  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) bzero(rdata,1024);
-  rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
+  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"));
@@ -3409,29 +3445,24 @@ static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data
 
 
   if (rdata_len > mdrcnt ||
-      rparam_len > mprcnt)
-    {
+      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);
 
-      
-  mem_create(&rdata_buf , rdata , 0, rdata_len , 0, False);
-  mem_create(&rparam_buf, rparam, 0, rparam_len, 0, False);
-
-  /* now send the reply */
-  send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);
+  send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
 
-  if (rdata ) free(rdata);
-  if (rparam) free(rparam);
+  if (rdata )
+    free(rdata);
+  if (rparam)
+    free(rparam);
   
-  return(-1);
+  return -1;
 }
 
 /****************************************************************************
@@ -3445,9 +3476,7 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na
        DEBUG(3,("named pipe command on <%s> name\n", name));
 
        if (strequal(name,"LANMAN"))
-       {
                return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
-       }
 
        if (strequal(name,"WKSSVC") ||
            strequal(name,"SRVSVC") ||
@@ -3460,26 +3489,23 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na
        }
 
        if (strlen(name) < 1)
-       {
                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]));
-       }
 
        return 0;
 }
 
 
 /****************************************************************************
-  reply to a SMBtrans
-  ****************************************************************************/
+ Reply to a SMBtrans.
+ ****************************************************************************/
+
 int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize)
 {
        fstring name;
-        int name_offset = 0;
+       int name_offset = 0;
        char *data=NULL,*params=NULL;
        uint16 *setup=NULL;
        int outsize = 0;
@@ -3497,7 +3523,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
        int dsoff = SVAL(inbuf,smb_vwv12);
        int suwcnt = CVAL(inbuf,smb_vwv13);
 
-       bzero(name, sizeof(name));
+       memset(name, '\0',sizeof(name));
        fstrcpy(name,smb_buf(inbuf));
 
        if (dscnt > tdscnt || pscnt > tpscnt) {
@@ -3523,7 +3549,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
        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)));
+          DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
                  return(ERROR(ERRDOS,ERRnomem));
         } 
                for (i=0;i<suwcnt;i++)
@@ -3546,16 +3572,19 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
       
                ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
 
-               if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret) {
+               if ((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 (params) free(params);
-                       if (data) free(data);
-                       if (setup) free(setup);
+                       if (params)
+                               free(params);
+                       if (data)
+                               free(data);
+                       if (setup)
+                               free(setup);
                        return(ERROR(ERRSRV,ERRerror));
                }
 
@@ -3589,14 +3618,13 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
        DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
                 name,tdscnt,tpscnt,suwcnt));
        
-        /*
-         * WinCE wierdness....
-         */
+       /*
+        * WinCE wierdness....
+        */
 
-        if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine,
-                                strlen(local_machine)) == 0)) {
-          name_offset = strlen(local_machine)+1;
-        }
+       if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine, strlen(local_machine)) == 0) &&
+                       (name[strlen(local_machine)+1] == '\\'))
+               name_offset = strlen(local_machine)+1;
 
        if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) {
                DEBUG(5,("calling named_pipe\n"));
@@ -3609,9 +3637,12 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
        }
 
        
-       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);
index b829746a32644de609f7d2c1add24a2b526b047d..48e16e533222b12e8f6bb5d8a7daa8a38e40f09c 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,12 +112,13 @@ 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 )
@@ -148,7 +151,7 @@ static void init_chartest( void )
   char          *illegalchars = "*\\/?<>|\":";
   unsigned char *s;
   
-  bzero( (char *)chartest, 256 );
+  memset( (char *)chartest, '\0', 256 );
 
   for( s = (unsigned char *)illegalchars; *s; s++ )
     chartest[*s] = ILLEGAL_MASK;
@@ -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 );
 
@@ -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;
@@ -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..2f94bdf111b831cd3ed3d95e2ab5c707f86f160a 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) {
@@ -74,10 +74,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 +102,6 @@ int reply_sends(connection_struct *conn,
 
   msgpos = 0;
 
-
   if (! (*lp_msg_command()))
     return(ERROR(ERRSRV,ERRmsgoff));
 
@@ -113,7 +115,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 +144,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 +177,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 +207,3 @@ int reply_sendend(connection_struct *conn,
 
   return(outsize);
 }
-
index 0b48b0e2b256094834297721dfdbb390911a29af..b2366b0a3794b14ad6c61865325f4b5c0b8f1b5a 100644 (file)
@@ -26,8 +26,6 @@ extern int Protocol;
 extern int max_recv;
 extern fstring global_myworkgroup;
 extern fstring remote_machine;
-extern pstring myhostname;
-extern dfs_internal dfs_struct;
 
 /****************************************************************************
 reply for the core protocol
@@ -160,6 +158,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);
@@ -168,32 +176,9 @@ 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 (lp_security() == SEC_SERVER)
-       {
-               cli = server_cryptkey();
-       }
+  if (lp_security() == SEC_SERVER) {
+         cli = server_cryptkey();
+  }
 
   if (cli) {
          DEBUG(3,("using password server validation\n"));
@@ -218,13 +203,12 @@ static int reply_nt1(char *outbuf)
   if (doencrypt) secword |= 2;
 
   /* decide where (if) to put the encryption challenge, and
-     follow it with the OEM'd domain name in Unicode.
+     follow it with the OEM'd domain name
    */
-  data_len = crypt_len + (strlen(global_myworkgroup)+1)*2;
+  data_len = crypt_len + strlen(global_myworkgroup) + 1;
 
   set_message(outbuf,17,data_len,True);
-  ascii_to_unibuf(smb_buf(outbuf)+crypt_len, global_myworkgroup,
-                  (strlen(global_myworkgroup)+1)*2);
+  pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
 
   CVAL(outbuf,smb_vwv1) = secword;
   SSVALS(outbuf,smb_vwv16+1,crypt_len);
@@ -268,6 +252,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]
@@ -281,29 +273,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
-       XENIX CORE                                      2      2
+       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 {
@@ -346,17 +340,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"))
@@ -382,6 +376,9 @@ int reply_negprot(connection_struct *conn,
   case ARCH_WINNT:
     set_remote_arch(RA_WINNT);
     break;
+  case ARCH_WIN2K:
+    set_remote_arch(RA_WIN2K);
+    break;
   case ARCH_OS2:
     set_remote_arch(RA_OS2);
     break;
@@ -394,7 +391,7 @@ int reply_negprot(connection_struct *conn,
   reload_services(True);      
     
   /* a special case to stop password server loops */
-  if (Index == 1 && strequal(remote_machine,myhostname) && 
+  if (Index == 1 && strequal(remote_machine,myhostname()) && 
       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
     exit_server("Password server loop!");
   
index 70023e240764c98e9083b0fcf05a09cfc8aad7f4..9615c5ada25afb7ab68cb38ae4f8edb3624ff4ee 100644 (file)
@@ -37,17 +37,14 @@ 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",
   "\\lsass",
   "\\lsarpc",
   "\\winreg",
-  "\\spoolss",
   NULL
 };
 
@@ -58,7 +55,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 +75,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.
@@ -355,18 +359,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 +397,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,11 +479,40 @@ 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.
 ****************************************************************************/
@@ -487,32 +531,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));
 
        p = open_rpc_pipe_p(fname, conn, vuid);
@@ -547,7 +574,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;
@@ -556,6 +583,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
@@ -576,9 +604,24 @@ 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.
        */
@@ -600,26 +643,17 @@ int reply_ntcreate_and_X(connection_struct *conn,
 
       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;
@@ -654,11 +688,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
      * desired access and the share access.
         */
        
-       if((smb_open_mode = map_share_mode(fname, desired_access, 
+       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.
@@ -670,11 +706,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) {
@@ -696,9 +728,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
                
        unixmode = unix_mode(conn,smb_attr | aARCH);
     
-       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.
         */
@@ -706,8 +735,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);
 
@@ -733,13 +762,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
@@ -752,21 +780,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;
@@ -782,15 +843,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(dos_stat(fsp->fsp_name, &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 (!fsp->stat_open && sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
                        close_file(fsp,False);
                        restore_case_semantics(file_attributes);
                        return(ERROR(ERRDOS,ERRnoaccess));
@@ -817,9 +876,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;
@@ -828,8 +887,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;
@@ -861,6 +926,7 @@ 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, 
@@ -893,6 +959,7 @@ 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;
 
   /* 
    * We need to construct the open_and_X ofun value from the
@@ -914,8 +981,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.
+       */
+
+      StrnCpy(fname,params+53,fname_len);
+      fname[fname_len] = '\0';
+
+      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.
@@ -951,17 +1034,26 @@ 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);
 
-       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) {
@@ -983,17 +1075,6 @@ static int call_nt_transact_create(connection_struct *conn,
   
     unixmode = unix_mode(conn,smb_attr | aARCH);
     
-    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.
      */
@@ -1012,37 +1093,96 @@ 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(dos_stat(fsp->fsp_name, &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(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+              close_file(fsp,True);
+              restore_case_semantics(file_attributes);
+              return(ERROR(ERRDOS,ERRnoaccess));
+          }
+      } else {
+          if (!fsp->stat_open && sys_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)
@@ -1063,7 +1203,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;
     }
   }
@@ -1075,8 +1215,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);
@@ -1119,7 +1267,7 @@ static int call_nt_transact_create(connection_struct *conn,
   }
 
   /* 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;
 }
@@ -1156,6 +1304,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,
@@ -1179,7 +1328,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));
@@ -1190,6 +1339,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
@@ -1201,9 +1362,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;
 
@@ -1243,9 +1404,93 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro
   send_smb(Client,outbuf);
 }
 
+/****************************************************************************
+ Create the hash we will use to determine if the contents changed.
+*****************************************************************************/
+
+static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
+{
+  SMB_STRUCT_STAT st;
+  files_struct *fsp = cnbp->fsp;
+
+  memset((char *)change_data, '\0', sizeof(change_data));
+
+  /* 
+   * 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;
+
+  /*
+   * 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).
+   */
+
+  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);
+
+    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 );
@@ -1274,7 +1519,34 @@ static void remove_pending_change_notify_requests_by_mid(int mid)
 
   while(cnbp != NULL) {
     if(SVAL(cnbp->request_buf,smb_mid) == mid) {
-      change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
+      change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |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,0xC0000000 |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;
@@ -1287,18 +1559,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
@@ -1306,8 +1580,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);
@@ -1343,9 +1616,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.
        */
@@ -1356,13 +1629,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));
@@ -1378,22 +1650,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);
 
@@ -1414,28 +1698,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
@@ -1452,43 +1730,661 @@ name = %s\n", fsp->fsp_name ));
 }
 
 /****************************************************************************
- Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though).
+ Map unix perms to NT.
 ****************************************************************************/
-static int call_nt_transact_query_security_desc(connection_struct *conn,
-                                               char *inbuf, char *outbuf, 
-                                               int length, 
-                                                int bufsize, 
-                                                char **ppsetup, char **ppparams, char **ppdata)
+
+static SEC_ACCESS map_unix_perms( int *pacl_type, mode_t perm, int r_mask, int w_mask, int x_mask, BOOL is_directory)
 {
-  static BOOL logged_message = False;
+       SEC_ACCESS sa;
+       uint32 nt_mask = 0;
 
-  if(!logged_message) {
-    DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
-    logged_message = True; /* Only print this once... */
-  }
+       *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;
+       }
+       init_sec_access(&sa,nt_mask);
+       return sa;
+}
+
+/****************************************************************************
+ 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)
+{
+  extern DOM_SID global_sam_sid;
+  extern DOM_SID global_sid_World;
+  SMB_STRUCT_STAT sbuf;
+  SEC_ACE ace_list[6];
+  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_World);
+    sid_copy( &group_sid, &global_sid_World);
+  } else {
+
+    if(fsp->is_directory || fsp->fd_ptr == NULL) {
+      if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
+        return 0;
+      }
+    } else {
+      if(sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+        return 0;
+      }
+    }
+
+    /*
+     * Get the owner, group and world SIDs.
+     */
+
+    sid_copy(&owner_sid, &global_sam_sid);
+    sid_copy(&group_sid, &global_sam_sid);
+    sid_append_rid(&owner_sid, pdb_uid_to_user_rid(sbuf.st_uid));
+    sid_append_rid(&group_sid, pdb_gid_to_group_rid(sbuf.st_gid));
+
+    /*
+     * 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)
+      init_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
+                   owner_access, 0);
+
+    if(group_access.mask)
+      init_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
+                   group_access, 0);
+
+    if(other_access.mask)
+      init_sec_ace(&ace_list[num_acls++], &global_sid_World, 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);
+
+      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)
+        init_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)
+        init_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)
+        init_sec_ace(&ace_list[num_acls++], &global_sid_World, other_acl_type,
+                     other_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+    }
+
+    if(num_acls)
+      if((psa = make_sec_acl( 3, num_acls, ace_list)) == NULL) {
+        DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+        return 0;
+      }
+  }
+
+  *ppdesc = make_standard_sec_desc( &owner_sid, &group_sid, psa, &sec_desc_size);
+
+  if(!*ppdesc) {
+    DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
+    sec_desc_size = 0;
+  }
+
+  free_sec_acl(&psa);
+
+  return sec_desc_size;
+}
 
-  return(ERROR(ERRSRV,ERRnosupport));
-}
-   
 /****************************************************************************
- Reply to set a security descriptor - currently this is not implemented (it
- is planned to be though).
+ Reply to query a security descriptor - currently this is not implemented (it
+ 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 **ppsetup, char **ppparams, char **ppdata)
+{
+  uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+  char *params = *ppparams;
+  char *data = *ppdata;
+  prs_struct pd;
+  SEC_DESC *psd;
+  size_t sec_desc_size;
+
+  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);
+
+    send_nt_replies(inbuf, outbuf, bufsize, 0xC0000000|NT_STATUS_BUFFER_TOO_SMALL,
+                    params, 4, *ppdata, 0);
+    return -1;
+  }
+
+  /*
+   * Allocate the data we will point this at.
+   */
+
+  data = *ppdata = Realloc(*ppdata, sec_desc_size);
+  if(data == NULL) {
+    free_sec_desc(&psd);
+    return(ERROR(ERRDOS,ERRnomem));
+  }
+
+  memset(data, '\0', sec_desc_size);
+
+  /*
+   * Init the parse struct we will marshall into.
+   */
+
+  prs_init(&pd, 0, 4, MARSHALL);
+
+  /*
+   * Setup the prs_struct to point at the memory we just
+   * allocated.
+   */
+       
+  prs_give_memory( &pd, data, (uint32)sec_desc_size, False);
+
+  /*
+   * Finally, linearize into the outgoing buffer.
+   */
+
+  if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
+    free_sec_desc(&psd);
+    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));
+  }
+
+  /*
+   * Now we can delete the security descriptor.
+   */
+
+  free_sec_desc(&psd);
+
+  send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
+  return -1;
+}
+
+/****************************************************************************
+ Validate a SID.
+****************************************************************************/
+
+static BOOL validate_unix_sid( DOM_SID *psid, uint32 *prid, DOM_SID *sd_sid)
+{
+  extern DOM_SID global_sam_sid;
+  DOM_SID sid;
+
+  if(!sd_sid) {
+    DEBUG(5,("validate_unix_sid: sid missing.\n"));
+    return False;
+  }
+
+  sid_copy(psid, sd_sid);
+  sid_copy(&sid, sd_sid);
+
+  if(!sid_split_rid(&sid, prid)) {
+    DEBUG(5,("validate_unix_sid: cannot get RID from sid.\n"));
+    return False;
+  }
+
+  if(!sid_equal( &sid, &global_sam_sid)) {
+    DEBUG(5,("validate_unix_sid: sid is not ours.\n"));
+    return False;
+  }
+
+  return True;
+}
+
+/****************************************************************************
+ 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(uid_t *puser, gid_t *pgrp, mode_t *pmode, uint32 security_info_sent,
+                                  SEC_DESC *psd, BOOL is_directory)
+{
+  extern DOM_SID global_sid_World;
+  DOM_SID owner_sid;
+  DOM_SID grp_sid;
+  uint32 owner_rid;
+  uint32 grp_rid;
+  SEC_ACL *dacl = psd->dacl;
+  int i;
+
+  *pmode = 0;
+  *puser = (uid_t)-1;
+  *pgrp = (gid_t)-1;
+
+  if(security_info_sent == 0) {
+    DEBUG(0,("unpack_unix_permissions: no security info sent !\n"));
+    return False;
+  }
+
+  /*
+   * Validate the owner and group SID's.
+   */
+
+  memset(&owner_sid, '\0', sizeof(owner_sid));
+  memset(&grp_sid, '\0', sizeof(grp_sid));
+
+  DEBUG(5,("unpack_unix_permissions: validating owner_sid.\n"));
+
+  /*
+   * Don't immediately fail if the owner sid cannot be validated.
+   * This may be a group chown only set.
+   */
+
+  if(!validate_unix_sid( &owner_sid, &owner_rid, psd->owner_sid))
+    DEBUG(3,("unpack_unix_permissions: unable to validate owner sid.\n"));
+  else if(security_info_sent & OWNER_SECURITY_INFORMATION)
+    *puser = pdb_user_rid_to_uid(owner_rid);
+
+  /*
+   * Don't immediately fail if the group sid cannot be validated.
+   * This may be an owner chown only set.
+   */
+
+  if(!validate_unix_sid( &grp_sid, &grp_rid, psd->grp_sid))
+    DEBUG(3,("unpack_unix_permissions: unable to validate group sid.\n"));
+  else if(security_info_sent & GROUP_SECURITY_INFORMATION)
+    *pgrp = pdb_user_rid_to_gid(grp_rid);
+
+  /*
+   * 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_list[i];
+
+    if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) &&
+       (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
+      DEBUG(3,("unpack_unix_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_unix_permissions: ignoring inherit only ACE.\n"));
+        continue;
+      }
+
+      psa->flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT);
+    }
+
+    if(psa->flags != 0) {
+      DEBUG(1,("unpack_unix_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, &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, &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_World)) {
+      /*
+       * 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_unix_permissions: unknown SID used in ACL.\n"));
+      return False;
+    }
+  }
+
+  return True;
+}
+
+/****************************************************************************
+ 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 = NULL;
+  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 to point at the memory we just
+   * allocated.
+   */
+       
+  prs_give_memory( &pd, data, total_data_count, False);
+
+  /*
+   * Finally, unmarshall from the data buffer.
+   */
+
+  if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
+    free_sec_desc(&psd);
+    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));
+
+  /*
+   * Unpack the user/group/world id's and permissions.
+   */
+
+  if(!unpack_nt_permissions( &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);
+
+  /*
+   * Get the current state of the file.
+   */
+
+  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 = dos_stat(fsp->fsp_name, &sbuf);
+    else
+      ret = sys_fstat(fsp->fd_ptr->fd,&sbuf);
+
+    if(ret != 0) {
+      return(UNIXERROR(ERRDOS,ERRnoaccess));
+    }
+  }
+
+  /*
+   * 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 = dos_stat(fsp->fsp_name, &sbuf);
+      else
+        ret = sys_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(dos_chmod( fsp->fsp_name, 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;
 }
    
 /****************************************************************************
@@ -1675,7 +2571,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 2c12d425b95778d74fafee456f231076fed33017..4491082b2c54fbf347900ef9ecc4177c09623d1f 100644 (file)
@@ -25,22 +25,22 @@ 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
 ****************************************************************************/
-static int fd_attempt_open(struct connection_struct *conn, char *fname, 
-                          int flags, mode_t mode)
+
+static int fd_attempt_open(char *fname, int flags, mode_t mode)
 {
-  int fd = conn->vfs_ops.open(fname,flags,mode);
+  int fd = dos_open(fname,flags,mode);
 
   /* Fix for files ending in '.' */
   if((fd == -1) && (errno == ENOENT) &&
      (strchr(fname,'.')==NULL))
     {
       pstrcat(fname,".");
-      fd = conn->vfs_ops.open(fname,flags,mode);
+      fd = dos_open(fname,flags,mode);
     }
 
 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
@@ -71,7 +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(fname,flags,mode)) == -1)
+          if ((fd = dos_open(fname,flags,mode)) == -1)
             p[max_len] = tmp;
         }
     }
@@ -83,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))
@@ -94,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;
@@ -111,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;
@@ -120,11 +123,11 @@ 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)
 {
   int fd = dos_open( fname, O_RDWR, mode);
@@ -145,17 +148,13 @@ 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(file_fd_struct *fd_ptr, int *err_ret)
 {
   extern struct current_user current_user;
-  file_fd_struct *fd_ptr = fsp->fd_ptr;
-  uint16 ret_ref;
+  uint16 ret_ref = fd_ptr->ref_count;
 
-  if (fd_ptr != NULL) {
-      ret_ref = fd_ptr->ref_count;
-  } else {
-      return 0;
-  }
+  *err_ret = 0;
 
   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,
@@ -168,12 +167,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(close(fd_ptr->fd) < 0)
+        *err_ret = errno;
+       }
+
+    if(fd_ptr->fd_readonly != -1) {
+      if(close(fd_ptr->fd_readonly) < 0) {
+        if(*err_ret == 0)
+          *err_ret = errno;
+      }
+       }
+
+    if(fd_ptr->fd_writeonly != -1) {
+      if( close(fd_ptr->fd_writeonly) < 0) {
+        if(*err_ret == 0)
+          *err_ret = errno;
+      }
+       }
+
     /*
      * Delete this fd_ptr.
      */
@@ -182,7 +195,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;
 }
 
 /****************************************************************************
@@ -192,14 +205,21 @@ This is really ugly code, as due to POSIX locking braindamage we must
 fork and then attempt to open the file, and return success or failure
 via an exit code.
 ****************************************************************************/
-static BOOL check_access_allowed_for_current_user(struct connection_struct
-                                                 *conn, char *fname, 
-                                                 int accmode )
+
+static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
 {
   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;
   }
 
@@ -209,11 +229,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);
@@ -245,7 +277,7 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
      */
     int fd;
     DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
-    if((fd = fd_attempt_open(conn, fname, accmode, 0)) < 0) {
+    if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
       /* Access denied. */
       _exit(EACCES);
     }
@@ -260,11 +292,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));
@@ -276,6 +309,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)
 {
@@ -287,7 +321,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);
@@ -304,7 +338,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));
@@ -335,7 +369,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
    * open fd table.
    */
   if(sbuf == 0) {
-    if(conn->vfs_ops.stat(dos_to_unix(fname,False), &statbuf) < 0) {
+    if(dos_stat(fname, &statbuf) < 0) {
       if(errno != ENOENT) {
         DEBUG(3,("Error doing stat on file %s (%s)\n",
                  fname,strerror(errno)));
@@ -376,7 +410,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
      */
 
     if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
-      if(!check_access_allowed_for_current_user(conn, fname, accmode )) {
+      if(!check_access_allowed_for_current_user( fname, accmode )) {
         /* Error - permission denied. */
         DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
               fname, flags, accmode));
@@ -433,7 +467,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     fd_ptr->real_open_flags = O_RDWR;
     /* Set the flags as needed without the read/write modes. */
     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
-    fd_ptr->fd = fd_attempt_open(conn, fname, open_flags|O_RDWR, mode);
+    fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
     /*
      * On some systems opening a file for R/W access on a read only
      * filesystems sets errno to EROFS.
@@ -444,7 +478,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     if((fd_ptr->fd == -1) && (errno == EACCES)) {
 #endif /* EROFS */
       if(accmode != O_RDWR) {
-        fd_ptr->fd = fd_attempt_open(conn, fname, open_flags|accmode, mode);
+        fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
         fd_ptr->real_open_flags = accmode;
       }
     }
@@ -458,10 +492,10 @@ 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(dname,&dum1,&dum2,&dum3) < 
-       (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
-      if(fd_attempt_close(fsp) == 0)
-        conn->vfs_ops.unlink(fname);
+    if (sys_disk_free(dname,False,&dum1,&dum2,&dum3) < (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
+      int err;
+      if(fd_attempt_close(fd_ptr, &err) == 0)
+        dos_unlink(fname);
       fsp->fd_ptr = 0;
       errno = ENOSPC;
       return;
@@ -470,10 +504,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(fd_ptr,&err);
     check_for_pipe(fname);
     return;
   }
@@ -482,12 +517,13 @@ 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) {
+      if(sys_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(fd_ptr,&err);
         return;
       }
       sbuf = &statbuf;
@@ -505,17 +541,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
@@ -526,6 +562,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
@@ -536,7 +573,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
      */
     if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
            DEBUG(3,("Writing postscript line\n"));
-           conn->vfs_ops.write(fsp->fd_ptr->fd,"%!\n",3);
+           write_file(fsp,"%!\n",-1,3);
     }
       
     DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -547,40 +584,12 @@ 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, int token, 
                                   BOOL *share_locked)
 {
@@ -606,19 +615,19 @@ static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, i
        }
 }
 
-
 enum {AFAIL,AREAD,AWRITE,AALL};
 
 /*******************************************************************
 reproduce the share mode access table
 ********************************************************************/
+
 static int access_table(int new_deny,int old_deny,int old_mode,
-                       int share_pid,char *fname)
+                       pid_t share_pid,char *fname)
 {
   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
 
   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
-    int pid = getpid();
+    pid_t pid = getpid();
     if (old_deny == new_deny && share_pid == pid) 
        return(AALL);    
 
@@ -660,10 +669,10 @@ static int access_table(int new_deny,int old_deny,int old_mode,
   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)
@@ -707,7 +716,7 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
     {
       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;
@@ -726,34 +735,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 = dos_file_exist(fname,&sbuf);
   BOOL share_locked = False;
   BOOL fcbopen = False;
-  int token;
+  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,".+,;=[].")) 
   {
@@ -861,6 +875,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 +888,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 +911,10 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
             }
             lock_share_entry(conn, dev, inode, &token);
             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 +933,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, token, dev, inode, &old_shares);
+          oplock_contention_count++;
         }
       } while(broke_oplock);
     }
@@ -921,6 +942,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 +1011,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;
       }
@@ -999,19 +1033,75 @@ 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,token,&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);
   }
 
   if (share_locked && lp_share_modes(SNUM(conn)))
     unlock_share_entry( conn, dev, inode, token);
 }
 
+/****************************************************************************
+ 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(dos_stat(fname, 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.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 +1111,55 @@ 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(dos_stat(fname, &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 {
+
+                       /*
+                        * Try and create the directory.
+                        */
+
+                       if(!CAN_WRITE(conn)) {
+                               DEBUG(2,("open_directory: failing create on read-only share\n"));
+                               errno = EACCES;
+                               return -1;
+                       }
 
-               *action = FILE_WAS_CREATED;
+                       if(dos_mkdir(fname, unix_mode(conn,aDIR)) < 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 +1169,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 +1188,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 +1212,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)
@@ -1107,14 +1225,14 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
   int num_share_modes;
   SMB_STRUCT_STAT sbuf;
   int token;
-  int pid = getpid();
+  pid_t pid = getpid();
   SMB_DEV_T dev;
   SMB_INO_T inode;
 
   if(!lp_share_modes(SNUM(conn)))
     return True;
 
-  if (conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf) == -1) return(True);
+  if (dos_stat(fname,&sbuf) == -1) return(True);
 
   dev = sbuf.st_dev;
   inode = sbuf.st_ino;
@@ -1144,9 +1262,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
@@ -1176,6 +1301,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, \
index 99fe7a69fab6a8254217420dc0f5041f33960f52..a64dd2d0efc6fd8fb16dfbcd7412cbcdde683ec2 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;
@@ -73,7 +86,7 @@ BOOL open_oplock_ipc(void)
   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
 
   /* Open a lookback UDP socket on a random port. */
-  oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
+  oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK),False);
   if (oplock_sock == -1)
   {
     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
@@ -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,&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,91 @@ 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)
+{
+  int token;
+  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, &token) == 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(token, 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(token, 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, token);
+  return ret;
 }
 
 /****************************************************************************
@@ -358,14 +460,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 +486,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 +503,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 +517,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 +529,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 +570,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 +595,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 +616,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 +626,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);
 
-    bzero((char *)&toaddr,sizeof(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 +635,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 +716,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 +734,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, &token) == 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(token, 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, token);
+
+  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 +875,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 +901,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. */
-  bzero(outbuf,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 +947,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 +1001,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 +1039,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 +1065,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 +1093,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 +1105,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 */
-  bzero((char *)&addr_out,sizeof(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 +1140,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 +1153,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 +1193,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 +1204,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 +1225,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 +1303,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 e15e08a1af106e3be11a2a32a517c547a4e698a3..9792c9ebc80dd845a3fe16573276ea45936c9996 100644 (file)
@@ -23,6 +23,7 @@
 
 extern int DEBUGLEVEL;
 extern int Protocol;
+extern struct in_addr ipzero;
 
 /* users from session setup */
 static pstring session_users="";
@@ -31,6 +32,261 @@ extern pstring scope;
 extern pstring global_myname;
 extern fstring global_myworkgroup;
 
+/* Data to do lanman1/2 password challenge. */
+static unsigned char saved_challenge[8];
+static BOOL challenge_sent=False;
+
+/*******************************************************************
+Get the next challenge value - no repeats.
+********************************************************************/
+void generate_next_challenge(char *challenge)
+{
+#if 0
+        /* 
+         * Leave this ifdef'd out while we test
+         * the new crypto random number generator.
+         * JRA.
+         */
+       unsigned char buf[16];
+       static int counter = 0;
+       struct timeval tval;
+       int v1,v2;
+
+       /* get a sort-of random number */
+       GetTimeOfDay(&tval);
+       v1 = (counter++) + getpid() + tval.tv_sec;
+       v2 = (counter++) * getpid() + tval.tv_usec;
+       SIVAL(challenge,0,v1);
+       SIVAL(challenge,4,v2);
+
+       /* mash it up with md4 */
+       mdfour(buf, (unsigned char *)challenge, 8);
+#else
+        unsigned char buf[8];
+
+        generate_random_buffer(buf,8,False);
+#endif 
+       memcpy(saved_challenge, buf, 8);
+       memcpy(challenge,buf,8);
+       challenge_sent = True;
+}
+
+/*******************************************************************
+set the last challenge sent, usually from a password server
+********************************************************************/
+BOOL set_challenge(unsigned char *challenge)
+{
+  memcpy(saved_challenge,challenge,8);
+  challenge_sent = True;
+  return(True);
+}
+
+/*******************************************************************
+get the last challenge sent
+********************************************************************/
+static BOOL last_challenge(unsigned char *challenge)
+{
+  if (!challenge_sent) return(False);
+  memcpy(challenge,saved_challenge,8);
+  return(True);
+}
+
+/* this holds info on user ids that are already validated for this VC */
+static user_struct *validated_users = NULL;
+static int num_validated_users = 0;
+
+/****************************************************************************
+check if a uid has been validated, and return an pointer to the user_struct
+if it has. NULL if not. vuid is biased by an offset. This allows us to
+tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+user_struct *get_valid_user_struct(uint16 vuid)
+{
+  if (vuid == UID_FIELD_INVALID)
+    return NULL;
+  vuid -= VUID_OFFSET;
+  if ((vuid >= (uint16)num_validated_users) || 
+     (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1))
+    return NULL;
+  return &validated_users[vuid];
+}
+
+/****************************************************************************
+invalidate a uid
+****************************************************************************/
+void invalidate_vuid(uint16 vuid)
+{
+  user_struct *vuser = get_valid_user_struct(vuid);
+
+  if (vuser == NULL) return;
+
+  vuser->uid = (uid_t)-1;
+  vuser->gid = (gid_t)-1;
+
+  vuser->n_sids = 0;
+
+  /* same number of igroups as groups */
+  vuser->n_groups = 0;
+
+  if (vuser->groups)
+    free((char *)vuser->groups);
+
+  if (vuser->sids)
+    free((char *)vuser->sids);
+
+  vuser->sids    = NULL;
+  vuser->groups  = NULL;
+}
+
+
+/****************************************************************************
+return a validated username
+****************************************************************************/
+char *validated_username(uint16 vuid)
+{
+  user_struct *vuser = get_valid_user_struct(vuid);
+  if (vuser == NULL)
+    return 0;
+  return(vuser->name);
+}
+
+
+/****************************************************************************
+Setup the groups a user belongs to.
+****************************************************************************/
+int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
+{
+       int i,ngroups;
+       gid_t grp = 0;
+       gid_t *groups = NULL;
+
+       if (-1 == initgroups(user,gid))
+       {
+               DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
+               if (getuid() == 0)
+               {
+                       if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
+                       {
+                               DEBUG(0,("This is probably a problem with the account %s\n", user));
+                       }
+               }
+               return -1;
+       }
+
+       ngroups = sys_getgroups(0,&grp);
+       if (ngroups <= 0)
+       {
+               ngroups = 32;
+       }
+
+#ifdef NGROUPS_MAX
+       if((groups = (gid_t *)malloc(sizeof(gid_t)*NGROUPS_MAX)) == NULL)
+#else /* NGROUPS_MAX */
+       if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
+#endif /* NGROUPS_MAX */
+       {
+               DEBUG(0,("setup_groups malloc fail !\n"));
+               return -1;
+       }
+
+       ngroups = sys_getgroups(ngroups,groups);
+
+       (*p_ngroups) = ngroups;
+       (*p_groups) = groups;
+
+       DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
+       for (i = 0; i < ngroups; i++ )
+       {
+               DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
+       }
+       DEBUG( 3, ( "\n" ) );
+
+       return 0;
+}
+
+
+/****************************************************************************
+register a uid/name pair as being valid and that a valid password
+has been given. vuid is biased by an offset. This allows us to
+tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest)
+{
+  user_struct *vuser;
+  struct passwd *pwfile; /* for getting real name from passwd file */
+
+  /* Ensure no vuid gets registered in share level security. */
+  if(lp_security() == SEC_SHARE)
+    return UID_FIELD_INVALID;
+
+#if 0
+  /*
+   * After observing MS-Exchange services writing to a Samba share
+   * I belive this code is incorrect. Each service does its own
+   * sessionsetup_and_X for the same user, and as each service shuts
+   * down, it does a user_logoff_and_X. As we are consolidating multiple
+   * sessionsetup_and_X's onto the same vuid here, when the first service
+   * shuts down, it invalidates all the open files for the other services.
+   * Hence I am removing this code and forcing each sessionsetup_and_X
+   * to get a new vuid.
+   * Jeremy Allison. (jallison@whistle.com).
+   */
+
+  int i;
+  for(i = 0; i < num_validated_users; i++) {
+    vuser = &validated_users[i];
+    if ( vuser->uid == uid )
+      return (uint16)(i + VUID_OFFSET); /* User already validated */
+  }
+#endif
+
+  validated_users = (user_struct *)Realloc(validated_users,
+                          sizeof(user_struct)*
+                          (num_validated_users+1));
+  
+  if (!validated_users)
+    {
+      DEBUG(0,("Failed to realloc users struct!\n"));
+      num_validated_users = 0;
+      return UID_FIELD_INVALID;
+    }
+
+  vuser = &validated_users[num_validated_users];
+  num_validated_users++;
+
+  vuser->uid = uid;
+  vuser->gid = gid;
+  vuser->guest = guest;
+  fstrcpy(vuser->name,unix_name);
+  fstrcpy(vuser->requested_name,requested_name);
+
+  vuser->n_sids = 0;
+  vuser->sids   = NULL;
+
+  vuser->n_groups = 0;
+  vuser->groups  = NULL;
+
+  /* Find all the groups this uid is in and store them. 
+     Used by become_user() */
+  setup_groups(unix_name,uid,gid,
+              &vuser->n_groups,
+              &vuser->groups);
+
+  DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
+
+  DEBUG(3, ("Clearing default real name\n"));
+  fstrcpy(vuser->real_name, "<Full Name>\0");
+  if (lp_unix_realname()) {
+    if ((pwfile=sys_getpwnam(vuser->name))!= NULL)
+      {
+      DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos));
+      fstrcpy(vuser->real_name, pwfile->pw_gecos);
+      }
+  }
+
+  return (uint16)((num_validated_users - 1) + VUID_OFFSET);
+}
+
 
 /****************************************************************************
 add a name to the session users list
@@ -71,12 +327,17 @@ static BOOL update_smbpassword_file(char *user, char *password)
                DEBUG(0,("getsmbpwnam returned NULL\n"));
                return False;
        }
+
+       /*
+        * Remove the account disabled flag - we are updating the
+        * users password from a login.
+        */
+       smbpw->acct_ctrl &= ~ACB_DISABLED;
+
        /* Here, the flag is one, because we want to ignore the
            XXXXXXX'd out password */
        ret = change_oem_password( smbpw, password, True);
-       if (!ret)
-       {
+       if (ret == False) {
                DEBUG(3,("change_oem_password returned False\n"));
        }
 
@@ -87,17 +348,202 @@ static BOOL update_smbpassword_file(char *user, char *password)
 
 
 
+/****************************************************************************
+core of smb password checking routine.
+****************************************************************************/
+BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8)
+{
+  /* Finish the encryption of part_passwd. */
+  unsigned char p21[21];
+  unsigned char p24[24];
+
+  if (part_passwd == NULL)
+    DEBUG(10,("No password set - allowing access\n"));
+  /* No password set - always true ! */
+  if (part_passwd == NULL)
+    return 1;
+
+  memset(p21,'\0',21);
+  memcpy(p21,part_passwd,16);
+  E_P24(p21, c8, p24);
+#if DEBUG_PASSWORD
+  {
+    int i;
+    DEBUG(100,("Part password (P16) was |"));
+    for(i = 0; i < 16; i++)
+      DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
+    DEBUG(100,("|\n"));
+    DEBUG(100,("Password from client was |"));
+    for(i = 0; i < 24; i++)
+      DEBUG(100,("%X ", (unsigned char)password[i]));
+    DEBUG(100,("|\n"));
+    DEBUG(100,("Given challenge was |"));
+    for(i = 0; i < 8; i++)
+      DEBUG(100,("%X ", (unsigned char)c8[i]));
+    DEBUG(100,("|\n"));
+    DEBUG(100,("Value from encryption was |"));
+    for(i = 0; i < 24; i++)
+      DEBUG(100,("%X ", (unsigned char)p24[i]));
+    DEBUG(100,("|\n"));
+  }
+#endif
+  return (memcmp(p24, password, 24) == 0);
+}
+
+/****************************************************************************
+ Do a specific test for an smb password being correct, given a smb_password and
+ the lanman and NT responses.
+****************************************************************************/
+BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
+                     uchar lm_pass[24], uchar nt_pass[24])
+{
+       uchar challenge[8];
+
+       if (!lm_pass || !smb_pass) return(False);
+
+       DEBUG(4,("Checking SMB password for user %s\n", 
+                smb_pass->smb_name));
+
+       if(smb_pass->acct_ctrl & ACB_DISABLED) {
+               DEBUG(1,("account for user %s was disabled.\n", 
+                        smb_pass->smb_name));
+               return(False);
+       }
+
+       if (chal == NULL)
+       {
+               DEBUG(5,("use last SMBnegprot challenge\n"));
+               if (!last_challenge(challenge))
+               {
+                       DEBUG(1,("no challenge done - password failed\n"));
+                       return False;
+               }
+       }
+       else
+       {
+               DEBUG(5,("challenge received\n"));
+               memcpy(challenge, chal, 8);
+       }
+
+       if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) {
+               /* We have the NT MD4 hash challenge available - see if we can
+                  use it (ie. does it exist in the smbpasswd file).
+               */
+               DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
+               if (smb_password_check((char *)nt_pass, 
+                                      (uchar *)smb_pass->smb_nt_passwd, 
+                                      challenge)) {
+                       DEBUG(4,("NT MD4 password check succeeded\n"));
+                       return(True);
+               }
+               DEBUG(4,("NT MD4 password check failed\n"));
+       }
+
+       /* Try against the lanman password. smb_pass->smb_passwd == NULL means
+          no password, allow access. */
+
+       DEBUG(4,("Checking LM MD4 password\n"));
+
+       if((smb_pass->smb_passwd == NULL) && 
+          (smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
+               DEBUG(4,("no password required for user %s\n",
+                        smb_pass->smb_name));
+               return True;
+       }
+
+       if((smb_pass->smb_passwd != NULL) && 
+          smb_password_check((char *)lm_pass, 
+                             (uchar *)smb_pass->smb_passwd, challenge)) {
+               DEBUG(4,("LM MD4 password check succeeded\n"));
+               return(True);
+       }
+
+       DEBUG(4,("LM MD4 password check failed\n"));
+
+       return False;
+}
+
+
+/****************************************************************************
+check if a username/password is OK assuming the password is a 24 byte
+SMB hash
+return True if the password is correct, False otherwise
+****************************************************************************/
+
+BOOL pass_check_smb(char *user, char *domain,
+               uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
+               struct passwd *pwd)
+{
+       struct passwd *pass;
+       struct smb_passwd *smb_pass;
+
+       if (!lm_pwd || !nt_pwd)
+       {
+               return(False);
+       }
+
+       if (pwd != NULL && user == NULL)
+       {
+               pass = (struct passwd *) pwd;
+               user = pass->pw_name;
+       }
+       else
+       {
+               pass = Get_Pwnam(user,True);
+       }
+
+       if (pass == NULL)
+       {
+               DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user));
+               return(False);
+       }
+
+       smb_pass = getsmbpwnam(user);
+
+       if (smb_pass == NULL)
+       {
+               DEBUG(1,("Couldn't find user '%s' in smb_passwd file.\n", user));
+               return(False);
+       }
+
+       /* Quit if the account was disabled. */
+       if(smb_pass->acct_ctrl & ACB_DISABLED) {
+               DEBUG(1,("Account for user '%s' was disabled.\n", user));
+               return(False);
+        }
+
+       /* Ensure the uid's match */
+       if (smb_pass->smb_userid != pass->pw_uid)
+       {
+               DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user));
+               return(False);
+       }
+
+       if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords())
+       {
+               DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name));
+               return(True);
+       }
+
+       if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd))
+       {
+               return(True);
+       }
+       
+       DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user));
+       return False;
+}
+
 /****************************************************************************
 check if a username/password pair is OK either via the system password
 database or the encrypted SMB password database
 return True if the password is correct, False otherwise
 ****************************************************************************/
-BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
-               uchar user_sess_key[16])
+BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
 {
-       if (pwlen >= 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords()))
+       if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords()))
        {
-               /* if 24 bytes or longer assume it is an encrypted password */
+               /* if 24 bytes long assume it is an encrypted password */
                uchar challenge[8];
 
                if (!last_challenge(challenge))
@@ -106,10 +552,8 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
                        return False;
                }
 
-               return pass_check_smb(getsmbpwnam(user), global_myworkgroup,
-                                     challenge, (uchar *)password,
-                                       pwlen, (uchar *)password, pwlen,
-                                       pwd, user_sess_key);
+               return pass_check_smb(user, global_myworkgroup,
+                                     challenge, (uchar *)password, (uchar *)password, pwd);
        } 
 
        return pass_check(user, password, pwlen, pwd, 
@@ -117,71 +561,84 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
                          update_smbpassword_file : NULL);
 }
 
+/****************************************************************************
+check if a username is valid
+****************************************************************************/
+BOOL user_ok(char *user,int snum)
+{
+       pstring valid, invalid;
+       BOOL ret;
+
+       StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)-1);
+       StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)-1);
+
+       pstring_sub(valid,"%S",lp_servicename(snum));
+       pstring_sub(invalid,"%S",lp_servicename(snum));
+       
+       ret = !user_in_list(user,invalid);
+       
+       if (ret && valid && *valid) {
+               ret = user_in_list(user,valid);
+       }
+
+       if (ret && lp_onlyuser(snum)) {
+               char *user_list = lp_username(snum);
+               pstring_sub(user_list,"%S",lp_servicename(snum));
+               ret = user_in_list(user,user_list);
+       }
+
+       return(ret);
+}
+
 
 
 
 /****************************************************************************
 validate a group username entry. Return the username or NULL
 ****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum,
-                               uchar user_sess_key[16])
+static char *validate_group(char *group,char *password,int pwlen,int snum)
 {
-#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,password,pwlen,NULL, user_sess_key)) {
-         endnetgrent();
-         return(user);
+#ifdef HAVE_NETGROUP
+       {
+               char *host, *user, *domain;
+               setnetgrent(group);
+               while (getnetgrent(&host, &user, &domain)) {
+                       if (user) {
+                               if (user_ok(user, snum) && 
+                                   password_ok(user,password,pwlen,NULL)) {
+                                       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,password,pwlen,NULL, user_sess_key))
-             return(&name[0]);
-           member++;
-         }
-#ifdef GROUP_CHECK_PWENT
+#ifdef HAVE_GETGRENT
        {
-         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, password, pwlen, pwd, user_sess_key)) {
-               fstrcpy(tm, pwd->pw_name);
-               endpwent ();
-               return tm;
-             }
-           }
-         }
-         endpwent ();
+               struct group *gptr;
+               char **member;
+               setgrent();
+               while ((gptr = (struct group *)getgrent())) {
+                       if (!strequal(gptr->gr_name,group))
+                               continue;
+                       member = gptr->gr_mem;
+                       while (member && *member) {
+                               static fstring name;
+                               fstrcpy(name,*member);
+                               if (user_ok(name,snum) &&
+                                   password_ok(name,password,pwlen,NULL)) {
+                                       endgrent();
+                                       return(&name[0]);
+                               }
+                               member++;
+                       }
+               }
+               endgrent();
        }
-#endif /* GROUP_CHECK_PWENT */
-      }
-  }      
 #endif
-  return(NULL);
+       return(NULL);
 }
 
 
@@ -221,14 +678,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
 
       /* check the given username and password */
       if (!ok && (*user) && user_ok(user,snum)) {
-       ok = password_ok(user,password, pwlen, NULL, vuser->user_sess_key);
+       ok = password_ok(user,password, pwlen, NULL);
        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, password, pwlen, NULL, vuser->user_sess_key)) {
+           password_ok(vuser->name, password, pwlen, NULL)) {
          fstrcpy(user, vuser->name);
          vuser->guest = False;
          DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
@@ -242,7 +699,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
     {
       char *auser;
       char *user_list = strdup(session_users);
-      if (!user_list) return False;
+      if (!user_list) return(False);
 
       for (auser=strtok(user_list,LIST_SEP); 
            !ok && auser; 
@@ -252,7 +709,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
         fstrcpy(user2,auser);
         if (!user_ok(user2,snum)) continue;
                  
-        if (password_ok(user2,password, pwlen, NULL, vuser->user_sess_key)) {
+        if (password_ok(user2,password, pwlen, NULL)) {
           ok = True;
           fstrcpy(user,user2);
           DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
@@ -283,7 +740,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
        pstring user_list;
        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;
@@ -291,7 +748,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
          {
            if (*auser == '@')
              {
-               auser = validate_group(auser+1,password,pwlen,snum, vuser->user_sess_key);
+               auser = validate_group(auser+1,password,pwlen,snum);
                if (auser)
                  {
                    ok = True;
@@ -304,7 +761,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
                fstring user2;
                fstrcpy(user2,auser);
                if (user_ok(user2,snum) && 
-                   password_ok(user2,password,pwlen,NULL, vuser->user_sess_key))
+                   password_ok(user2,password,pwlen,NULL))
                  {
                    ok = True;
                    fstrcpy(user,user2);
@@ -454,10 +911,10 @@ BOOL check_hosts_equiv(char *user)
 {
   char *fname = NULL;
   pstring rhostsfile;
-  const struct passwd *pass = Get_Pwnam(user,True);
+  struct passwd *pass = Get_Pwnam(user,True);
 
   if (!pass) 
-    return False;
+    return(False);
 
   fname = lp_hosts_equiv();
 
@@ -470,7 +927,7 @@ BOOL check_hosts_equiv(char *user)
   
   if (lp_use_rhosts())
     {
-      char *home = get_unixhome_dir(user);
+      char *home = get_user_home_dir(user);
       if (home) {
              extern int Client;
              slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
@@ -479,13 +936,14 @@ BOOL check_hosts_equiv(char *user)
       }
     }
 
-  return False;
+  return(False);
 }
 
 
 /****************************************************************************
-return the client state structure
+ Return the client state structure.
 ****************************************************************************/
+
 struct cli_state *server_client(void)
 {
        static struct cli_state pw_cli;
@@ -493,20 +951,77 @@ struct cli_state *server_client(void)
 }
 
 /****************************************************************************
-support for server level security 
+ Support for server level security.
 ****************************************************************************/
+
 struct cli_state *server_cryptkey(void)
 {
-       if (cli_connect_serverlist(server_client(), lp_passwordserver()))
-       {
-               return server_client();
+       struct cli_state *cli;
+       fstring desthost;
+       struct in_addr dest_ip;
+       char *p;
+    BOOL connected_ok = False;
+
+       cli = server_client();
+
+       if (!cli_initialise(cli))
+               return NULL;
+
+        p = lp_passwordserver();
+        while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
+               standard_sub_basic(desthost);
+               strupper(desthost);
+
+               if(!resolve_name( desthost, &dest_ip, 0x20)) {
+                       DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
+                       continue;
+               }
+
+               if (ismyip(dest_ip)) {
+                       DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
+                       continue;
+               }
+
+               if (cli_connect(cli, desthost, &dest_ip)) {
+                       DEBUG(3,("connected to password server %s\n",desthost));
+                       connected_ok = True;
+                       break;
+               }
+       }
+
+       if (!connected_ok) {
+               DEBUG(0,("password server not available\n"));
+               cli_shutdown(cli);
+               return NULL;
        }
-       return NULL;
+
+       if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip))
+               return NULL;
+
+       DEBUG(3,("got session\n"));
+
+       if (!cli_negprot(cli)) {
+               DEBUG(1,("%s rejected the negprot\n",desthost));
+               cli_shutdown(cli);
+               return NULL;
+       }
+
+       if (cli->protocol < PROTOCOL_LANMAN2 ||
+           !(cli->sec_mode & 1)) {
+               DEBUG(1,("%s isn't in user level security mode\n",desthost));
+               cli_shutdown(cli);
+               return NULL;
+       }
+
+       DEBUG(3,("password server OK\n"));
+
+       return cli;
 }
 
 /****************************************************************************
-validate a password with the password server
+ Validate a password with the password server.
 ****************************************************************************/
+
 BOOL server_validate(char *user, char *domain, 
                     char *pass, int passlen,
                     char *ntpass, int ntpasslen)
@@ -520,7 +1035,7 @@ BOOL server_validate(char *user, char *domain,
 
   if (!cli->initialised) {
     DEBUG(1,("password server %s is not connected\n", cli->desthost));
-    return False;
+    return(False);
   }  
 
   if(badpass[0] == 0)
@@ -541,8 +1056,7 @@ BOOL server_validate(char *user, char *domain,
    */
 
   if(!tested_password_server) {
-    if (cli_session_setup(cli, global_myname,
-                              user, (char *)badpass, sizeof(badpass), 
+    if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), 
                               (char *)badpass, sizeof(badpass), domain)) {
 
       /*
@@ -587,8 +1101,7 @@ use this machine as the password server.\n"));
    * not guest enabled, we can try with the real password.
    */
 
-  if (!cli_session_setup(cli, global_myname,
-                              user, pass, passlen, ntpass, ntpasslen, domain)) {
+  if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
     DEBUG(1,("password server %s rejected the password\n", cli->desthost));
     return False;
   }
@@ -597,12 +1110,365 @@ use this machine as the password server.\n"));
   if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {
     DEBUG(1,("password server %s gave us guest only\n", cli->desthost));
     cli_ulogoff(cli);
-    return False;
+    return(False);
   }
 
-
   cli_ulogoff(cli);
 
   return(True);
 }
 
+/***********************************************************************
+ Connect to a remote machine for domain security authentication
+ given a name or IP address.
+************************************************************************/
+
+static BOOL connect_to_domain_password_server(struct cli_state *pcli, char *remote_machine,
+                                              unsigned char *trust_passwd)
+{
+  struct in_addr dest_ip;
+
+  if(cli_initialise(pcli) == False) {
+    DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n"));
+    return False;
+  }
+
+  standard_sub_basic(remote_machine);
+  strupper(remote_machine);
+
+  if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
+    DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine));
+    cli_shutdown(pcli);
+    return False;
+  }
+  
+  if (ismyip(dest_ip)) {
+    DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
+         remote_machine));
+    cli_shutdown(pcli);
+    return False;
+  }
+  
+  if (!cli_connect(pcli, remote_machine, &dest_ip)) {
+    DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+    cli_shutdown(pcli);
+    return False;
+  }
+  
+  if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) {
+    DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \
+session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+    return False;
+  }
+  
+  pcli->protocol = PROTOCOL_NT1;
+
+  if (!cli_negprot(pcli)) {
+    DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  if (pcli->protocol != PROTOCOL_NT1) {
+    DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n",
+                   remote_machine));
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  /*
+   * Do an anonymous session setup.
+   */
+
+  if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) {
+    DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  if (!(pcli->sec_mode & 1)) {
+    DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n",
+               remote_machine));
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) {
+    DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  /*
+   * We now have an anonymous connection to IPC$ on the domain password server.
+   */
+
+  /*
+   * Even if the connect succeeds we need to setup the netlogon
+   * pipe here. We do this as we may just have changed the domain
+   * account password on the PDC and yet we may be talking to
+   * a BDC that doesn't have this replicated yet. In this case
+   * a successful connect to a DC needs to take the netlogon connect
+   * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
+   */
+
+  if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) {
+    DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
+    cli_nt_session_close(pcli);
+    cli_ulogoff(pcli);
+    cli_shutdown(pcli);
+    return False;
+  }
+
+  if (cli_nt_setup_creds(pcli, trust_passwd) == False) {
+    DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
+%s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
+    cli_nt_session_close(pcli);
+    cli_ulogoff(pcli);
+    cli_shutdown(pcli);
+    return(False);
+  }
+
+  return True;
+}
+
+/***********************************************************************
+ Utility function to attempt a connection to an IP address of a DC.
+************************************************************************/
+
+static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, unsigned char *trust_passwd)
+{
+  fstring dc_name;
+
+  /*
+   * Ignore addresses we have already tried.
+   */
+
+  if(ip_equal(ipzero, *ip))
+    return False;
+
+  if(!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name))
+    return False;
+
+  return connect_to_domain_password_server(pcli, dc_name, trust_passwd);
+}
+
+/***********************************************************************
+ Do the same as security=server, but using NT Domain calls and a session
+ key from the machine password.
+************************************************************************/
+
+BOOL domain_client_validate( char *user, char *domain, 
+                             char *smb_apasswd, int smb_apasslen, 
+                             char *smb_ntpasswd, int smb_ntpasslen,
+                             BOOL *user_exists)
+{
+  unsigned char local_challenge[8];
+  unsigned char local_lm_response[24];
+  unsigned char local_nt_reponse[24];
+  unsigned char trust_passwd[16];
+  fstring remote_machine;
+  char *p;
+  NET_ID_INFO_CTR ctr;
+  NET_USER_INFO_3 info3;
+  struct cli_state cli;
+  uint32 smb_uid_low;
+  BOOL connected_ok = False;
+
+  if(user_exists != NULL)
+    *user_exists = True; /* Only set false on a very specific error. */
+  /* 
+   * Check that the requested domain is not our own machine name.
+   * If it is, we should never check the PDC here, we use our own local
+   * password file.
+   */
+
+  if(strequal( domain, global_myname)) {
+    DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n"));
+    return False;
+  }
+
+  /*
+   * Next, check that the passwords given were encrypted.
+   */
+
+  if(((smb_apasslen != 24) && (smb_apasslen != 0)) || 
+     ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) {
+
+    /*
+     * Not encrypted - do so.
+     */
+
+    DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n"));
+    generate_random_buffer( local_challenge, 8, False);
+    SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response);
+    SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse);
+    smb_apasslen = 24;
+    smb_ntpasslen = 24;
+    smb_apasswd = (char *)local_lm_response;
+    smb_ntpasswd = (char *)local_nt_reponse;
+  } else {
+
+    /*
+     * Encrypted - get the challenge we sent for these
+     * responses.
+     */
+
+    if (!last_challenge(local_challenge)) {
+      DEBUG(0,("domain_client_validate: no challenge done - password failed\n"));
+      return False;
+    }
+  }
+
+  /*
+   * Get the machine account password.
+   */
+  if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname))
+  {
+    return False;
+  }
+
+  /*
+   * At this point, smb_apasswd points to the lanman response to
+   * the challenge in local_challenge, and smb_ntpasswd points to
+   * the NT response to the challenge in local_challenge. Ship
+   * these over the secure channel to a domain controller and
+   * see if they were valid.
+   */
+
+  ZERO_STRUCT(cli);
+
+  /*
+   * Treat each name in the 'password server =' line as a potential
+   * PDC/BDC. Contact each in turn and try and authenticate.
+   */
+
+  p = lp_passwordserver();
+  while(!connected_ok && p &&
+        next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
+    if(strequal(remote_machine, "*")) {
+
+      /*
+       * We have been asked to dynamcially determine the IP addresses of
+       * the PDC and BDC's for this DOMAIN, and query them in turn.
+       */
+
+      struct in_addr *ip_list = NULL;
+      int count = 0;
+      int i;
+
+      if(!get_dc_list(lp_workgroup(), &ip_list, &count))
+        continue;
+
+      /*
+       * Firstly try and contact a PDC/BDC who has the same
+       * network address as any of our interfaces.
+       */
+
+      for(i = 0; i < count; i++) {
+        if(!is_local_net(ip_list[i]))
+          continue;
+
+        if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
+          break;
+
+        ip_list[i] = ipzero; /* Tried and failed. */
+      }
+
+      /*
+       * Secondly try and contact a random PDC/BDC.
+       */
+
+      if(!connected_ok) {
+        i = (sys_random() % count);
+
+        if(!(connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
+          ip_list[i] = ipzero; /* Tried and failed. */
+      }
+
+      /*
+       * Finally go through the IP list in turn, ignoring any addresses
+       * we have already tried.
+       */
+
+      if(!connected_ok) {
+
+        /*
+         * Try and connect to any of the other IP addresses in the PDC/BDC list.
+         * Note that from a WINS server the #1 IP address is the PDC.
+         */
+
+        for(i = 0; i < count; i++) {
+          if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd)))
+            break;
+        }
+      }
+
+      if(ip_list != NULL)
+        free((char *)ip_list);
+
+    } else {
+      connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
+    }
+  }
+
+  if (!connected_ok) {
+    DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  /* We really don't care what LUID we give the user. */
+  generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
+
+  if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge,
+                          ((smb_apasslen != 0) ? smb_apasswd : NULL),
+                          ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL),
+                          &ctr, &info3) == False) {
+    uint32 nt_rpc_err;
+
+    cli_error(&cli, NULL, NULL, &nt_rpc_err);
+    DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+    cli_nt_session_close(&cli);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+
+    if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL))
+      *user_exists = False;
+
+    return False;
+  }
+
+  /*
+   * Here, if we really want it, we have lots of info about the user in info3.
+   */
+
+#if 0
+  /* 
+   * We don't actually need to do this - plus it fails currently with
+   * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
+   * send here. JRA.
+   */
+
+  if(cli_nt_logoff(&cli, &ctr) == False) {
+    DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));        
+    cli_nt_session_close(&cli);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  }
+#endif /* 0 */
+
+  cli_nt_session_close(&cli);
+  cli_ulogoff(&cli);
+  cli_shutdown(&cli);
+  return True;
+}
index e20d0498348da847feb9629d39236a0a693a2e7d..15f52c0af678c9da166125c285ee61670dbca37c 100644 (file)
@@ -74,10 +74,16 @@ int reply_open_pipe_and_X(connection_struct *conn,
        /* Strip \PIPE\ off the name. */
        pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
 
+       /*
+        * Hack for NT printers... JRA.
+        */
+    if(should_fail_next_srvsvc_open(fname))
+      return(ERROR(ERRSRV,ERRaccess));
+
        /* 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 */
+       smb_ofun |= FILE_CREATE_IF_NOT_EXIST;
 
        p = open_rpc_pipe_p(fname, conn, vuid);
        if (!p) return(ERROR(ERRSRV,ERRnofids));
@@ -105,45 +111,37 @@ int reply_open_pipe_and_X(connection_struct *conn,
 }
 
 /****************************************************************************
-  reply to a write 
-
-  This code is basically stolen from reply_write with some
-  wrinkles to handle pipes.
+  reply to a write on a pipe
 ****************************************************************************/
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
+int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
 {
        pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
        size_t numtowrite = SVAL(inbuf,smb_vwv1);
-       int nwritten = -1;
+       int nwritten;
+       int outsize;
        char *data;
-       size_t outsize;
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return(ERROR(ERRDOS,ERRbadfid));
 
        data = smb_buf(inbuf) + 3;
 
        if (numtowrite == 0)
-       {
                nwritten = 0;
-       }
        else
-       {
-               nwritten = write_pipe(p, data, numtowrite);
-       }
+               nwritten = write_to_pipe(p, data, numtowrite);
 
        if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
-       {
                return (UNIXERROR(ERRDOS,ERRnoaccess));
-       }
   
        outsize = set_message(outbuf,1,0,True);
 
        SSVAL(outbuf,smb_vwv0,nwritten);
-
+  
        DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
                 p->pnum, nwritten));
 
-       return outsize;
+       return(outsize);
 }
 
 /****************************************************************************
@@ -160,23 +158,18 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
        int smb_doff = SVAL(inbuf, smb_vwv11);
        char *data;
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return(ERROR(ERRDOS,ERRbadfid));
 
        data = smb_base(inbuf) + smb_doff;
 
        if (numtowrite == 0)
-       {
                nwritten = 0;
-       }
        else
-       {
-               nwritten = write_pipe(p, data, numtowrite);
-       }
+               nwritten = write_to_pipe(p, data, numtowrite);
 
        if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
-       {
                return (UNIXERROR(ERRDOS,ERRnoaccess));
-       }
   
        set_message(outbuf,6,0,True);
 
@@ -197,18 +190,24 @@ 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)
 {
        pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
-       uint32 smb_offs = IVAL(inbuf,smb_vwv3);
        int smb_maxcnt = SVAL(inbuf,smb_vwv5);
        int smb_mincnt = SVAL(inbuf,smb_vwv6);
        int nread = -1;
        char *data;
+       /* we don't use the offset given to use for pipe reads. This
+           is deliberate, instead we always return the next lump of
+           data on the pipe */
+#if 0
+       uint32 smb_offs = IVAL(inbuf,smb_vwv3);
+#endif
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return(ERROR(ERRDOS,ERRbadfid));
 
        set_message(outbuf,12,0,True);
        data = smb_buf(outbuf);
 
-       nread = read_pipe(p, data, smb_offs, smb_maxcnt);
+       nread = read_from_pipe(p, data, smb_maxcnt);
 
        if (nread < 0)
                return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -231,12 +230,13 @@ 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);
 
-       if (!p) return(ERROR(ERRDOS,ERRbadfid));
+       if (!p)
+               return(ERROR(ERRDOS,ERRbadfid));
 
        DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
 
-       if (!close_rpc_pipe_hnd(p, conn)) return(ERROR(ERRDOS,ERRbadfid));
+       if (!close_rpc_pipe_hnd(p, conn))
+               return(ERROR(ERRDOS,ERRbadfid));
 
        return(outsize);
 }
-
index f51e54a568c3dda94a6da366c2f025eb649b08ed..de85a4a55379b84d9f2daafa5ba3d44a5f1a2dfe 100644 (file)
@@ -37,12 +37,12 @@ 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
 ****************************************************************************/
-ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num)
+ssize_t read_predict(int fd,SMB_OFF_T offset,char *buf,char **ptr,size_t num)
 {
   ssize_t ret = 0;
   ssize_t possible = rp_length - (offset - rp_offset);
@@ -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)
@@ -70,7 +70,7 @@ ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char *
 
     /* Find the end of the file - ensure we don't
        read predict beyond it. */
-    if(fsp->conn->vfs_ops.fstat(fd,&rp_stat) < 0)
+    if(sys_fstat(fd,&rp_stat) < 0)
     {
       DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno)));
       predict_skip = True;
@@ -95,7 +95,7 @@ ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char *
 /****************************************************************************
 pre-read some data
 ****************************************************************************/
-void do_read_prediction(connection_struct *conn)
+void do_read_prediction(void)
 {
   static size_t readsize = 0;
 
@@ -134,13 +134,13 @@ void do_read_prediction(connection_struct *conn)
        }
     }
 
-  if (conn->vfs_ops.lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
+  if (sys_lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
     rp_fd = -1;
     rp_predict_fd = -1;
     return;
   }
 
-  rp_length = conn->vfs_ops.read(rp_fd,rp_buffer,rp_predict_length);
+  rp_length = read(rp_fd,rp_buffer,rp_predict_length);
   rp_time = time(NULL);
   if (rp_length < 0)
     rp_length = 0;
index 95222d3f51ef1b2b9f4c8407aafad959d46b11ab..7e94ffa173d39ad6d886ec89be6290f47a342786 100644 (file)
@@ -23,7 +23,7 @@
 
 extern int DEBUGLEVEL;
 
-time_t smb_last_time=(time_t)0;
+struct timeval smb_last_time;
 
 char *InBuffer = NULL;
 char *OutBuffer = 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 BOOL global_machine_password_needs_changing;
 extern fstring global_myworkgroup;
 extern pstring global_myname;
@@ -173,7 +173,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len,
   to.tv_sec = timeout / 1000;
   to.tv_usec = (timeout % 1000) * 1000;
 
-  selrtn = sys_select(MAX(maxfd,Client)+1,&fds,NULL, timeout>0?&to:NULL);
+  selrtn = sys_select(MAX(maxfd,Client)+1,&fds,timeout>0?&to:NULL);
 
   /* Check if error */
   if(selrtn == -1) {
@@ -231,6 +231,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 
@@ -283,8 +329,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},
@@ -319,9 +365,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 },
@@ -330,7 +376,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},
@@ -339,14 +385,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 },
    {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},
@@ -368,14 +414,14 @@ 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;
 
-  if (pid == -1)
+  if (pid == (pid_t)-1)
     pid = getpid();
 
   errno = 0;
@@ -399,21 +445,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;
@@ -508,7 +558,7 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
   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();
@@ -640,7 +690,7 @@ char *smb_fn_name(int type)
 
 void construct_reply_common(char *inbuf,char *outbuf)
 {
-  bzero(outbuf,smb_size);
+  memset(outbuf,'\0',smb_size);
 
   set_message(outbuf,0,0,True);
   CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
@@ -687,6 +737,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;
@@ -741,234 +799,271 @@ 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 caler 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_name(Client)));
-    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;
 
-  while (True)
+  if (keepalive && (t - last_keepalive_sent_time)>keepalive) 
   {
-    int deadtime = lp_deadtime()*60;
-    int counter;
-    int last_keepalive=0;
-    int service_load_counter = 0;
-    BOOL got_smb = False;
+    struct cli_state *cli = server_client();
+    if (!send_keepalive(Client)) {
+      DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+      return False;
+    }      
+    /* also send a keepalive to the password server if its still
+       connected */
+    if (cli && cli->initialised)
+      send_keepalive(cli->fd);
+    last_keepalive_sent_time = t;
+  }
 
-    if (deadtime <= 0)
-      deadtime = DEFAULT_SMBD_TIMEOUT;
+  /* check for connection timeouts */
+  allidle = conn_idle_all(t, deadtime);
 
-#if USE_READ_PREDICTION
-    if (lp_readprediction())
-      do_read_prediction();
-#endif
+  if (allidle && conn_num_open()>0) {
+    DEBUG(2,("Closing idle connection 2.\n"));
+    return False;
+  }
 
-    errno = 0;      
+  if(global_machine_password_needs_changing)
+  {
+    unsigned char trust_passwd_hash[16];
+    time_t lct;
+    pstring remote_machine_list;
+
+    /*
+     * We're in domain level security, and the code that
+     * read the machine password flagged that the machine
+     * password needs changing.
+     */
+
+    /*
+     * First, open the machine password file with an exclusive lock.
+     */
+
+    if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
+      DEBUG(0,("process: unable to open the machine account password file for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+      return True;
+    }
 
-    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(!get_trust_account_password( trust_passwd_hash, &lct)) {
+      DEBUG(0,("process: unable to read the machine account password for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+      trust_password_unlock();
+      return True;
+    }
 
-      if (counter > 365 * 3600) /* big number of seconds. */
-      {
-        counter = 0;
-        service_load_counter = 0;
-      }
+    /*
+     * Make sure someone else hasn't already done this.
+     */
 
-      if (smb_read_error == READ_EOF) 
-      {
-        DEBUG(3,("end of file from client\n"));
-        return;
-      }
+    if(t < lct + lp_machine_password_timeout()) {
+      trust_password_unlock();
+      global_machine_password_needs_changing = False;
+      return True;
+    }
 
-      if (smb_read_error == READ_ERROR) 
-      {
-        DEBUG(3,("receive_smb error (%s) exiting\n",
-                  strerror(errno)));
-        return;
-      }
+    pstrcpy(remote_machine_list, lp_passwordserver());
 
-      t = time(NULL);
+    change_trust_account_password( global_myworkgroup, remote_machine_list);
+    trust_password_unlock();
+    global_machine_password_needs_changing = False;
+  }
 
-      /* become root again if waiting */
-      unbecome_user();
+  /*
+   * Check to see if we have any blocking locks
+   * outstanding on the queue.
+   */
+  process_blocking_lock_queue(t);
 
-      /* check for smb.conf reload */
-      if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
-      {
-        service_load_counter = counter;
+  /*
+   * Check to see if we have any change notifies 
+   * outstanding on the queue.
+   */
+  process_pending_change_notify_queue(t);
 
-        /* reload services, if files have changed. */
-        reload_services(True);
-      }
+  /*
+   * Modify the select timeout depending upon
+   * what we have remaining in our queues.
+   */
 
-      /*
-       * If reload_after_sighup == True then we got a SIGHUP
-       * and are being asked to reload. Fix from <branko.cibej@hermes.si>
-       */
+  *select_timeout = setup_select_timeout();
 
-      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();
-      }
+  return True;
+}
 
-      /* automatic timeout if all connections are closed */      
-      if (conn_num_open()==0 && counter >= IDLE_CLOSED_TIMEOUT) 
-      {
-        DEBUG( 2, ( "Closing idle connection\n" ) );
-        return;
-      }
+/****************************************************************************
+  process commands from the client
+****************************************************************************/
 
-      if (keepalive && (counter-last_keepalive)>keepalive) 
-      {
-             struct cli_state *cli = server_client();
-             if (!send_keepalive(Client)) {
-                     DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
-                     return;
-             }     
-             /* also send a keepalive to the password server if its still
-                connected */
-             if (cli && cli->initialised)
-                     send_keepalive(cli->fd);
-             last_keepalive = counter;
-      }
+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;
 
-      /* check for connection timeouts */
-      allidle = conn_idle_all(t, deadtime);
+  InBuffer += SMB_ALIGNMENT;
+  OutBuffer += SMB_ALIGNMENT;
 
-      if (allidle && conn_num_open()>0) {
-             DEBUG(2,("Closing idle connection 2.\n"));
-             return;
-      }
+  max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
 
-      if(global_machine_password_needs_changing)
-      {
-        unsigned char trust_passwd_hash[16];
-        time_t lct;
-        pstring remote_machine_list;
-        int sec_chan = SEC_CHAN_WKSTA;
-
-        /*
-         * We're in domain level security, and the code that
-         * read the machine password flagged that the machine
-         * password needs changing.
-         */
+  /* re-initialise the timezone */
+  TimeInit();
 
-        /*
-         * First, open the machine password file with an exclusive lock.
-         */
+  while (True)
+  {
+    int deadtime = lp_deadtime()*60;
+    BOOL got_smb = False;
+    int select_timeout = setup_select_timeout();
 
-        if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
-          DEBUG(0,("process: unable to open the machine account password file for \
-machine %s in domain %s.\n", global_myname, global_myworkgroup ));
-          continue;
-        }
+    if (deadtime <= 0)
+      deadtime = DEFAULT_SMBD_TIMEOUT;
 
-        if(!get_trust_account_password( trust_passwd_hash, &lct)) {
-          DEBUG(0,("process: unable to read the machine account password for \
-machine %s in domain %s.\n", global_myname, global_myworkgroup ));
-          trust_password_unlock();
-          continue;
-        }
+#if USE_READ_PREDICTION
+    if (lp_readprediction())
+      do_read_prediction();
+#endif
 
-        /*
-         * Make sure someone else hasn't already done this.
-         */
+    errno = 0;      
 
-        if(t < lct + lp_machine_password_timeout()) {
-          trust_password_unlock();
-          global_machine_password_needs_changing = False;
-          continue;
-        }
+    while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
+    {
+      if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+        return;
+      num_smbs = 0; /* Reset smb counter. */
+    }
 
-        pstrcpy(remote_machine_list, lp_passwordserver());
-        if (lp_server_role() == ROLE_DOMAIN_BDC)
-          sec_chan = SEC_CHAN_BDC;
+    if(got_smb) {
+      /*
+       * 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;
+
+      process_smb(InBuffer, OutBuffer);
 
-        change_trust_account_password(global_myworkgroup, remote_machine_list,
-                                        sec_chan);
-        trust_password_unlock();
-        global_machine_password_needs_changing = False;
+      if(smb_echo_count != num_echos) {
+        if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+          return;
+        num_smbs = 0; /* Reset smb counter. */
       }
 
-      /*
-       * Check to see if we have any blocking locks
-       * outstanding on the queue.
-       */
-      process_blocking_lock_queue(t);
+      num_smbs++;
 
       /*
-       * Check to see if we have any change notifies 
-       * 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_pending_change_notify_queue(t);
-    }
 
-    if(got_smb)
-      process_smb(InBuffer, OutBuffer);
+      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. */
+        }
+      }
+    }
     else
       process_local_message(InBuffer, BUFFER_SIZE);
   }
index afabb1befdf3d6ccb70c4079ea4bbe22a9ace762..badc0562bc8dd052e511a70144ddbbdad43d8d54 100644 (file)
@@ -47,7 +47,6 @@ try to get the disk space from disk quotas (LINUX version)
 
 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
-  uid_t euser_id;
   int r;
   struct dqblk D;
   SMB_STRUCT_STAT S;
@@ -55,6 +54,9 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   struct mntent *mnt;
   SMB_DEV_T devno;
   int found;
+  uid_t euser_id;
+
+  euser_id = geteuid();
   
   /* find the block device file */
   
@@ -81,10 +83,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
       return(False);
     }
 
-  euser_id=geteuid();
-  seteuid(0);  
+  save_re_uid();
+  set_effective_uid(0);  
   r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D);
-      seteuid(euser_id);
+  restore_re_uid();
 
   /* Use softlimit to determine disk space, except when it has been exceeded */
   *bsize = 1024;
@@ -212,11 +214,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   
   *dsize = request.qf_entry.user_q.f_use ;
   
-  if ( *dfree )
-    *dfree -= *dsize ;
-  
-  if ( *dfree < 0 )
+  if ( *dfree < *dsize )
     *dfree = 0 ;
+  else
+    *dfree -= *dsize ;
   
   *bsize = 4096 ;  /* Cray blocksize */
   
@@ -244,7 +245,7 @@ Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
 
 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
-  uid_t user_id, euser_id;
+  uid_t euser_id;
   int ret;
   struct dqblk D;
 #if defined(SUNOS5)
@@ -261,6 +262,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   SMB_DEV_T devno ;
   static SMB_DEV_T devno_cached = 0 ;
   int found ;
+
+  euser_id = geteuid();
   
   if ( sys_stat(path,&sbuf) == -1 )
     return(False) ;
@@ -312,18 +315,14 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
       return(False) ;
   }
 
-  euser_id = geteuid();
-  user_id = getuid();
-
-  setuid(0);  /* Solaris seems to want to give info only to super-user */
-  seteuid(0);
+  save_re_uid();
+  set_effective_uid(0);
 
 #if defined(SUNOS5)
   DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
   if((file=sys_open(name, O_RDONLY,0))<0) {
-    setuid(user_id);  /* Restore the original UID status */
-    seteuid(euser_id);
-    return(False);
+         restore_re_uid();
+         return(False);
   }
   command.op = Q_GETQUOTA;
   command.uid = euser_id;
@@ -335,8 +334,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
 #endif
 
-  setuid(user_id); /* Restore the original uid status. */
-  seteuid(euser_id);
+  restore_re_uid();
 
   if (ret < 0) {
     DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));
@@ -353,14 +351,13 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   if (D.dqb_bsoftlimit==0)
     return(False);
   *bsize = DEV_BSIZE;
-  *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
   *dsize = D.dqb_bsoftlimit;
 
-  if(*dfree < 0)
-    {
+  if (D.dqb_curblocks > D.dqb_bsoftlimit) {
      *dfree = 0;
      *dsize = D.dqb_curblocks;
-    }
+  } else
+    *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
       
   DEBUG(5,("disk_quotas for path \"%s\" returning  bsize %.0f, dfree %.0f, dsize %.0f\n",
          path,(double)*bsize,(double)*dfree,(double)*dsize));
@@ -378,21 +375,26 @@ try to get the disk space from disk quotas - OSF1 version
 
 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
-  uid_t user_id, euser_id;
   int r, save_errno;
   struct dqblk D;
   SMB_STRUCT_STAT S;
+  uid_t euser_id;
 
+  /*
+   * This code presumes that OSF1 will only
+   * give out quota info when the real uid 
+   * matches the effective uid. JRA.
+   */
   euser_id = geteuid();
-  user_id = getuid();
+  save_re_uid();
+  if (set_re_uid() != 0) return False;
 
-  setreuid(euser_id, -1);
   r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D);
-  if (r)
+  if (r) {
      save_errno = errno;
+  }
 
-  if (setreuid(user_id, -1) == -1)
-    DEBUG(5,("Unable to reset uid to %d\n", user_id));
+  restore_re_uid();
 
   *bsize = DEV_BSIZE;
 
@@ -423,7 +425,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   return (True);
 }
 
-#elif defined (SGI6)
+#elif defined (IRIX6)
 /****************************************************************************
 try to get the disk space from disk quotas (IRIX 6.2 version)
 ****************************************************************************/
@@ -469,7 +471,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   }
 
   euser_id=geteuid();
-  seteuid(0);  
+  save_re_uid();
+  set_effective_uid(0);  
 
   /* Use softlimit to determine disk space, except when it has been exceeded */
 
@@ -479,7 +482,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   {
     r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);
 
-    seteuid(euser_id); /* Restore the original uid status. */
+    restore_re_uid();
 
     if (r==-1)
       return(False);
@@ -510,7 +513,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   {
     r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);
 
-    seteuid(euser_id); /* Restore the original uid status. */
+    restore_re_uid();
 
     if (r==-1)
       return(False);
@@ -539,8 +542,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   }
   else
   {
-    seteuid(euser_id); /* Restore the original uid status. */
-    return(False);
+         restore_re_uid();
+         return(False);
   }
 
   return (True);
@@ -570,9 +573,9 @@ try to get the disk space from disk quotas - default version
 
 BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
 {
-  uid_t euser_id;
   int r;
   struct dqblk D;
+  uid_t euser_id;
 #if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
   char dev_disk[256];
   SMB_STRUCT_STAT S;
@@ -584,36 +587,32 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
   euser_id = geteuid();
 
 #ifdef HPUX
-  {
-    uid_t user_id;
-
-    /* for HPUX, real uid must be same as euid to execute quotactl for euid */
-    user_id = getuid();
-    setresuid(euser_id,-1,-1);
-    r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
-    if (setresuid(user_id,-1,-1))
-      DEBUG(5,("Unable to reset uid to %d\n", user_id));
-  }
+  /* for HPUX, real uid must be same as euid to execute quotactl for euid */
+  save_re_uid();
+  if (set_re_uid() != 0) return False;
+  
+  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
+
+  restore_re_uid();
 #else 
 #if defined(__FreeBSD__) || defined(__OpenBSD__)
   {
     /* FreeBSD patches from Marty Moll <martym@arbor.edu> */
-    uid_t user_id;
     gid_t egrp_id;
  
-    /* Need to be root to get quotas in FreeBSD */
-    user_id = getuid();
+    save_re_uid();
+    set_effective_uid(0);
+
     egrp_id = getegid();
-    setuid(0);
-    seteuid(0);
     r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
 
     /* As FreeBSD has group quotas, if getting the user
        quota fails, try getting the group instead. */
-    if (r)
-      r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
-    setuid(user_id);
-    seteuid(euser_id);
+    if (r) {
+           r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
+    }
+
+    restore_re_uid();
   }
 #elif defined(AIX)
   /* AIX has both USER and GROUP quotas: 
@@ -622,7 +621,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
 #else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
   r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
 #endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
-#endif /* HAVE_SETRES */
+#endif /* HPUX */
 
   /* Use softlimit to determine disk space, except when it has been exceeded */
 #if defined(__FreeBSD__) || defined(__OpenBSD__)
index fed82b5e545bd2c68d6f34d0b2613631e9d8e320..54f646e09113a518408d8aab2fc07836446acf9f 100644 (file)
@@ -38,77 +38,33 @@ 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
 ****************************************************************************/
+
 static void overflow_attack(int len)
 {
-        if( DEBUGLVL( 0 ) )
-          {
-         dbgtext( "ERROR: Invalid password length %d.\n", len );
-         dbgtext( "Your machine may be under attack by someone " );
-          dbgtext( "attempting to exploit an old bug.\n" );
-         dbgtext( "Attack was from IP = %s.\n", client_addr(Client) );
-          }
+       if( DEBUGLVL( 0 ) ) {
+               dbgtext( "ERROR: Invalid password length %d.\n", len );
+               dbgtext( "Your machine may be under attack by someone " );
+               dbgtext( "attempting to exploit an old bug.\n" );
+               dbgtext( "Attack was from IP = %s.\n", client_addr(Client) );
+       }
        exit_server("possible attack");
 }
 
 
-/****************************************************************************
-  does _both_ nt->unix and unix->unix username remappings.
-****************************************************************************/
-static void map_nt_and_unix_username(const char *domain, char *user)
-{
-       DOM_NAME_MAP gmep;
-       fstring nt_username;
-
-       /*
-        * Pass the user through the NT -> unix user mapping
-        * function.
-        */
-   
-       if (lp_server_role() != ROLE_DOMAIN_NONE)
-       {
-               memset(nt_username, 0, sizeof(nt_username));
-               if (domain != NULL)
-               {
-                       slprintf(nt_username, sizeof(nt_username)-1, "%s\\%s",
-                                domain, user);
-               }
-               else
-               {
-                       fstrcpy(nt_username, user);
-               }
-
-               if (lookupsmbpwntnam(nt_username, &gmep))
-               {
-                       fstrcpy(user, gmep.unix_name);
-               }
-       }
-
-       /*
-        * Pass the user through the unix -> unix user mapping
-        * function.
-        */
-
-       (void)map_username(user);
-
-       /*
-        * Do any UNIX username case mangling.
-        */
-       (void)Get_Pwnam( user, True);
-}
-
 /****************************************************************************
   reply to an special message 
 ****************************************************************************/
+
 int reply_special(char *inbuf,char *outbuf)
 {
        int outsize = 4;
@@ -122,13 +78,10 @@ int reply_special(char *inbuf,char *outbuf)
        
        *name1 = *name2 = 0;
        
-       bzero(outbuf,smb_size);
+       memset(outbuf,'\0',smb_size);
 
        smb_setlen(outbuf,0);
        
-       DEBUG(20,("NBT message\n"));
-       dump_data(20, inbuf, smb_len(inbuf));
-
        switch (msg_type) {
        case 0x81: /* session request */
                CVAL(outbuf,0) = 0x82;
@@ -202,11 +155,11 @@ int reply_special(char *inbuf,char *outbuf)
 /*******************************************************************
 work out what error to give to a failed connection
 ********************************************************************/
+
 static int connection_error(char *inbuf,char *outbuf,int ecode)
 {
-       if (ecode == ERRnoipc) {
+       if (ecode == ERRnoipc)
                return(ERROR(ERRDOS,ERRnoipc));
-       }
 
        return(ERROR(ERRSRV,ecode));
 }
@@ -247,15 +200,14 @@ 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;
@@ -269,7 +221,25 @@ int reply_tcon(connection_struct *conn,
 
        parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
 
-       map_nt_and_unix_username(global_myworkgroup, user);
+    /*
+     * Ensure the user and password names are in UNIX codepage format.
+     */
+
+    dos_to_unix(user,True);
+       if (!doencrypt)
+       dos_to_unix(password,True);
+
+       /*
+        * Pass the user through the NT -> unix user mapping
+        * function.
+        */
+   
+       (void)map_username(user);
+
+       /*
+        * Do any UNIX username case mangling.
+        */
+       (void)Get_Pwnam( user, True);
 
        conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
   
@@ -288,16 +258,17 @@ int reply_tcon(connection_struct *conn,
        return(outsize);
 }
 
-
 /****************************************************************************
-  reply to a tcon and X
+ Reply to a tcon and X.
 ****************************************************************************/
+
 int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
        pstring service;
        pstring user;
        pstring password;
        pstring devicename;
+       BOOL doencrypt = SMBENCRYPT();
        int ecode = -1;
        uint16 vuid = SVAL(inbuf,smb_uid);
        int passlen = SVAL(inbuf,smb_vwv3);
@@ -314,7 +285,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        if (passlen > MAX_PASS_LEN) {
                overflow_attack(passlen);
        }
-  
        memcpy(password,smb_buf(inbuf),passlen);
        password[passlen]=0;    
        path = smb_buf(inbuf) + passlen;
@@ -339,8 +310,26 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        StrnCpy(devicename,path + strlen(path) + 1,6);
        DEBUG(4,("Got device type %s\n",devicename));
 
-       map_nt_and_unix_username(global_myworkgroup, user);
+    /*
+     * Ensure the user and password names are in UNIX codepage format.
+     */
+
+    dos_to_unix(user,True);
+       if (!doencrypt)
+               dos_to_unix(password,True);
 
+       /*
+        * Pass the user through the NT -> unix user mapping
+        * function.
+        */
+       
+       (void)map_username(user);
+       
+       /*
+        * Do any UNIX username case mangling.
+        */
+       (void)Get_Pwnam(user, True);
+       
        conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
        
        if (!conn)
@@ -397,14 +386,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;
 }
 
 /****************************************************************************
@@ -415,7 +429,6 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
                                 char *smb_nt_passwd, int smb_nt_passlen)
 {
   struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
-       uchar last_chal[8];
   if (lp_security() == SEC_USER)
   {
     smb_trust_acct = getsmbpwnam(user);
@@ -442,10 +455,8 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
       return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
     }
-       if (!last_challenge(last_chal) ||
-            !smb_password_ok(smb_trust_acct, last_chal, NULL, NULL,
-       (unsigned char *)smb_passwd, smb_passlen,
-       (unsigned char *)smb_nt_passwd, smb_nt_passlen, NULL))
+
+    if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
     {
       DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
@@ -479,20 +490,155 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
   return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
 }
 
+/****************************************************************************
+ Create a UNIX user on demand.
+****************************************************************************/
+
+static int smb_create_user(char *unix_user)
+{
+  pstring add_script;
+  int ret;
+
+  pstrcpy(add_script, lp_adduser_script());
+  pstring_sub(add_script, "%u", unix_user);
+  ret = smbrun(add_script,NULL,False);
+  DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
+  return ret;
+}
+
+/****************************************************************************
+ Delete a UNIX user on demand.
+****************************************************************************/
+
+static int smb_delete_user(char *unix_user)
+{
+  pstring del_script;
+  int ret;
+
+  pstrcpy(del_script, lp_deluser_script());
+  pstring_sub(del_script, "%u", unix_user);
+  ret = smbrun(del_script,NULL,False);
+  DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
+  return ret;
+}
+
+/****************************************************************************
+ Check user is in correct domain if required
+****************************************************************************/
+
+static BOOL check_domain_match(char *user, char *domain) 
+{
+  /*
+   * If we aren't serving to trusted domains, we must make sure that
+   * the validation request comes from an account in the same domain
+   * as the Samba server
+   */
+
+  if (!lp_allow_trusted_domains() &&
+      !strequal(lp_workgroup(), domain) ) {
+      DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
+      return False;
+  } else {
+      return True;
+  }
+}
+
 /****************************************************************************
  Check for a valid username and password in security=server mode.
 ****************************************************************************/
 
-static BOOL check_server_security(char *orig_user, char *domain, 
+static BOOL check_server_security(char *orig_user, char *domain, char *unix_user,
                                   char *smb_apasswd, int smb_apasslen,
                                   char *smb_ntpasswd, int smb_ntpasslen)
 {
+  BOOL ret = False;
+
   if(lp_security() != SEC_SERVER)
     return False;
 
-  return server_validate(orig_user, domain, 
+  if (!check_domain_match(orig_user, domain))
+     return False;
+
+  ret = server_validate(orig_user, domain, 
                             smb_apasswd, smb_apasslen, 
                             smb_ntpasswd, smb_ntpasslen);
+  if(ret) {
+    /*
+     * User validated ok against Domain controller.
+     * If the admin wants us to try and create a UNIX
+     * user on the fly, do so.
+     * Note that we can never delete users when in server
+     * level security as we never know if it was a failure
+     * due to a bad password, or the user really doesn't exist.
+     */
+    if(lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
+      smb_create_user(unix_user);
+    }
+  }
+
+  return ret;
+}
+
+/****************************************************************************
+ Check for a valid username and password in security=domain mode.
+****************************************************************************/
+
+static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user, 
+                                  char *smb_apasswd, int smb_apasslen,
+                                  char *smb_ntpasswd, int smb_ntpasslen)
+{
+  BOOL ret = False;
+  BOOL user_exists = True;
+
+  if(lp_security() != SEC_DOMAIN)
+    return False;
+
+  if (!check_domain_match(orig_user, domain))
+     return False;
+
+  ret = domain_client_validate(orig_user, domain,
+                                smb_apasswd, smb_apasslen,
+                                smb_ntpasswd, smb_ntpasslen,
+                                &user_exists);
+
+  if(ret) {
+    /*
+     * User validated ok against Domain controller.
+     * If the admin wants us to try and create a UNIX
+     * user on the fly, do so.
+     */
+    if(user_exists && lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
+      smb_create_user(unix_user);
+    }
+  } else {
+    /*
+     * User failed to validate ok against Domain controller.
+     * If the failure was "user doesn't exist" and admin 
+     * wants us to try and delete that UNIX user on the fly,
+     * do so.
+     */
+    if(!user_exists && lp_deluser_script() && Get_Pwnam(unix_user,True)) {
+      smb_delete_user(unix_user);
+    }
+  }
+
+  return ret;
+}
+
+/****************************************************************************
+ Return a bad password error configured for the correct client type.
+****************************************************************************/       
+
+static int bad_password_error(char *inbuf,char *outbuf)
+{
+  enum remote_arch_types ra_type = get_remote_arch();
+
+  if(ra_type == RA_WINNT && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) {
+    SSVAL(outbuf,smb_flg2,FLAGS2_32_BIT_ERROR_CODES);
+    return(ERROR(0,0xc0000000|NT_STATUS_LOGON_FAILURE));
+  }
+
+  return(ERROR(ERRSRV,ERRbadpw));
 }
 
 /****************************************************************************
@@ -502,9 +648,8 @@ reply to a session setup command
 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
   uint16 sess_vuid;
-  uchar user_sess_key[16];
-  int gid;
-  int uid;
+  gid_t gid;
+  uid_t uid;
   int   smb_bufsize;    
   int   smb_apasslen = 0;   
   pstring smb_apasswd;
@@ -517,63 +662,55 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
   static BOOL done_sesssetup = False;
   BOOL doencrypt = SMBENCRYPT();
   char *domain = "";
-       uchar last_chal[8];
 
   *smb_apasswd = 0;
   *smb_ntpasswd = 0;
   
   smb_bufsize = SVAL(inbuf,smb_vwv2);
 
-  if (Protocol < PROTOCOL_NT1)
-  {
+  if (Protocol < PROTOCOL_NT1) {
     smb_apasslen = SVAL(inbuf,smb_vwv7);
     if (smb_apasslen > MAX_PASS_LEN)
-    {
-           overflow_attack(smb_apasslen);
-    }
+      overflow_attack(smb_apasslen);
 
     memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
     smb_apasswd[smb_apasslen] = 0;
     pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
-
+    /*
+     * Incoming user is in DOS codepage format. Convert
+     * to UNIX.
+     */
+    dos_to_unix(user,True);
+  
     if (!doencrypt && (lp_security() != SEC_SERVER)) {
-           smb_apasslen = strlen(smb_apasswd);
+      smb_apasslen = strlen(smb_apasswd);
     }
-
-       if (lp_server_ntlmv2() == True)
-       {
-               DEBUG(1,("NTLMv2-only accepted with NT LANMAN 1.0 and above.\n\
-user %s attempted down-level SMB connection\n", user));
-               return(ERROR(ERRSRV,ERRbadpw));
-       }
-  }
-  else
-  {
+  } else {
     uint16 passlen1 = SVAL(inbuf,smb_vwv7);
     uint16 passlen2 = SVAL(inbuf,smb_vwv8);
     enum remote_arch_types ra_type = get_remote_arch();
     char *p = smb_buf(inbuf);    
 
-    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_WIN95) {
       if(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
         set_remote_arch( RA_WINNT);
       else
         set_remote_arch( RA_WIN95);
     }
 
-    if (passlen1 != 24 && passlen2 <= 24)
+    if (passlen1 != 24 && passlen2 != 24)
       doencrypt = False;
 
     if (passlen1 > MAX_PASS_LEN) {
-           overflow_attack(passlen1);
+      overflow_attack(passlen1);
     }
 
     passlen1 = MIN(passlen1, MAX_PASS_LEN);
@@ -590,18 +727,33 @@ user %s attempted down-level SMB connection\n", user));
 
           if passlen1>0 and passlen2>0 then maybe its a NT box and its
           setting passlen2 to some random value which really stuffs
-          things up. we need to fix that one.
+          things up. we need to fix that one.  */
 
-          LKCLXXXX: the random value can be random 16 bit.  old test
-          used to have ... && passlen <= 24) which of course fails
-          most of the time.
-        */
-
-      if (passlen1 > 0 && passlen2 > 0 && passlen2 != 1)
+      if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
         passlen2 = 0;
     }
 
-    if (doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
+    if (lp_restrict_anonymous()) {
+      /* there seems to be no reason behind the differences in MS clients formatting
+       * various info like the domain, NativeOS, and NativeLanMan fields. Win95
+       * in particular seems to have an extra null byte between the username and the
+       * domain, or the password length calculation is wrong, which throws off the
+       * string extraction routines below.  This makes the value of domain be the
+       * empty string, which fails the restrict anonymous check further down.
+       * This compensates for that, and allows browsing to work in mixed NT and
+       * win95 environments even when restrict anonymous is true. AAB
+       */
+      dump_data(100, p, 0x70);
+      DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2));
+      if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
+        DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n"));
+        DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n"));
+        DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
+        passlen1 = 1;
+      }
+    }
+
+    if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
       /* Save the lanman2 password and the NT md4 password. */
       smb_apasslen = passlen1;
       memcpy(smb_apasswd,p,smb_apasslen);
@@ -609,54 +761,77 @@ user %s attempted down-level SMB connection\n", user));
       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);
 
       /* wfwg sometimes uses a space instead of a null */
       if (strequal(smb_apasswd," ")) {
-       smb_apasslen = 0;
-       *smb_apasswd = 0;
+        smb_apasslen = 0;
+        *smb_apasswd = 0;
       }
     }
     
-    if (passlen2 == 0 && smb_apasslen == 0 && ra_type == RA_WIN95)
-    {
-      /* work-around for win95 NULL sessions, where NULL password is
-         actually put in the data stream before the domain name etc */
-      p++;
-    }
-    else
-    {
-           p += passlen1 + passlen2;
-    }
-
-    fstrcpy(user,p); p = skip_string(p,1);
+    p += passlen1 + passlen2;
+    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,("Domain=[%s]  NativeOS=[%s] NativeLanMan=[%s]\n",
-            domain, skip_string(p,1), skip_string(p,2)));
+            domain,skip_string(p,1),skip_string(p,2)));
   }
 
+
   DEBUG(3,("sesssetupX:name=[%s]\n",user));
 
   /* If name ends in $ then I think it's asking about whether a */
   /* computer with that name (minus the $) has access. For now */
   /* say yes to everything ending in $. */
-  if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24))
-  {
+
+  if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
     return session_trust_account(conn, inbuf, outbuf, user, 
                                  smb_apasswd, smb_apasslen,
                                  smb_ntpasswd, smb_ntpasslen);
   }
 
+  if (done_sesssetup && lp_restrict_anonymous()) {
+    /* tests show that even if browsing is done over already validated connections
+     * without a username and password the domain is still provided, which it
+     * wouldn't be if it was a purely anonymous connection.  So, in order to
+     * restrict anonymous, we only deny connections that have no session
+     * information.  If a domain has been provided, then it's not a purely
+     * anonymous connection. AAB
+     */
+    if (!*user && !*smb_apasswd && !*domain) {
+      DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
+      return(ERROR(ERRDOS,ERRnoaccess));
+    }
+  }
+
   /* If no username is sent use the guest account */
-  if (!*user)
-  {
+  if (!*user) {
     pstrcpy(user,lp_guestaccount(-1));
     /* If no user and no password then set guest flag. */
     if( *smb_apasswd == 0)
@@ -664,6 +839,7 @@ user %s attempted down-level SMB connection\n", user));
   }
 
   strlower(user);
+
   /*
    * In share level security, only overwrite sesssetup_use if
    * it's a non null-session share. Helps keep %U and %G
@@ -672,6 +848,7 @@ user %s attempted down-level SMB connection\n", user));
 
   if((lp_security() != SEC_SHARE) || (*user && !guest))
     pstrcpy(sesssetup_user,user);
+
   reload_services(True);
 
   /*
@@ -682,7 +859,17 @@ user %s attempted down-level SMB connection\n", user));
 
   pstrcpy( orig_user, user);
 
-  map_nt_and_unix_username(domain, user);
+  /*
+   * Pass the user through the NT -> unix user mapping
+   * function.
+   */
+   
+  (void)map_username(user);
+
+  /*
+   * Do any UNIX username case mangling.
+   */
+  (void)Get_Pwnam( user, True);
 
   add_session_user(user);
 
@@ -699,14 +886,12 @@ user %s attempted down-level SMB connection\n", user));
    */
 
   if (!guest && 
-      !check_server_security(orig_user, domain,
+                         !check_server_security(orig_user, domain, user,
+                                                                        smb_apasswd, smb_apasslen,
+                                                                        smb_ntpasswd, smb_ntpasslen) &&
+                         !check_domain_security(orig_user, domain, user,
                              smb_apasswd, smb_apasslen,
                              smb_ntpasswd, smb_ntpasslen) &&
-      !last_challenge(last_chal) &&
-      !check_domain_security(orig_user, domain,
-                             last_chal,
-                             smb_apasswd, smb_apasslen,
-                             smb_ntpasswd, smb_ntpasslen, user_sess_key) &&
       !check_hosts_equiv(user)
      )
   {
@@ -721,25 +906,31 @@ user %s attempted down-level SMB connection\n", user));
      * 128 length unicode.
       */
 
-    if (smb_ntpasslen)
+    if(smb_ntpasslen)
     {
-      if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL,user_sess_key))
-        DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
+      if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
+        DEBUG(2,("NT Password did not match for user '%s' ! Defaulting to Lanman\n", user));
       else
         valid_nt_password = True;
     } 
 
-    if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL,user_sess_key))
+    if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL))
     {
       if (lp_security() >= SEC_USER) 
       {
         if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
-          return(ERROR(ERRSRV,ERRbadpw));
+        {
+          DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
+          return bad_password_error(inbuf,outbuf);
+        }
 
         if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
         {
-         if (Get_Pwnam(user,True))
-            return(ERROR(ERRSRV,ERRbadpw));
+          if (Get_Pwnam(user,True))
+          {
+            DEBUG(1,("Rejecting user '%s': bad password\n", user));
+            return bad_password_error(inbuf,outbuf);
+          }
         }
 
         /*
@@ -765,15 +956,12 @@ user %s attempted down-level SMB connection\n", user));
       lp_servicenumber(user) < 0)      
   {
     int homes = lp_servicenumber(HOMES_NAME);
-    char *home = get_unixhome_dir(user);
+    char *home = get_user_home_dir(user);
     if (homes >= 0 && home)
-       {
-               pstring home_dir;
-               fstrcpy(home_dir, home);
-               lp_add_home(user,homes,home_dir);
-       }
+      lp_add_home(user,homes,home);
   }
 
+
   /* it's ok - setup a reply */
   if (Protocol < PROTOCOL_NT1) {
     set_message(outbuf,3,0,True);
@@ -793,10 +981,10 @@ user %s attempted down-level SMB connection\n", user));
      user we should become.
      */
   {
-    const struct passwd *pw = Get_Pwnam(user,False);
+    struct passwd *pw = Get_Pwnam(user,False);
     if (!pw) {
       DEBUG(1,("Username %s is invalid on this system\n",user));
-      return(ERROR(ERRSRV,ERRbadpw));
+      return bad_password_error(inbuf,outbuf);
     }
     gid = pw->pw_gid;
     uid = pw->pw_uid;
@@ -807,7 +995,7 @@ user %s attempted down-level SMB connection\n", user));
 
   /* register the name and uid as being validated, so further connections
      to a uid can get through without a password, on the same VC */
-  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest,user_sess_key);
+  sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
  
   SSVAL(outbuf,smb_uid,sess_vuid);
   SSVAL(inbuf,smb_uid,sess_vuid);
@@ -836,14 +1024,10 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   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));
-  }
+  unix_convert(name,conn,0,&bad_path,&st);
 
   mode = SVAL(inbuf,smb_vwv0);
+
   if (check_name(name,conn)) {
     if(VALID_STAT(st))
       ok = S_ISDIR(st.st_mode);
@@ -900,7 +1084,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL bad_path = False;
  
   pstrcpy(fname,smb_buf(inbuf) + 1);
-  
+
   /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
      under WfWg - weird! */
   if (! (*fname))
@@ -913,14 +1097,10 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   }
   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;
@@ -982,11 +1162,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   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);
@@ -1025,7 +1201,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   int outsize = 0;
   SMB_BIG_UINT dfree,dsize,bsize;
   
-  conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
+  sys_disk_free(".",True,&bsize,&dfree,&dsize);
   
   outsize = set_message(outbuf,5,0,True);
   
@@ -1084,74 +1260,70 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   
   /* 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)
-    {
-      pstring dir2;
-
-      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_format(dir2);
+    pstring dir2;
 
-      if (!check_name(directory,conn))
-        can_open = False;
+    pstrcpy(directory,smb_buf(inbuf)+1);
+    pstrcpy(dir2,smb_buf(inbuf)+1);
+    unix_convert(directory,conn,0,&bad_path,NULL);
+    unix_format(dir2);
 
-      p = strrchr(dir2,'/');
-      if (p == NULL) 
-      {
-        pstrcpy(mask,dir2);
-        *dir2 = 0;
-      }
-      else
-      {
-        *p = 0;
-        pstrcpy(mask,p+1);
-      }
+    if (!check_name(directory,conn))
+      can_open = False;
 
-      p = strrchr(directory,'/');
-      if (!p) 
-        *directory = 0;
-      else
-        *p = 0;
-
-      if (strlen(directory) == 0)
-        pstrcpy(directory,"./");
-      bzero(status,21);
-      CVAL(status,0) = dirtype;
+    p = strrchr(dir2,'/');
+    if (p == NULL) 
+    {
+      pstrcpy(mask,dir2);
+      *dir2 = 0;
     }
-  else
+    else
     {
-      memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
-      memcpy(mask,status+1,11);
-      mask[11] = 0;
-      dirtype = CVAL(status,0) & 0x1F;
-      conn->dirptr = dptr_fetch(status+12,&dptr_num);      
-      if (!conn->dirptr)
-       goto SearchEmpty;
-      string_set(&conn->dirpath,dptr_path(dptr_num));
-      if (!case_sensitive)
-       strnorm(mask);
+      *p = 0;
+      pstrcpy(mask,p+1);
     }
 
+    p = strrchr(directory,'/');
+    if (!p) 
+      *directory = 0;
+    else
+      *p = 0;
+
+    if (strlen(directory) == 0)
+      pstrcpy(directory,"./");
+    memset((char *)status,'\0',21);
+    CVAL(status,0) = dirtype;
+  }
+  else
+  {
+    memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
+    memcpy(mask,status+1,11);
+    mask[11] = 0;
+    dirtype = CVAL(status,0) & 0x1F;
+    conn->dirptr = dptr_fetch(status+12,&dptr_num);      
+    if (!conn->dirptr)
+      goto SearchEmpty;
+    string_set(&conn->dirpath,dptr_path(dptr_num));
+    if (!case_sensitive)
+      strnorm(mask);
+  }
+
   /* turn strings of spaces into a . */  
   {
     trim_string(mask,NULL," ");
     if ((p = strrchr(mask,' ')))
-      {
-       fstring ext;
-       fstrcpy(ext,p+1);
-       *p = 0;
-       trim_string(mask,NULL," ");
-       pstrcat(mask,".");
-       pstrcat(mask,ext);
-      }
+    {
+      fstring ext;
+      fstrcpy(ext,p+1);
+      *p = 0;
+      trim_string(mask,NULL," ");
+      pstrcat(mask,".");
+      pstrcat(mask,ext);
+    }
   }
 
   /* Convert the formatted mask. (This code lives in trans2.c) */
@@ -1179,104 +1351,104 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   }
 
   if (!strchr(mask,'.') && strlen(mask)>8)
-    {
-      fstring tmp;
-      fstrcpy(tmp,&mask[8]);
-      mask[8] = '.';
-      mask[9] = 0;
-      pstrcat(mask,tmp);
-    }
+  {
+    fstring tmp;
+    fstrcpy(tmp,&mask[8]);
+    mask[8] = '.';
+    mask[9] = 0;
+    pstrcat(mask,tmp);
+  }
 
   DEBUG(5,("mask=%s directory=%s\n",mask,directory));
   
   if (can_open)
-    {
-      p = smb_buf(outbuf) + 3;
-      
-      ok = True;
+  {
+    p = smb_buf(outbuf) + 3;
       
-      if (status_len == 0)
-       {
-         dptr_num = dptr_create(conn,directory,expect_close,SVAL(inbuf,smb_pid));
-         if (dptr_num < 0)
+    ok = True;
+     
+    if (status_len == 0)
+    {
+      dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
+      if (dptr_num < 0)
+      {
+        if(dptr_num == -2)
         {
-          if(dptr_num == -2)
+          if((errno == ENOENT) && bad_path)
           {
-            if((errno == ENOENT) && bad_path)
-            {
-              unix_ERR_class = ERRDOS;
-              unix_ERR_code = ERRbadpath;
-            }
-            return (UNIXERROR(ERRDOS,ERRnofids));
+            unix_ERR_class = ERRDOS;
+            unix_ERR_code = ERRbadpath;
           }
-          return(ERROR(ERRDOS,ERRnofids));
+          return (UNIXERROR(ERRDOS,ERRnofids));
         }
-       }
+        return(ERROR(ERRDOS,ERRnofids));
+      }
+    }
 
-      DEBUG(4,("dptr_num is %d\n",dptr_num));
+    DEBUG(4,("dptr_num is %d\n",dptr_num));
 
-      if (ok)
-       {
-         if ((dirtype&0x1F) == aVOLID)
-           {     
-             memcpy(p,status,21);
-             make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
-             dptr_fill(p+12,dptr_num);
-             if (dptr_zero(p+12) && (status_len==0))
-               numentries = 1;
-             else
-               numentries = 0;
-             p += DIR_STRUCT_SIZE;
-           }
-         else 
-           {
-             DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
-                      conn->dirpath,lp_dontdescend(SNUM(conn))));
-             if (in_list(conn->dirpath,
-                         lp_dontdescend(SNUM(conn)),True))
-               check_descend = True;
-
-             for (i=numentries;(i<maxentries) && !finished;i++)
-               {
-                 finished = 
-                   !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
-                 if (!finished)
-                   {
-                     memcpy(p,status,21);
-                     make_dir_struct(p,mask,fname,size,mode,date);
-                     dptr_fill(p+12,dptr_num);
-                     numentries++;
-                   }
-                 p += DIR_STRUCT_SIZE;
-               }
-           }
-       }
-    }
+    if (ok)
+    {
+      if ((dirtype&0x1F) == aVOLID)
+      {          
+        memcpy(p,status,21);
+        make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
+        dptr_fill(p+12,dptr_num);
+        if (dptr_zero(p+12) && (status_len==0))
+          numentries = 1;
+        else
+          numentries = 0;
+        p += DIR_STRUCT_SIZE;
+      }
+      else 
+      {
+        DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
+              conn->dirpath,lp_dontdescend(SNUM(conn))));
+        if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
+          check_descend = True;
+
+        for (i=numentries;(i<maxentries) && !finished;i++)
+        {
+          finished = 
+            !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
+          if (!finished)
+          {
+            memcpy(p,status,21);
+            make_dir_struct(p,mask,fname,size,mode,date);
+            dptr_fill(p+12,dptr_num);
+            numentries++;
+          }
+          p += DIR_STRUCT_SIZE;
+        }
+      }
+       } /* if (ok ) */
+  }
 
 
- SearchEmpty:
 SearchEmpty:
 
   if (numentries == 0 || !ok)
-    {
-      CVAL(outbuf,smb_rcls) = ERRDOS;
-      SSVAL(outbuf,smb_err,ERRnofiles);
-    }
+  {
+    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
      and no entries were found then return error and close dirptr 
      (X/Open spec) */
 
   if(ok && expect_close && numentries == 0 && status_len == 0)
-    {
-      CVAL(outbuf,smb_rcls) = ERRDOS;
-      SSVAL(outbuf,smb_err,ERRnofiles);
-      /* Also close the dptr - we know it's gone */
-      dptr_close(dptr_num);
-    }
+  {
+    CVAL(outbuf,smb_rcls) = ERRDOS;
+    SSVAL(outbuf,smb_err,ERRnofiles);
+    /* Also close the dptr - we know it's gone */
+    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);
@@ -1295,8 +1467,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
     slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
 
   DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
-       smb_fn_name(CVAL(inbuf,smb_com)), 
-       mask, directory, dirtype, numentries, maxentries ) );
+        smb_fn_name(CVAL(inbuf,smb_com)), 
+        mask, directory, dirtype, numentries, maxentries ) );
 
   return(outsize);
 }
@@ -1311,7 +1483,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   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;
@@ -1325,7 +1497,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
   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);
@@ -1358,11 +1530,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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));
-  }
+  unix_convert(fname,conn,0,&bad_path,NULL);
     
   fsp = file_new();
   if (!fsp)
@@ -1381,9 +1549,8 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
  
   unixmode = unix_mode(conn,aARCH);
       
-  open_file_shared(fsp, conn, fname, share_mode,
-                  (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN),
-                  unixmode, oplock_request, &rmode, NULL);
+  open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+                   unixmode, oplock_request,&rmode,NULL);
 
   if (!fsp->open)
   {
@@ -1396,7 +1563,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+  if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1425,7 +1592,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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,19 +1626,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   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));
-  }
+  unix_convert(fname,conn,0,&bad_path,NULL);
     
   fsp = file_new();
   if (!fsp)
@@ -1490,8 +1651,8 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 
   unixmode = unix_mode(conn,smb_attr | aARCH);
       
-  open_file_shared(fsp, conn, fname, smb_mode, smb_ofun, unixmode,
-                  oplock_request, &rmode, &smb_action);
+  open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
+                      oplock_request, &rmode,&smb_action);
       
   if (!fsp->open)
   {
@@ -1504,7 +1665,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+  if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(ERROR(ERRDOS,ERRnoaccess));
   }
@@ -1526,7 +1687,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     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;
   }
 
@@ -1539,7 +1700,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
     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;
   }
 
@@ -1605,11 +1766,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
   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));
-  }
+  unix_convert(fname,conn,0,&bad_path,NULL);
 
   if (createmode & aVOLID)
     {
@@ -1636,18 +1793,17 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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. */
-  open_file_shared(fsp, conn, fname,
-                 SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
-                 ofun, unixmode, oplock_request, NULL, NULL);
+  open_file_shared(fsp,conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
+                   ofun, unixmode, oplock_request, NULL, NULL);
   
   if (!fsp->open)
   {
@@ -1667,7 +1823,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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 ) );
@@ -1695,11 +1851,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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));
-  }
+  unix_convert(fname,conn,0,&bad_path,NULL);
   
   unixmode = unix_mode(conn,createmode);
   
@@ -1718,14 +1870,12 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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. */
-  open_file_shared(fsp,conn,fname2,
-                  SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
-                  (FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_FAIL), 
-                  unixmode, oplock_request, NULL, NULL);
+  open_file_shared(fsp,conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB), 
+                   (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
 
   if (!fsp->open)
   {
@@ -1747,7 +1897,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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 ) );
@@ -1768,7 +1918,7 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False);
+  if (dos_lstat(fname,&sbuf) != 0) return(False);
   fmode = dos_mode(conn,fname,&sbuf);
   if (fmode & aDIR) return(False);
   if (!lp_delete_readonly(SNUM(conn))) {
@@ -1781,8 +1931,9 @@ 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)
 {
   int outsize = 0;
@@ -1796,6 +1947,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   BOOL has_wild;
   BOOL exists=False;
   BOOL bad_path = False;
+  BOOL rc = True;
 
   *directory = *mask = 0;
 
@@ -1805,11 +1957,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
    
   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) {
@@ -1821,7 +1969,16 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
     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,'?');
@@ -1829,10 +1986,10 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   if (!has_wild) {
     pstrcat(directory,"/");
     pstrcat(directory,mask);
-    if (can_delete(directory,conn,dirtype) && !conn->vfs_ops.unlink(directory))
+    if (can_delete(directory,conn,dirtype) && !dos_unlink(directory))
       count++;
     if (!count)
-      exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);    
+      exists = dos_file_exist(directory,NULL);    
   } else {
     void *dirptr = NULL;
     char *dname;
@@ -1862,7 +2019,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
            error = ERRnoaccess;
            slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
            if (!can_delete(fname,conn,dirtype)) continue;
-           if (!conn->vfs_ops.unlink(fname)) count++;
+           if (!dos_unlink(fname)) count++;
            DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
          }
        CloseDir(dirptr);
@@ -1892,6 +2049,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 /****************************************************************************
    reply to a readbraw (core+ protocol)
 ****************************************************************************/
+
 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
   size_t maxcount,mincount;
@@ -1917,13 +2075,45 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 
   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,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
             (double)startpos ));
@@ -1932,7 +2122,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
          return(-1);
     }      
   }
-#endif /* LARGE_SMB_OFF_T */
   maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
   mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
 
@@ -1940,13 +2129,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   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))
   {
     SMB_OFF_T size = fsp->size;
@@ -1955,7 +2137,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     if (size < sizeneeded)
     {
       SMB_STRUCT_STAT st;
-      if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0)
+      if (sys_fstat(fsp->fd_ptr->fd,&st) == 0)
         size = st.st_size;
       if (!fsp->can_write) 
         fsp->size = size;
@@ -1969,7 +2151,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   
   DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
              fsp->fnum, (double)startpos,
-             maxcount, mincount, nread ) );
+             (int)maxcount, (int)mincount, (int)nread ) );
   
 #if UNSAFE_READRAW
   {
@@ -1979,11 +2161,11 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
 
 #if USE_READ_PREDICTION
     if (!fsp->can_write)
-      predict = read_predict(fsp, fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
+      predict = read_predict(fsp->fd_ptr->fd,startpos,header+4,NULL,nread);
 #endif /* USE_READ_PREDICTION */
 
     if ((nread-predict) > 0) {
-      if(conn->vfs_ops.seek(fsp,startpos + predict) == -1) {
+      if(seek_file(fsp,startpos + predict) == -1) {
         DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
         ret = 0;
         seek_fail = True;
@@ -1991,7 +2173,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
     }
 
     if(!seek_fail)
-      ret = (ssize_t)vfs_transfer_file(-1, fsp->fd_ptr->fd, Client, NULL,
+      ret = (ssize_t)transfer_file(fsp->fd_ptr->fd,Client,
                                    (SMB_OFF_T)(nread-predict),header,4+predict, 
                                    startpos+predict);
   }
@@ -2037,8 +2219,15 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
   outsize = set_message(outbuf,5,3,True);
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
-  
-  if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
+  /*
+   * 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_WRLCK, &eclass, &ecode)) {
     if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
       /*
        * A blocking lock was requested. Package up
@@ -2062,7 +2251,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
   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);
 }
@@ -2071,7 +2260,8 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
 /****************************************************************************
   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;
@@ -2094,9 +2284,8 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));     
 
-  if (numtoread > 0) {
+  if (numtoread > 0)
     nread = read_file(fsp,data,startpos,numtoread);
-  }
   
   if (nread < 0)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2108,7 +2297,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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);
 }
@@ -2137,28 +2326,42 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   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))
     return(ERROR(ERRDOS,ERRlock));
   nread = read_file(fsp,data,startpos,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 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);
 }
@@ -2166,7 +2369,8 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 /****************************************************************************
   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 reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   ssize_t nwritten=0;
   ssize_t total_written=0;
@@ -2203,16 +2407,11 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
     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));
@@ -2237,12 +2436,11 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
 
   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,
-                              (SMB_OFF_T)numtowrite,NULL,0, 
-                              startpos+nwritten);
+  nwritten = transfer_file(Client,fsp->fd_ptr->fd,(SMB_OFF_T)numtowrite,NULL,0,
+                          startpos+nwritten);
   total_written += nwritten;
   
   /* Set up outbuf to return the correct return */
@@ -2255,12 +2453,11 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
     SSVAL(outbuf,smb_err,ERRdiskfull);      
   }
 
-  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)
+    sync_file(conn,fsp);
 
   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 */
@@ -2273,7 +2470,8 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
 /****************************************************************************
   reply to a writeunlock (core+)
 ****************************************************************************/
-int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   ssize_t nwritten = -1;
   size_t numtowrite;
@@ -2295,19 +2493,16 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     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)))
+    sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2320,7 +2515,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
   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);
 }
@@ -2328,7 +2523,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum
 /****************************************************************************
   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;
@@ -2337,9 +2532,9 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   files_struct *fsp = file_fsp(inbuf,smb_vwv0);
   int outsize = 0;
 
-         /* If it's an IPC, pass off the pipe handler. */
-         if (IS_IPC(conn))
-           return reply_pipe_write(inbuf,outbuf,dum_size,dum_buffsize);
+  /* If it's an IPC, pass off the pipe handler. */
+  if (IS_IPC(conn))
+    return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
 
   CHECK_FSP(fsp,conn);
   CHECK_WRITE(fsp);
@@ -2350,21 +2545,19 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   data = smb_buf(inbuf) + 3;
   
   if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
-    return(ERROR(ERRDOS,ERRlock));
-
-  if(seek_file(fsp,startpos) == -1)
-    return(UNIXERROR(ERRDOS,ERRnoaccess));
+    return(ERROR(ERRDOS,ERRlock));
 
   /* 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);
-  else
-    nwritten = write_file(fsp,data,numtowrite);
+  if(numtowrite == 0) {
+    if((nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos)) >= 0)
+      set_filelen_write_cache(fsp, startpos); 
+  } else
+    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)))
+    sync_file(conn,fsp);
 
   if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2379,7 +2572,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,i
   }
   
   DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
-          fsp->fnum, numtowrite, nwritten));
+          fsp->fnum, (int)numtowrite, (int)nwritten));
 
   return(outsize);
 }
@@ -2408,21 +2601,31 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
 
   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))
     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,
@@ -2430,7 +2633,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   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));
@@ -2445,11 +2648,10 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
   }
 
   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)
+    sync_file(conn,fsp);
 
   return chain_reply(inbuf,outbuf,length,bufsize);
 }
@@ -2458,7 +2660,8 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
 /****************************************************************************
   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;
@@ -2469,11 +2672,12 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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; break;
     case 1: umode = SEEK_CUR; break;
     case 2: umode = SEEK_END; break;
@@ -2481,16 +2685,48 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
       umode = SEEK_SET; break;
   }
 
-  if((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,startpos,umode)) == -1)
-    return(UNIXERROR(ERRDOS,ERRnoaccess));
+  if((res = sys_lseek(fsp->fd_ptr->fd,startpos,umode)) == -1) {
+    /*
+     * 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 = sys_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(sys_fstat( fsp->fd_ptr->fd, &sbuf) == -1)
+          return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+        current_pos += sbuf.st_size;
+      }
+      if(current_pos < 0)
+        res = sys_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);
 }
@@ -2498,7 +2734,8 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 /****************************************************************************
   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);
@@ -2511,7 +2748,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if (!fsp) {
          file_sync_all(conn);
   } else {
-         conn->vfs_ops.sync(fsp->fd_ptr->fd);
+         sync_file(conn,fsp);
   }
 
   DEBUG(3,("flush\n"));
@@ -2535,8 +2772,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;
@@ -2546,9 +2783,8 @@ int reply_close(connection_struct *conn,
        outsize = set_message(outbuf,0,0,True);
 
        /* If it's an IPC, pass off to the pipe handler. */
-       if (IS_IPC(conn)) {
+       if (IS_IPC(conn))
                return reply_pipe_close(conn, inbuf,outbuf);
-       }
 
        fsp = file_fsp(inbuf,smb_vwv0);
 
@@ -2556,25 +2792,26 @@ int reply_close(connection_struct *conn,
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-    if(!fsp || !fsp->open || (fsp->conn != conn))
-      return(ERROR(ERRDOS,ERRbadfid));
+       if(!fsp || !fsp->open || (fsp->conn != conn))
+               return(ERROR(ERRDOS,ERRbadfid));
 
        if(HAS_CACHED_ERROR(fsp)) {
                eclass = fsp->wbmpx_ptr->wr_errclass;
                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,
@@ -2592,10 +2829,19 @@ 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,
+                        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 */
@@ -2609,12 +2855,14 @@ 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;
@@ -2631,23 +2879,25 @@ int reply_writeclose(connection_struct *conn,
   
        if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
                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,
+                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);
@@ -2696,7 +2946,8 @@ 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 reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   int outsize = set_message(outbuf,0,0,True);
   SMB_OFF_T count,offset;
@@ -2775,6 +3026,8 @@ int reply_echo(connection_struct *conn,
 
        DEBUG(3,("echo %d times\n", smb_reverb));
 
+       smb_echo_count++;
+
        return -1;
 }
 
@@ -2815,7 +3068,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)) {
                file_free(fsp);
@@ -2852,6 +3105,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);
@@ -2862,7 +3116,12 @@ 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);
 }
@@ -2955,7 +3214,7 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
   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 ) );
@@ -2974,15 +3233,10 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   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));
+    ret = dos_mkdir(directory,unix_mode(conn,aDIR));
   
   if (ret < 0)
   {
@@ -3005,11 +3259,12 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 Static function used by reply_rmdir to delete an entire directory
 tree recursively.
 ****************************************************************************/
-static BOOL recursive_rmdir(connection_struct *conn, char *directory)
+
+static BOOL recursive_rmdir(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;
@@ -3033,7 +3288,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
     pstrcat(fullname, "/");
     pstrcat(fullname, dname);
 
-    if(conn->vfs_ops.lstat(fullname, &st) != 0)
+    if(dos_lstat(fullname, &st) != 0)
     {
       ret = True;
       break;
@@ -3041,18 +3296,18 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
 
     if(st.st_mode & S_IFDIR)
     {
-      if(recursive_rmdir(conn, fullname)!=0)
+      if(recursive_rmdir(fullname)!=0)
       {
         ret = True;
         break;
       }
-      if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0)
+      if(dos_rmdir(fullname) != 0)
       {
         ret = True;
         break;
       }
     }
-    else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
+    else if(dos_unlink(fullname) != 0)
     {
       ret = True;
       break;
@@ -3063,8 +3318,97 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
 }
 
 /****************************************************************************
-  reply to a rmdir
+ The internals of the rmdir code - called elsewhere.
+****************************************************************************/
+
+BOOL rmdir_internals(connection_struct *conn, char *directory)
+{
+  BOOL ok;
+
+  ok = (dos_rmdir(directory) == 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);
+
+    if(dirptr != NULL)
+    {
+      int dirpos = TellDir(dirptr);
+      while ((dname = ReadDirName(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;
+
+          /* Construct the full name. */
+          if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
+          {
+            errno = ENOMEM;
+            break;
+          }
+          pstrcpy(fullname, directory);
+          pstrcat(fullname, "/");
+          pstrcat(fullname, dname);
+                     
+          if(dos_lstat(fullname, &st) != 0)
+            break;
+          if(st.st_mode & S_IFDIR)
+          {
+            if(lp_recursive_veto_delete(SNUM(conn)))
+            {
+              if(recursive_rmdir(fullname) != 0)
+                break;
+            }
+            if(dos_rmdir(fullname) != 0)
+              break;
+          }
+          else if(dos_unlink(fullname) != 0)
+            break;
+        }
+        CloseDir(dirptr);
+        /* Retry the rmdir */
+        ok = (dos_rmdir(directory) == 0);
+      }
+      else
+        CloseDir(dirptr);
+    }
+    else
+      errno = ENOTEMPTY;
+  }
+          
+  if (!ok)
+    DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n",
+          directory,strerror(errno)));
+
+  return ok;
+}
+
+/****************************************************************************
+ Reply to a rmdir.
 ****************************************************************************/
+
 int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 {
   pstring directory;
@@ -3073,92 +3417,13 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL bad_path = False;
 
   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));
-  }
+  unix_convert(directory,conn, NULL,&bad_path,NULL);
   
   if (check_name(directory,conn))
-    {
-
-      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)))
-        {
-          /* 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)))
-                   {
-                  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;
-
-                      /* Construct the full name. */
-                      if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
-                        {
-                          errno = ENOMEM;
-                          break;
-                        }
-                      pstrcpy(fullname, directory);
-                      pstrcat(fullname, "/");
-                      pstrcat(fullname, dname);
-                      
-                      if(conn->vfs_ops.lstat(fullname, &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(fullname,False)) != 0)
-                          break;
-                      }
-                      else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
-                        break;
-                    }
-                  CloseDir(dirptr);
-                  /* Retry the rmdir */
-                  ok = (conn->vfs_ops.rmdir(dos_to_unix(directory,False)) == 0);
-                }
-              else
-                CloseDir(dirptr);
-            }
-          else
-            errno = ENOTEMPTY;
-         }
-          
-      if (!ok)
-        DEBUG(3,("couldn't remove directory %s : %s\n",
-                directory,strerror(errno)));
-    }
+  {
+    dptr_closepath(directory,SVAL(inbuf,smb_pid));
+    ok = rmdir_internals(conn, directory);
+  }
   
   if (!ok)
   {
@@ -3251,7 +3516,7 @@ static BOOL can_rename(char *fname,connection_struct *conn)
 
   if (!CAN_WRITE(conn)) return(False);
 
-  if (conn->vfs_ops.lstat(fname,&sbuf) != 0) return(False);
+  if (dos_lstat(fname,&sbuf) != 0) return(False);
   if (!check_file_sharing(conn,fname,True)) return(False);
 
   return(True);
@@ -3275,23 +3540,16 @@ int rename_internals(connection_struct *conn,
        int count=0;
        int error = ERRnoaccess;
        BOOL exists=False;
+       BOOL rc = True;
 
        *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
@@ -3309,7 +3567,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,'?');
@@ -3379,23 +3646,21 @@ int rename_internals(connection_struct *conn,
                         */
                        if(resolve_wildcards(directory,newname) &&
                           can_rename(directory,conn) &&
-                          !conn->vfs_ops.rename(dos_to_unix(directory,False),
-                                                newname))
+                          !dos_rename(directory,newname))
                                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))
+                           !dos_file_exist(newname,NULL) &&
+                           !dos_rename(directory,newname))
                                count++;
                }
 
                DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
                          directory,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)) {
+               if (!count) exists = dos_file_exist(directory,NULL);
+               if (!count && exists && dos_file_exist(newname,NULL)) {
                        exists = True;
                        error = ERRrename;
                }
@@ -3436,13 +3701,13 @@ int rename_internals(connection_struct *conn,
                                        continue;
                                }
                                
-                               if (!replace_if_exists && vfs_file_exist(conn,dos_to_unix(destname,False),NULL)) {
-                                       DEBUG(6,("file_exist %s\n", destname));
+                               if (!replace_if_exists && dos_file_exist(destname,NULL)) {
+                                       DEBUG(6,("dos_file_exist %s\n", destname));
                                        error = 183;
                                        continue;
                                }
                                
-                               if (!conn->vfs_ops.rename(dos_to_unix(fname,False),destname))
+                               if (!dos_rename(fname,destname))
                                        count++;
                                DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
                        }
@@ -3492,14 +3757,16 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
   ******************************************************************/
 
 static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
-                     int count,BOOL target_is_directory)
+                     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) {
     char *p = strrchr(src,'/');
@@ -3511,16 +3778,15 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
     pstrcat(dest,p);
   }
 
-  if (!vfs_file_exist(conn,dos_to_unix(src,False),&st))
+  if (!dos_file_exist(src,&st))
     return(False);
 
   fsp1 = file_new();
-  if (!fsp1) 
+  if (!fsp1)
     return(False);
 
-  open_file_shared(fsp1, conn, src,
-      SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_RDONLY),
-      (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN), 0, 0, &Access, &action);
+  open_file_shared(fsp1,conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
 
   if (!fsp1->open) {
          file_free(fsp1);
@@ -3535,9 +3801,8 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
          close_file(fsp1,False);
          return(False);
   }
-  open_file_shared(fsp2, conn, dest,
-      SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_WRONLY),
-      ofun, st.st_mode, 0, &Access, &action);
+  open_file_shared(fsp2,conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+                  ofun,st.st_mode,0,&Access,&action);
 
   if (!fsp2->open) {
     close_file(fsp1,False);
@@ -3546,7 +3811,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
 
   if ((ofun&3) == 1) {
-    if(conn->vfs_ops.lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) {
+    if(sys_lseek(fsp2->fd_ptr->fd,0,SEEK_END) == -1) {
       DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
                strerror(errno) ));
       /*
@@ -3558,12 +3823,19 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
   }
   
   if (st.st_size)
-    ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0);
+    ret = transfer_file(fsp1->fd_ptr->fd,
+                        fsp2->fd_ptr->fd,st.st_size,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);
 }
 
 
@@ -3580,6 +3852,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   char *p;
   int count=0;
   int error = ERRnoaccess;
+  int err = 0;
   BOOL has_wild;
   BOOL exists=False;
   int tid2 = SVAL(inbuf,smb_vwv0);
@@ -3588,6 +3861,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   BOOL target_is_directory=False;
   BOOL bad_path1 = False;
   BOOL bad_path2 = False;
+  BOOL rc = True;
 
   *directory = *mask = 0;
 
@@ -3602,16 +3876,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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));
-  }
+  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);
 
@@ -3639,7 +3905,16 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     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,'?');
@@ -3649,8 +3924,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     pstrcat(directory,mask);
     if (resolve_wildcards(directory,newname) && 
        copy_file(directory,newname,conn,ofun,
-                 count,target_is_directory)) count++;
-    if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
+                 count,target_is_directory,&err)) count++;
+    if(!count && err) {
+               errno = err;
+               return(UNIXERROR(ERRHRD,ERRgeneral));
+       }
+    if (!count) exists = dos_file_exist(directory,NULL);
   } else {
     void *dirptr = NULL;
     char *dname;
@@ -3659,33 +3938,38 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
     if (check_name(directory,conn))
       dirptr = OpenDir(conn, directory, True);
 
-    if (dirptr)
-      {
+    if (dirptr) {
        error = ERRbadfile;
 
        if (strequal(mask,"????????.???"))
          pstrcpy(mask,"*");
 
-       while ((dname = ReadDirName(dirptr)))
-         {
+       while ((dname = ReadDirName(dirptr))) {
            pstring fname;
            pstrcpy(fname,dname);
            
-           if(!mask_match(fname, mask, case_sensitive, False)) continue;
+           if(!mask_match(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));
          }
        CloseDir(dirptr);
-      }
+    }
   }
   
   if (count == 0) {
+    if(err) {
+      /* Error on close... */
+      errno = err;
+      return(UNIXERROR(ERRHRD,ERRgeneral));
+    }
+
     if (exists)
       return(ERROR(ERRDOS,error));
     else
@@ -3742,9 +4026,149 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
   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;
+}
+
+/****************************************************************************
+ 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
 ****************************************************************************/
+
 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
 {
   files_struct *fsp = file_fsp(inbuf,smb_vwv2);
@@ -3761,6 +4185,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   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);
 
@@ -3771,35 +4197,28 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
    */
   if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
   {
-    int token;
-    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);
-    }
-
-    /* Remove the oplock flag from the sharemode. */
-    lock_share_entry(fsp->conn, dev, inode, &token);
-    if(remove_share_oplock(token, 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));
+no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
 
-           unlock_share_entry(fsp->conn, dev, inode, token);
-    } else {
-           unlock_share_entry(fsp->conn, dev, inode, token);
+      /* 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);
+    }
 
-           /* Clear the granted flag and return. */
-           fsp->granted_oplock = False;
+    if (remove_oplock(fsp) == False) {
+      DEBUG(0,("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 */
@@ -3817,18 +4236,14 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
   /* Data now points at the beginning of the list
      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",
           (double)offset, (double)count, fsp->fsp_name ));
@@ -3847,18 +4262,14 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
      of smb_lkrng structs */
 
   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",
           (double)offset, (double)count, fsp->fsp_name ));
@@ -3882,19 +4293,15 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
      all of the previous locks (X/Open spec). */
   if(i != num_locks && num_locks != 0) {
     for(; 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);
     }
     return ERROR(eclass,ecode);
@@ -3980,7 +4387,8 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
 /****************************************************************************
   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 reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   size_t numtowrite;
   ssize_t nwritten = -1;
@@ -4011,14 +4419,10 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
     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);
 
-  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)
+    sync_file(conn,fsp);
   
   if(nwritten < (ssize_t)numtowrite)
     return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -4056,7 +4460,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
   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) {
     /* we need to send both a primary and a secondary response */
@@ -4116,23 +4520,10 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
   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)
+    sync_file(conn,fsp);
   
   if (nwritten < (ssize_t)numtowrite)
   {
@@ -4172,7 +4563,8 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
 /****************************************************************************
   reply to a SMBsetattrE
 ****************************************************************************/
-int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+
+int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   struct utimbuf unix_times;
   int outsize = 0;
@@ -4224,7 +4616,8 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
 /****************************************************************************
   reply to a SMBgetattrE
 ****************************************************************************/
-int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+
+int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
 {
   SMB_STRUCT_STAT sbuf;
   int outsize = 0;
@@ -4237,7 +4630,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_si
   CHECK_ERROR(fsp);
 
   /* Do an fstat on this file */
-  if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd, &sbuf))
+  if(sys_fstat(fsp->fd_ptr->fd, &sbuf))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   
   mode = dos_mode(conn,fsp->fsp_name,&sbuf);
index bdb2827483eb50735cc56d93bb6a363af9c04ac8..1c6d6536ade0ed5cc4c71ee4438ba64051c3d46e 100644 (file)
@@ -25,9 +25,7 @@
 pstring servicesf = CONFIGFILE;
 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;
 
@@ -49,8 +47,6 @@ extern int dcelogin_atmost_once;
 
 extern fstring remote_machine;
 extern pstring OriginalDir;
-extern pstring myhostname;
-
 
 /****************************************************************************
   when exiting, take the whole family
@@ -76,13 +72,11 @@ static void  killkids(void)
 static BOOL open_sockets_inetd(void)
 {
        extern int Client;
-       extern int ClientPort;
 
        /* Started from inetd. fd 0 is the socket. */
        /* We will abort gracefully when the client or remote system 
           goes away */
        Client = dup(0);
-       ClientPort = SMB_PORT;
        
        /* close our standard file descriptors */
        close_low_fds();
@@ -93,40 +87,19 @@ static BOOL open_sockets_inetd(void)
        return True;
 }
 
-/****************************************************************************
-  open and listen to a socket
-****************************************************************************/
-static int open_server_socket(int port, uint32 ipaddr)
-{
-       int s;
-
-       s = open_socket_in(SOCK_STREAM, port, 0, ipaddr);
-       if(s == -1)
-               return -1;
-               /* ready to listen */
-       if (listen(s, 5) == -1) {
-               DEBUG(0,("listen: %s\n", strerror(errno)));
-               close(s);
-               return -1;
-       }
-       return s;
-}
 
 /****************************************************************************
   open the socket communication
 ****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port,int port445)
+static BOOL open_sockets(BOOL is_daemon,int port)
 {
        extern int Client;
-       extern int ClientPort;
        int num_interfaces = iface_count();
        int fd_listenset[FD_SETSIZE];
        fd_set listen_set;
        int s;
        int i;
 
-       memset(&fd_listenset, 0, sizeof(fd_listenset));
-
        if (!is_daemon) {
                return open_sockets_inetd();
        }
@@ -154,7 +127,7 @@ static BOOL open_sockets(BOOL is_daemon,int port,int port445)
                   socket per interface and bind to only these.
                */
                
-               if(num_interfaces * 2 > FD_SETSIZE) {
+               if(num_interfaces > FD_SETSIZE) {
                        DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
 max can be %d\n", 
                                 num_interfaces, FD_SETSIZE));
@@ -170,11 +143,15 @@ max can be %d\n",
                                DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
                                continue;
                        }
-                       s = fd_listenset[i * 2] = open_server_socket(port, ifip->s_addr);
-                       if(s == -1) return False;
-                       FD_SET(s,&listen_set);
-                       s = fd_listenset[i * 2 + 1] = open_server_socket(port445, ifip->s_addr);
-                       if(s == -1) return False;
+                       s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
+                       if(s == -1)
+                               return False;
+                               /* ready to listen */
+                       if (listen(s, 5) == -1) {
+                               DEBUG(0,("listen: %s\n",strerror(errno)));
+                               close(s);
+                               return False;
+                       }
                        FD_SET(s,&listen_set);
                }
        } else {
@@ -183,18 +160,21 @@ max can be %d\n",
                num_interfaces = 1;
                
                /* open an incoming socket */
-               s = open_server_socket(port, interpret_addr(lp_socket_address()));
+               s = open_socket_in(SOCK_STREAM, port, 0,
+                                  interpret_addr(lp_socket_address()),True);
                if (s == -1)
                        return(False);
+               
+               /* ready to listen */
+               if (listen(s, 5) == -1) {
+                       DEBUG(0,("open_sockets: listen: %s\n",
+                                strerror(errno)));
+                       close(s);
+                       return False;
+               }
+               
                fd_listenset[0] = s;
                FD_SET(s,&listen_set);
-#if 0
-               s = open_server_socket(port445, interpret_addr(lp_socket_address()));
-               if (s == -1)
-                       return(False);
-               fd_listenset[1] = s;
-               FD_SET(s,&listen_set);
-#endif
        } 
 
        /* now accept incoming connections - forking a new process
@@ -207,11 +187,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);
                
                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--) {
@@ -220,24 +203,15 @@ max can be %d\n",
                        
                        s = -1;
                        for(i = 0; i < num_interfaces; i++) {
-                               if(FD_ISSET(fd_listenset[i * 2],&lfds)) {
-                                       s = fd_listenset[i * 2];
-                                       ClientPort = SMB_PORT;
+                               if(FD_ISSET(fd_listenset[i],&lfds)) {
+                                       s = fd_listenset[i];
+                                       /* Clear this so we don't look
+                                          at it again. */
+                                       FD_CLR(fd_listenset[i],&lfds);
                                        break;
                                }
-#if 0
-                               if(FD_ISSET(fd_listenset[i * 2 + 1],&lfds)) {
-                                       s = fd_listenset[i * 2 + 1];
-                                       ClientPort = SMB_PORT2;
-                                       break;
-                               }
-#endif
                        }
 
-                       /* Clear this so we don't look
-                          at it again. */
-                       FD_CLR(s,&lfds);
-
                        Client = accept(s,&addr,&in_addrlen);
                        
                        if (Client == -1 && errno == EINTR)
@@ -357,9 +331,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)
 {
@@ -434,6 +409,8 @@ void exit_server(char *reason)
 
        conn_close_all();
 
+    respond_to_all_remaining_local_messages();
+
 #ifdef WITH_DFS
        if (dcelogin_atmost_once) {
                dfs_unlogin();
@@ -456,13 +433,6 @@ void exit_server(char *reason)
        locking_end();
 
        DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
-#ifdef MEM_MAN
-       {
-               extern FILE *dbf;
-               smb_mem_write_verbose(dbf);
-               dbgflush();
-       }
-#endif
        exit(0);
 }
 
@@ -471,17 +441,34 @@ void exit_server(char *reason)
 /****************************************************************************
   initialise connect, service and file structs
 ****************************************************************************/
-static void init_structs(void)
+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 */
-       if (!init_policy_hnd(MAX_SERVER_POLICY_HANDLES)) 
-       {
-               exit_server("could not allocate policy handles\n");
-       }
+
+       /* for RPC pipes */
+       init_rpc_pipe_hnd();
+
+       /* for LSA handles */
+       init_lsa_policy_hnd();
+
        init_dptrs();
-       init_dfs_table();
 }
 
 /****************************************************************************
@@ -489,19 +476,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] [-i scope]\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");
 }
@@ -516,7 +505,6 @@ static void usage(char *pname)
        /* shall I run as a daemon */
        BOOL is_daemon = False;
        int port = SMB_PORT;
-       int port445 = SMB_PORT2;
        int opt;
        extern char *optarg;
        
@@ -524,55 +512,13 @@ 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 */
-#ifdef HAVE_SETRESUID
-       setresuid(0,0,0);
-#else
-       setuid(0);
-       seteuid(0);
-       setuid(0);
-       seteuid(0);
-#endif
-
-       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:i:l:s:d:Dp:h?VPaof:")) )
                switch (opt)  {
                case 'O':
                        pstrcpy(user_socket_options,optarg);
@@ -626,11 +572,72 @@ 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();
+
+       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));
@@ -644,13 +651,15 @@ static void usage(char *pname)
                exit(1);
        }
 
-       get_myname(myhostname,NULL);
+       /*
+        * Do this before reload_services.
+        */
 
        if (!reload_services(False))
                return(-1);     
 
        init_structs();
-
+       
 #ifdef WITH_PROFILE
        if (!profile_setup(False)) {
                DEBUG(0,("ERROR: failed to setup profiling\n"));
@@ -658,16 +667,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;
@@ -679,40 +678,10 @@ static void usage(char *pname)
 
        codepage_initialise(lp_client_code_page());
 
-       if (!pwdb_initialise(True))
-       {
-               exit(1);
-       }
-
-       if(!initialise_sam_password_db())
-       {
-               exit(1);
-       }
-
-       if(!initialise_passgrp_db())
-       {
-               exit(1);
-       }
+       fstrcpy(global_myworkgroup, lp_workgroup());
 
-       if(!initialise_group_db())
-       {
-               exit(1);
-       }
-
-       if(!initialise_alias_db())
-       {
-               exit(1);
-       }
-
-       if(!initialise_builtin_db())
-       {
-               exit(1);
-       }
-
-       if (!get_member_domain_sid())
-       {
-               DEBUG(0,("ERROR: Samba cannot obtain PDC SID from PDC(s) %s.\n",
-                         lp_passwordserver()));
+       if(!pdb_generate_sam_sid()) {
+               DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
                exit(1);
        }
 
@@ -746,7 +715,7 @@ static void usage(char *pname)
                become_daemon();
        }
 
-       check_kernel_oplocks();
+    check_kernel_oplocks();
 
        if (!directory_exist(lp_lockdir(), NULL)) {
                mkdir(lp_lockdir(), 0755);
@@ -756,10 +725,13 @@ static void usage(char *pname)
                pidfile_create("smbd");
        }
 
-       if (!open_sockets(is_daemon,port,port445))
+       if (!locking_init(0))
                exit(1);
 
-       if (!locking_init(0))
+       if (!open_sockets(is_daemon,port))
+               exit(1);
+
+       if(!initialize_password_db())
                exit(1);
 
        /* possibly reload the services file. */
index 64abf3de1dd2b4bb823ae61b88b0e28d4b064097..92807e2d43902bf13328a5a46103e8e7012730b0 100644 (file)
@@ -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;
@@ -49,7 +49,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);
   
@@ -84,24 +84,23 @@ int find_service(char *service)
 {
    int iService;
 
-   string_sub(service,"\\","/");
+   all_string_sub(service,"\\","/",0);
 
    iService = lp_servicenumber(service);
 
    /* now handle the special case of a home directory */
    if (iService < 0)
    {
-      char *phome_dir = get_unixhome_dir(service);
-       pstring home_dir;
+      char *phome_dir = get_user_home_dir(service);
 
-      if(phome_dir == NULL)
+      if(!phome_dir)
       {
         /*
          * Try mapping the servicename, it may
          * be a Windows to unix mapped user name.
          */
         if(map_username(service))
-          phome_dir = get_unixhome_dir(service);
+          phome_dir = get_user_home_dir(service);
       }
 
       DEBUG(3,("checking for home directory %s gave %s\n",service,
@@ -110,10 +109,9 @@ int find_service(char *service)
       if (phome_dir)
       {   
         int iHomeService;
-       pstrcpy(home_dir, phome_dir);
         if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
         {
-          lp_add_home(service,iHomeService,home_dir);
+          lp_add_home(service,iHomeService,phome_dir);
           iService = lp_servicenumber(service);
         }
       }
@@ -144,11 +142,6 @@ int find_service(char *service)
       }
    }
 
-   /* Check for default vfs service?  Unsure whether to implement this */
-   if (iService < 0)
-   {
-   }
-
    /* just possibly it's a default service? */
    if (iService < 0) 
    {
@@ -168,7 +161,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);
        }
      }
@@ -194,11 +187,12 @@ int find_service(char *service)
 connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode)
 {
        int snum;
-       const struct passwd *pass = NULL;
+       struct passwd *pass = NULL;
        BOOL guest = False;
        BOOL force = False;
        extern int Client;
        connection_struct *conn;
+       int ret;
 
        strlower(service);
 
@@ -218,21 +212,31 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        }
 
        if (strequal(service,HOMES_NAME)) {
-               if (*user && Get_Pwnam(user,True))
-                       return(make_connection(user,user,password,
+               if (*user && Get_Pwnam(user,True)) {
+                       fstring dos_username;
+                       fstrcpy(dos_username, user);
+                       unix_to_dos(dos_username, True);
+                       return(make_connection(dos_username,user,password,
                                               pwlen,dev,vuid,ecode));
+               }
 
                if(lp_security() != SEC_SHARE) {
                        if (validated_username(vuid)) {
-                               pstrcpy(user,validated_username(vuid));
-                               return(make_connection(user,user,password,pwlen,dev,vuid,ecode));
+                               fstring dos_username;
+                               fstrcpy(user,validated_username(vuid));
+                               fstrcpy(dos_username, user);
+                               unix_to_dos(dos_username, True);
+                               return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
                        }
                } else {
                        /* Security = share. Try with sesssetup_user
                         * as the username.  */
                        if(*sesssetup_user) {
-                               pstrcpy(user,sesssetup_user);
-                               return(make_connection(user,user,password,pwlen,dev,vuid,ecode));
+                               fstring dos_username;
+                               fstrcpy(user,sesssetup_user);
+                               fstrcpy(dos_username, user);
+                               unix_to_dos(dos_username, True);
+                               return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
                        }
                }
        }
@@ -300,13 +304,13 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        {
                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;    
@@ -333,6 +337,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        conn->vuid = vuid;
        conn->uid = pass->pw_uid;
        conn->gid = pass->pw_gid;
+       safe_strcpy(conn->client_address, client_addr(Client), sizeof(conn->client_address)-1);
        conn->num_files_open = 0;
        conn->lastused = time(NULL);
        conn->service = snum;
@@ -345,65 +350,83 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        conn->veto_oplock_list = NULL;
        string_set(&conn->dirpath,"");
        string_set(&conn->user,user);
+       
+       /*
+        * 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)) {
+               struct passwd *pass2;
+               pstring fuser;
+               pstrcpy(fuser,lp_force_user(snum));
 
-       /* Initialise VFS function pointers */
-
-       if (*lp_vfsobj(SNUM(conn))) {
-
-#ifdef HAVE_LIBDL
-
-           /* Loadable object file */
-
-           if (!vfs_init_custom(conn)) {
-               return NULL;
-           }
-#else
-           DEBUG(0, ("No libdl present - cannot use VFS objects\n"));
-           conn_free(conn);
-           return NULL;
-#endif
-
-       } else {
-
-           /* Normal share - initialise with disk access functions */
+               /* Allow %S to be used by force user. */
+               pstring_sub(fuser,"%S",service);
 
-           vfs_init_default(conn);
+               pass2 = (struct passwd *)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) {
-                       conn->gid = gptr->gr_gid;
-                       DEBUG(3,("Forced group %s\n",gname));
+                       /*
+                        * 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 for member %s\n",gname,user));
+                                               break;
+                                       }
+                               }
+                       } else {
+                               conn->gid = gptr->gr_gid;
+                               DEBUG(3,("Forced group %s\n",gname));
+                       }
                } else {
                        DEBUG(1,("Couldn't find group %s\n",gname));
                }
        }
-#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));
-               }
-       }
+#endif /* HAVE_GETGRNAM */
 
        {
                pstring s;
@@ -420,7 +443,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
        if (!IS_IPC(conn)) {
                /* Find all the groups this uid is in and
                   store them. Used by become_user() */
-               get_unixgroups(conn->user,conn->uid,conn->gid,
+               setup_groups(conn->user,conn->uid,conn->gid,
                             &conn->ngroups,&conn->groups);
                
                /* check number of connections */
@@ -445,7 +468,13 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
                standard_sub(conn,cmd);
                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)) {
@@ -499,7 +528,26 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                pstring cmd;
                pstrcpy(cmd,lp_preexec(SNUM(conn)));
                standard_sub(conn,cmd);
-               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 */
@@ -512,61 +560,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn)));
        }
        
-       if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
-               extern int Client;
-               
-               dbgtext( "%s (%s) ", remote_machine, client_addr(Client) );
-               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)getpid() );
-       }
-
-       /* Invoke 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 *)malloc(conn->ngroups * sizeof(gid_t));
-           if (vconn->groups != NULL) {
-               memcpy(vconn->groups, conn->groups, 
-                      conn->ngroups * sizeof(gid_t));
-           }
-
-           /* Call connect hook */
-           
-           if (conn->vfs_ops.connect(vconn, service, user) < 0) {
-               return NULL;
-           }
-       }
-       
        return(conn);
 }
 
@@ -576,31 +569,14 @@ close a cnum
 ****************************************************************************/
 void close_cnum(connection_struct *conn, uint16 vuid)
 {
-       extern int Client;
        DirCacheFlush(SNUM(conn));
 
        unbecome_user();
 
        DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
-                                remote_machine,client_addr(Client),
+                                remote_machine,conn->client_address,
                                 lp_servicename(SNUM(conn))));
 
-       if (conn->vfs_ops.disconnect != NULL) {
-
-           /* Call disconnect hook */
-           
-           conn->vfs_ops.disconnect();
-           
-           /* Free vfs_connection_struct */
-           
-           if (conn->vfs_conn != NULL) {
-               if (conn->vfs_conn->groups != NULL) {
-                   free(conn->vfs_conn->groups);
-               }
-               free(conn->vfs_conn);
-           }
-       }
-
        yield_connection(conn,
                         lp_servicename(SNUM(conn)),
                         lp_max_connections(SNUM(conn)));
@@ -632,5 +608,3 @@ void close_cnum(connection_struct *conn, uint16 vuid)
        
        conn_free(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 14fa26dd5595862bad3dec46aae1e7373ad6ae85..e971f8bbb689e57e5e973cfa51b77f577b9e1256 100644 (file)
@@ -31,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.
@@ -113,8 +113,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
     SSVAL(outbuf,smb_prcnt, params_sent_thistime);
     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_proff,0);
       SSVAL(outbuf,smb_prdisp,0);
     }
     else
@@ -216,11 +215,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)
@@ -253,7 +248,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
 
-  if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+  if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
     close_file(fsp,False);
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   }
@@ -272,7 +267,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
   if(params == NULL)
     return(ERROR(ERRDOS,ERRnomem));
 
-  bzero(params,28);
+  memset((char *)params,'\0',28);
   SSVAL(params,0,fsp->fnum);
   SSVAL(params,2,fmode);
   put_dos_date2(params,4, mtime);
@@ -298,12 +293,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;
@@ -329,6 +324,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);
@@ -346,6 +342,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);
@@ -367,7 +365,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)
@@ -380,7 +397,7 @@ static int get_lanman2_dir_entry(connection_struct *conn,
       if(needslash)
         pstrcat(pathreal,"/");
       pstrcat(pathreal,dname);
-      if (conn->vfs_ops.stat(dos_to_unix(pathreal,False),&sbuf) != 0) 
+      if (dos_stat(pathreal,&sbuf) != 0) 
       {
         DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
         continue;
@@ -406,7 +423,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;
@@ -502,7 +519,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;
@@ -579,6 +596,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);
 }
   
@@ -610,8 +628,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)
@@ -669,11 +688,7 @@ static int call_trans2findfirst(connection_struct *conn,
 
   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)
     {
@@ -708,40 +723,25 @@ static int call_trans2findfirst(connection_struct *conn,
   pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
   if(!*ppdata)
     return(ERROR(ERRDOS,ERRnomem));
-  bzero(pdata,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));
   }
 
@@ -763,39 +763,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 - 
@@ -803,7 +813,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. */
 
@@ -823,6 +836,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);
 }
 
@@ -843,7 +867,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);
@@ -891,7 +915,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));
-  bzero(pdata,max_data_bytes);
+  memset((char *)pdata,'\0',max_data_bytes + 1024);
 
   /* Realloc the params space */
   params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
@@ -968,7 +992,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))
       {
@@ -996,7 +1020,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))
         {
@@ -1009,38 +1033,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 */
@@ -1070,6 +1105,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);
@@ -1078,16 +1114,16 @@ 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));
 
-  if(conn->vfs_ops.stat(".",&st)!=0) {
+  if(dos_stat(".",&st)!=0) {
     DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
     return (ERROR(ERRSRV,ERRinvdevice));
   }
 
-  pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
+  pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
+  memset((char *)pdata,'\0',max_data_bytes + 1024);
 
   switch (info_level) 
   {
@@ -1095,7 +1131,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);       
+      sys_disk_free(".",False,&bsize,&dfree,&dsize);   
       SIVAL(pdata,l1_idFileSystem,st.st_dev);
       SIVAL(pdata,l1_cSectorUnit,bsize/512);
       SIVAL(pdata,l1_cUnit,dsize);
@@ -1124,16 +1160,21 @@ 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|
+            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)/2);
+      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));
@@ -1158,19 +1199,19 @@ static int call_trans2qfsinfo(connection_struct *conn,
       } 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)/2);      
       }
 
       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);
+      sys_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;
@@ -1236,6 +1277,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);
@@ -1256,20 +1298,17 @@ 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) && dos_stat(fname,&sbuf))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1278,6 +1317,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.
@@ -1286,11 +1328,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       CHECK_ERROR(fsp);
 
       fname = fsp->fsp_name;
-      if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+      if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
-      if((pos = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
+      if((pos = sys_lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
         return(UNIXERROR(ERRDOS,ERRnoaccess));
 
       delete_pending = fsp->fd_ptr->delete_on_close;
@@ -1298,16 +1340,13 @@ 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));
-       }
-    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) && dos_stat(fname,&sbuf))) {
       DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1335,8 +1374,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); bzero(params,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) {
@@ -1345,7 +1385,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
     return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
   }
 
-  bzero(pdata,data_size);
+  memset((char *)pdata,'\0',data_size);
 
   switch (info_level) 
     {
@@ -1416,26 +1456,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)*2);
+        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)*2);
+      } else {
+        pstrcpy(pdata+4,fname);
+      }
       data_size = 4 + l;
       SIVAL(pdata,0,l);
-      pstrcpy(pdata+4,fname);
       break;
 
     case SMB_QUERY_FILE_ALLOCATION_INFO:
@@ -1527,20 +1578,15 @@ 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) && dos_stat(fname,&st))) {
         DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
         if((errno == ENOENT) && bad_path)
         {
@@ -1559,7 +1605,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       fname = fsp->fsp_name;
       fd = fsp->fd_ptr->fd;
 
-      if (fsp->conn->vfs_ops.fstat(fd,&st) != 0) {
+      if (sys_fstat(fd,&st) != 0) {
         DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
         return(UNIXERROR(ERRDOS,ERRbadfid));
       }
@@ -1569,11 +1615,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)
@@ -1584,7 +1626,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       return(UNIXERROR(ERRDOS,ERRbadpath));
     }
  
-    if(!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st)!=0) {
+    if(!VALID_STAT(st) && dos_stat(fname,&st)!=0) {
       DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
       if((errno == ENOENT) && bad_path)
       {
@@ -1599,10 +1641,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;
@@ -1656,7 +1700,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
       tvs.actime = interpret_long_date(pdata+8);
 
       /* write time + changed time, combined. */
-      tvs.modtime=MAX(interpret_long_date(pdata+16),
+      tvs.modtime=MIN(interpret_long_date(pdata+16),
                       interpret_long_date(pdata+24));
 
 #if 0 /* Needs more testing... */
@@ -1672,6 +1716,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);
@@ -1681,12 +1745,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))
@@ -1694,121 +1756,134 @@ 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 token;
-            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, &token) == 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, token, 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 token;
+              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, &token) == 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, token, 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, token);
+                  unlock_share_entry(fsp->conn, dev, inode, token);
 
-                /*
-                 * 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(token, iterate_fsp, new_share_mode)==False)
-                DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+                if(modify_share_mode(token, 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, token);
+              /*
+               * 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, token);
 
-          } /* 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;
@@ -1820,23 +1895,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
@@ -1844,38 +1929,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"));
+  if(size != st.st_size) {
+
+    DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
+          fname, (double)size ));
+
+    if (fd == -1) {
       fd = dos_open(fname,O_RDWR,0);
       if (fd == -1)
-      {
         return(UNIXERROR(ERRDOS,ERRbadpath));
-      }
       set_filelen(fd, size);
       close(fd);
-    }
-    else
-    {
+    } else {
       set_filelen(fd, size);
     }
+
+    if(fsp)
+      set_filelen_write_cache(fsp, size);
   }
 
   SSVAL(params,0,0);
@@ -1904,14 +2002,9 @@ 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));
+    ret = dos_mkdir(directory,unix_mode(conn,aDIR));
   
   if(ret < 0)
     {
@@ -2012,11 +2105,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);
 
@@ -2049,237 +2142,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); 
-       bzero(*ppdata, 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!
@@ -2410,104 +2272,73 @@ 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;
+       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
@@ -2525,4 +2356,3 @@ int reply_trans2(connection_struct *conn,
                           call_trans2xxx calls have already sent
                           it. If outsize != -1 then it is returning */
 }
-
index 3501879d5fcd537c9f9ca53877eb9c588c07dadc..ce0631e418a26b48a5d740006b657b7564f9df5c 100644 (file)
 
 extern int DEBUGLEVEL;
 
-static uid_t initial_uid;
-static gid_t initial_gid;
-static struct uid_cache vcache;
-
 /* what user is current? */
 extern struct current_user current_user;
 
 pstring OriginalDir;
 
 /****************************************************************************
-initialise the uid routines
+ Initialise the uid routines.
 ****************************************************************************/
+
 void init_uid(void)
 {
-       initial_uid = current_user.uid = geteuid();
-       initial_gid = current_user.gid = getegid();
-
-       if (initial_gid != 0 && initial_uid == 0) {
-#ifdef HAVE_SETRESUID
-               setresgid(0,0,0);
-#else
-               setgid(0);
-               setegid(0);
-#endif
-       }
+       current_user.uid = geteuid();
+       current_user.gid = getegid();
 
-       initial_uid = geteuid();
-       initial_gid = getegid();
+       if (current_user.gid != 0 && current_user.uid == 0) {
+               gain_root_group_privilege();
+       }
 
        current_user.conn = NULL;
        current_user.vuid = UID_FIELD_INVALID;
        
-       vcache.entries = 0;
-
        dos_ChDir(OriginalDir);
 }
 
-
 /****************************************************************************
-  become the specified uid 
+ Become the specified uid.
 ****************************************************************************/
+
 static BOOL become_uid(uid_t uid)
 {
-       if (initial_uid != 0) {
-               return(True);
-       }
-       
        if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
                static int done;
                if (!done) {
@@ -78,98 +61,53 @@ static BOOL become_uid(uid_t uid)
                }
        }
 
-#ifdef HAVE_TRAPDOOR_UID
-#ifdef HAVE_SETUIDX
-       /* AIX3 has setuidx which is NOT a trapoor function (tridge) */
-       if (setuidx(ID_EFFECTIVE, uid) != 0) {
-               if (seteuid(uid) != 0) {
-                       DEBUG(1,("Can't set uid %d (setuidx)\n", (int)uid));
-                       return False;
-               }
-       }
-#endif
-#endif
-
-#ifdef HAVE_SETRESUID
-    if (setresuid(-1,uid,-1) != 0)
-#else
-    if ((seteuid(uid) != 0) && 
-       (setuid(uid) != 0))
-#endif
-      {
-       DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
-                (int)uid,(int)getuid(), (int)geteuid()));
-       if (uid > (uid_t)32000) {
-               DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
-       }
-       return(False);
-      }
-
-    if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) && (geteuid() != uid)) {
-           DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
-           return(False);
-    }
+       set_effective_uid(uid);
 
-    current_user.uid = uid;
+       current_user.uid = uid;
 
 #ifdef WITH_PROFILE
-    profile_p->uid_changes++;
+       profile_p->uid_changes++;
 #endif
 
-    return(True);
+       return(True);
 }
 
 
 /****************************************************************************
-  become the specified gid
+ Become the specified gid.
 ****************************************************************************/
+
 static BOOL become_gid(gid_t gid)
 {
-  if (initial_uid != 0)
-    return(True);
-
-  if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) {
-    DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid));    
-  }
-  
-#ifdef HAVE_SETRESUID
-  if (setresgid(-1,gid,-1) != 0)
-#else
-  if (setgid(gid) != 0)
-#endif
-      {
-       DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
-                (int)gid,(int)getgid(),(int)getegid()));
-       if (gid > 32000) {
-               DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
+       if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) {
+               DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid));    
        }
-       return(False);
-      }
-
-  current_user.gid = gid;
-
-  return(True);
+  
+       set_effective_gid(gid);
+       
+       current_user.gid = gid;
+       
+       return(True);
 }
 
 
 /****************************************************************************
-  become the specified uid and gid
+ Become the specified uid and gid.
 ****************************************************************************/
+
 static BOOL become_id(uid_t uid,gid_t gid)
 {
        return(become_gid(gid) && become_uid(uid));
 }
 
 /****************************************************************************
-become the guest user
+ Become the guest user.
 ****************************************************************************/
+
 BOOL become_guest(void)
 {
   BOOL ret;
-  static const struct passwd *pass=NULL;
-
-  if (initial_uid != 0) 
-    return(True);
+  static struct passwd *pass=NULL;
 
   if (!pass)
     pass = Get_Pwnam(lp_guestaccount(-1),True);
@@ -193,138 +131,43 @@ BOOL become_guest(void)
 }
 
 /*******************************************************************
-check if a username is OK
+ Check if a username is OK.
 ********************************************************************/
-static BOOL check_vuser_ok(struct uid_cache *cache, user_struct *vuser,int snum)
+
+static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
 {
   int i;
-  for (i=0;i<cache->entries;i++)
-    if (cache->list[i] == vuser->uid) return(True);
+  for (i=0;i<conn->uid_cache.entries;i++)
+    if (conn->uid_cache.list[i] == vuser->uid) return(True);
 
   if (!user_ok(vuser->name,snum)) return(False);
 
-  i = cache->entries % UID_CACHE_SIZE;
-  cache->list[i] = vuser->uid;
+  i = conn->uid_cache.entries % UID_CACHE_SIZE;
+  conn->uid_cache.list[i] = vuser->uid;
 
-  if (cache->entries < UID_CACHE_SIZE)
-    cache->entries++;
+  if (conn->uid_cache.entries < UID_CACHE_SIZE)
+    conn->uid_cache.entries++;
 
   return(True);
 }
 
 
 /****************************************************************************
-  become the user of a connection number
-****************************************************************************/
-BOOL become_vuser(uint16 vuid)
-{
-       user_struct *vuser = get_valid_user_struct(vuid);
-       gid_t gid;
-       uid_t uid;
-
-       unbecome_vuser();
-
-       if((vuser != NULL) && !check_vuser_ok(&vcache, vuser, -1))
-               return False;
-
-       if ( vuser != 0 &&
-            current_user.vuid == vuid && 
-            current_user.uid  == vuser->uid)
-       {
-               DEBUG(4,("Skipping become_vuser - already user\n"));
-               return(True);
-       }
-       uid = vuser->uid;
-       gid = vuser->gid;
-       current_user.ngroups = vuser->n_groups;
-       current_user.groups  = vuser->groups;
-       
-       if (initial_uid == 0)
-       {
-               if (!become_gid(gid)) return(False);
-
-#ifdef HAVE_SETGROUPS      
-               /* groups stuff added by ih/wreu */
-               if (current_user.ngroups > 0)
-               {
-                       if (setgroups(current_user.ngroups,
-                                     current_user.groups)<0) {
-                               DEBUG(0,("setgroups call failed!\n"));
-                       }
-               }
-#endif
-
-               if (!become_uid(uid)) return(False);
-       }
-       
-       current_user.conn = NULL;
-       current_user.vuid = vuid;
-
-       DEBUG(5,("become_vuser uid=(%d,%d) gid=(%d,%d)\n",
-                (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
-  
-       return(True);
-}
-
-/****************************************************************************
-  unbecome a user 
+ Become the user of a connection number.
 ****************************************************************************/
-BOOL unbecome_vuser(void)
-{
-  dos_ChDir(OriginalDir);
-
-  if (initial_uid == 0)
-    {
-#ifdef HAVE_SETRESUID
-      setresuid(-1,getuid(),-1);
-      setresgid(-1,getgid(),-1);
-#else
-      if (seteuid(initial_uid) != 0) 
-       setuid(initial_uid);
-      setgid(initial_gid);
-#endif
-    }
-
-#ifdef NO_EID
-  if (initial_uid == 0)
-    DEBUG(2,("Running with no EID\n"));
-  initial_uid = getuid();
-  initial_gid = getgid();
-#else
-  if (geteuid() != initial_uid) {
-         DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
-         initial_uid = geteuid();
-  }
-  if (getegid() != initial_gid) {
-         DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
-         initial_gid = getegid();
-  }
-#endif
 
-  current_user.uid = initial_uid;
-  current_user.gid = initial_gid;
-  
-  if (dos_ChDir(OriginalDir) != 0)
-    DEBUG( 0, ( "chdir(%s) failed in unbecome_vuser\n", OriginalDir ) );
-
-  DEBUG(5,("unbecome_vuser now uid=(%d,%d) gid=(%d,%d)\n",
-       (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
-
-  current_user.conn = NULL;
-  current_user.vuid = UID_FIELD_INVALID;
-
-  return(True);
-}
-
-/****************************************************************************
-  become the user of a connection number
-****************************************************************************/
 BOOL become_user(connection_struct *conn, uint16 vuid)
 {
        user_struct *vuser = get_valid_user_struct(vuid);
        int snum;
-       gid_t gid;
+    gid_t gid;
        uid_t uid;
+       char group_c;
+
+       if (!conn) {
+               DEBUG(2,("Connection not open\n"));
+               return(False);
+       }
 
        /*
         * We need a separate check in security=share mode due to vuid
@@ -346,14 +189,9 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
 
        unbecome_user();
 
-       if (!conn) {
-               DEBUG(2,("Connection not open\n"));
-               return(False);
-       }
-
        snum = SNUM(conn);
 
-       if((vuser != NULL) && !check_vuser_ok(&conn->uid_cache, vuser, snum))
+       if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
                return False;
 
        if (conn->force_user || 
@@ -369,32 +207,55 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
                        return(False);
                }
                uid = vuser->uid;
-               if(!*lp_force_group(snum)) {
-                       gid = vuser->gid;
+               gid = vuser->gid;
+               current_user.ngroups = vuser->n_groups;
+               current_user.groups  = vuser->groups;
+       }
+
+       /*
+        * See if we should force group for this service.
+        * If so this overrides any group set in the force
+        * user code.
+        */
+
+       if((group_c = *lp_force_group(snum))) {
+               if(group_c == '+') {
+
+                       /*
+                        * Only force group if the user is a member of
+                        * the service group. Check the group memberships for
+                        * this user (we already have this) to
+                        * see if we should force the group.
+                        */
+
+                       int i;
+                       for (i = 0; i < current_user.ngroups; i++) {
+                               if (current_user.groups[i] == conn->gid) {
+                                       gid = conn->gid;
+                                       break;
+                               }
+                       }
                } else {
                        gid = conn->gid;
                }
-               current_user.ngroups = vuser->n_groups;
-               current_user.groups  = vuser->groups;
        }
        
-       if (initial_uid == 0)  {
-               if (!become_gid(gid)) return(False);
+       if (!become_gid(gid))
+               return(False);
 
 #ifdef HAVE_SETGROUPS      
-               if (!(conn && conn->ipc)) {
-                       /* groups stuff added by ih/wreu */
-                       if (current_user.ngroups > 0)
-                               if (setgroups(current_user.ngroups,
-                                             current_user.groups)<0) {
-                                       DEBUG(0,("setgroups call failed!\n"));
-                               }
-               }
+       if (!(conn && conn->ipc)) {
+               /* groups stuff added by ih/wreu */
+               if (current_user.ngroups > 0)
+                       if (sys_setgroups(current_user.ngroups,
+                                     current_user.groups)<0) {
+                               DEBUG(0,("sys_setgroups call failed!\n"));
+                       }
+       }
 #endif
 
-               if (!conn->admin_user && !become_uid(uid))
-                       return(False);
-       }
+       if (!conn->admin_user && !become_uid(uid))
+               return(False);
        
        current_user.conn = conn;
        current_user.vuid = vuid;
@@ -406,56 +267,83 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
 }
 
 /****************************************************************************
-  unbecome the user of a connection number
+ Unbecome the user of a connection number.
 ****************************************************************************/
+
 BOOL unbecome_user(void )
 {
-  if (!current_user.conn)
-    return(False);
-
-  dos_ChDir(OriginalDir);
-
-  if (initial_uid == 0)
-    {
-#ifdef HAVE_SETRESUID
-      setresuid(-1,getuid(),-1);
-      setresgid(-1,getgid(),-1);
-#else
-      if (seteuid(initial_uid) != 0) 
-       setuid(initial_uid);
-      setgid(initial_gid);
-#endif
-    }
-
-#ifdef NO_EID
-  if (initial_uid == 0)
-    DEBUG(2,("Running with no EID\n"));
-  initial_uid = getuid();
-  initial_gid = getgid();
-#else
-  if (geteuid() != initial_uid) {
-         DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
-         initial_uid = geteuid();
-  }
-  if (getegid() != initial_gid) {
-         DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
-         initial_gid = getegid();
-  }
-#endif
+       if (!current_user.conn)
+               return(False);
+
+       dos_ChDir(OriginalDir);
 
-  current_user.uid = initial_uid;
-  current_user.gid = initial_gid;
+       set_effective_uid(0);
+       set_effective_gid(0);
+
+       if (geteuid() != 0) {
+               DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
+       }
+       if (getegid() != 0) {
+               DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
+       }
+
+       current_user.uid = 0;
+       current_user.gid = 0;
   
-  if (dos_ChDir(OriginalDir) != 0)
-    DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) );
+       if (dos_ChDir(OriginalDir) != 0)
+               DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) );
 
-  DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
-       (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
+       DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
+               (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
 
-  current_user.conn = NULL;
-  current_user.vuid = UID_FIELD_INVALID;
+       current_user.conn = NULL;
+       current_user.vuid = UID_FIELD_INVALID;
 
-  return(True);
+       return(True);
+}
+
+/****************************************************************************
+ Become the user of an authenticated connected named pipe.
+ When this is called we are currently running as the connection
+ user.
+****************************************************************************/
+
+BOOL become_authenticated_pipe_user(pipes_struct *p)
+{
+       /*
+        * Go back to root.
+        */
+
+       if(!unbecome_user())
+               return False;
+
+       /*
+        * Now become the authenticated user stored in the pipe struct.
+        */
+
+       if(!become_id(p->uid, p->gid)) {
+               /* Go back to the connection user. */
+               become_user(p->conn, p->vuid);
+               return False;
+       }
+
+       return True;     
+}
+
+/****************************************************************************
+ Unbecome the user of an authenticated connected named pipe.
+ When this is called we are running as the authenticated pipe
+ user and need to go back to being the connection user.
+****************************************************************************/
+
+BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
+{
+       if(!become_id(0,0)) {
+               DEBUG(0,("unbecome_authenticated_pipe_user: Unable to go back to root.\n"));
+               return False;
+       }
+
+       return become_user(p->conn, p->vuid);
 }
 
 static struct current_user current_user_saved;
@@ -463,13 +351,14 @@ static int become_root_depth;
 static pstring become_root_dir;
 
 /****************************************************************************
-This is used when we need to do a privilaged operation (such as mucking
+This is used when we need to do a privileged operation (such as mucking
 with share mode files) and temporarily need root access to do it. This
 call should always be paired with an unbecome_root() call immediately
 after the operation
 
 Set save_dir if you also need to save/restore the CWD 
 ****************************************************************************/
+
 void become_root(BOOL save_dir) 
 {
        if (become_root_depth) {
@@ -486,10 +375,11 @@ void become_root(BOOL save_dir)
 }
 
 /****************************************************************************
-When the privilaged operation is over call this
+When the privileged operation is over call this
 
 Set save_dir if you also need to save/restore the CWD 
 ****************************************************************************/
+
 void unbecome_root(BOOL restore_dir)
 {
        if (become_root_depth != 1) {
@@ -512,9 +402,9 @@ void unbecome_root(BOOL restore_dir)
 
 #ifdef HAVE_SETGROUPS      
        if (current_user_saved.ngroups > 0) {
-               if (setgroups(current_user_saved.ngroups,
+               if (sys_setgroups(current_user_saved.ngroups,
                              current_user_saved.groups)<0)
-                       DEBUG(0,("ERROR: setgroups call failed!\n"));
+                       DEBUG(0,("ERROR: sys_setgroups call failed!\n"));
        }
 #endif
 
@@ -531,5 +421,3 @@ void unbecome_root(BOOL restore_dir)
 
        become_root_depth = 0;
 }
-
-
index a38703ee7eabd67e8763c1e869fcd8ddf5d6a4d5..251c26733726a9b61b4f3193a1c0ab463f412d0f 100644 (file)
@@ -58,8 +58,6 @@
 #elif HAVE___OPEN64
 #define real_open64(fn,flags,mode)     (__open64(fn,flags,mode))
 #define NO_OPEN64_ALIAS
-#else
-#error No open64() wrapper
 #endif
 
 #ifdef HAVE__FORK
@@ -68,8 +66,6 @@
 #define real_fork()                    (__fork())
 #elif SYS_fork
 #define real_fork()            (syscall(SYS_fork))
-#else
-#error No fork() wrapper
 #endif
 
 #ifdef HAVE__OPENDIR
@@ -78,8 +74,6 @@
 #define real_opendir(fn)               (syscall(SYS_opendir,(fn)))
 #elif HAVE___OPENDIR
 #define real_opendir(fn)               (__opendir(fn))
-#else
-#error No opendir() wrapper
 #endif
 
 #ifdef HAVE__READDIR
@@ -88,8 +82,6 @@
 #define real_readdir(d)                (__readdir(d))
 #elif SYS_readdir
 #define real_readdir(d)                (syscall(SYS_readdir,(d)))
-#else
-#error No readdir() wrapper
 #endif
 
 #ifdef HAVE__CLOSEDIR
@@ -98,8 +90,6 @@
 #define real_closedir(d)               (syscall(SYS_closedir,(d)))
 #elif HAVE___CLOSEDIR
 #define real_closedir(d)               (__closedir(d))
-#else
-#error No closedir() wrapper
 #endif
 
 #ifdef HAVE__SEEKDIR
 #define real_seekdir(d,l)              (__seekdir(d,l))
 #else
 #define NO_SEEKDIR_WRAPPER
-#error No seekdir() wrapper
 #endif
 
 #ifdef HAVE__TELLDIR
 #define real_telldir(d)                (syscall(SYS_telldir,(d)))
 #elif HAVE___TELLDIR
 #define real_telldir(d)                (__telldir(d))
-#else
-#error No telldir() wrapper
 #endif
 
 #ifdef HAVE__DUP
 #define real_dup(d)            (syscall(SYS_dup,(d)))
 #elif HAVE___DUP
 #define real_dup(d)                    (__dup(d))
-#else
-#error No dup() wrapper
 #endif
 
 #ifdef HAVE__DUP2
 #define real_dup2(d1,d2)               (syscall(SYS_dup2,(d1),(d2)))
 #elif HAVE___DUP2
 #define real_dup2(d1,d2)               (__dup2(d1,d2))
-#else
-#error No dup2() wrapper
 #endif
 
 #ifdef HAVE__GETCWD
 #define real_getcwd(b,s)               ((char *)syscall(SYS_getcwd,(b),(s)))
 #elif HAVE___GETCWD
 #define real_getcwd(b,s)               ((char *)__getcwd(b,s))
-#else
-#error No getcwd() wrapper
 #endif
 
 #ifdef HAVE__STAT
 #define real_stat(fn,st)               (syscall(SYS_stat,(fn),(st)))
 #elif HAVE___STAT
 #define real_stat(fn,st)               (__stat(fn,st))
-#else
-#error No stat() wrapper
 #endif
 
 #ifdef HAVE__LSTAT
 #define real_lstat(fn,st)              (syscall(SYS_lstat,(fn),(st)))
 #elif HAVE___LSTAT
 #define real_lstat(fn,st)              (__lstat(fn,st))
-#else
-#error No lstat() wrapper
 #endif
 
 #ifdef HAVE__FSTAT
 #define real_fstat(fd,st)              (syscall(SYS_fstat,(fd),(st)))
 #elif HAVE___FSTAT
 #define real_fstat(fd,st)              (__fstat(fd,st))
-#else
-#error No fstat() wrapper
 #endif
 
 #if defined(HAVE_SYS_ACL_H) && defined(HAVE__ACL)
 #define real_stat64(fn,st)             (_stat64(fn,st))
 #elif HAVE___STAT64
 #define real_stat64(fn,st)             (__stat64(fn,st))
-#else
-#error No stat64() wrapper
 #endif
 
 #ifdef HAVE__LSTAT64
 #define real_lstat64(fn,st)                    (_lstat64(fn,st))
 #elif HAVE___LSTAT64
 #define real_lstat64(fn,st)                    (__lstat64(fn,st))
-#else
-#error No lstat64() wrapper
 #endif
 
 #ifdef HAVE__FSTAT64
 #define real_fstat64(fd,st)                    (_fstat64(fd,st))
 #elif HAVE___FSTAT64
 #define real_fstat64(fd,st)                    (__fstat64(fd,st))
-#else
-#error No fstat64() wrapper
 #endif
 
 #ifdef HAVE__READDIR64
 #define real_readdir64(d)              (_readdir64(d))
 #elif HAVE___READDIR64
 #define real_readdir64(d)              (__readdir64(d))
-#else
-#error No readdir64() wrapper
 #endif
 
 #ifdef HAVE__LLSEEK
 #define real_llseek(fd,ofs,whence)             (__llseek(fd,ofs,whence))
 #elif HAVE___SYS_LLSEEK
 #define real_llseek(fd,ofs,whence)             (__sys_llseek(fd,ofs,whence))
-#else
-#error No llseek() wrapper
 #endif
 
 
 #define real_pread(fd,buf,size,ofs)                    (_pread(fd,buf,size,ofs))
 #elif HAVE___PREAD
 #define real_pread(fd,buf,size,ofs)                    (__pread(fd,buf,size,ofs))
-#else
-#error No pread() wrapper
 #endif
 
 #ifdef HAVE__PREAD64
 #define real_pread64(fd,buf,size,ofs)                  (_pread64(fd,buf,size,ofs))
 #elif HAVE___PREAD64
 #define real_pread64(fd,buf,size,ofs)                  (__pread64(fd,buf,size,ofs))
-#else
-#error No pread64() wrapper
 #endif
 
 #ifdef HAVE__PWRITE
 #define real_pwrite(fd,buf,size,ofs)                   (_pwrite(fd,buf,size,ofs))
 #elif HAVE___PWRITE
 #define real_pwrite(fd,buf,size,ofs)                   (__pwrite(fd,buf,size,ofs))
-#else
-#error No pwrite() wrapper
 #endif
 
 #ifdef HAVE__PWRITE64
 #define real_pwrite64(fd,buf,size,ofs)                 (_pwrite64(fd,buf,size,ofs))
 #elif HAVE___PWRITE64
 #define real_pwrite64(fd,buf,size,ofs)                 (__pwrite64(fd,buf,size,ofs))
-#else
-#error No pwrite64() wrapper
 #endif
 
 
index 010c5ae19a30289d935321257d691afb4d35cb6c..f7f7b8c8ea931191d4d48ce33ddb04e605455f9f 100644 (file)
@@ -37,7 +37,7 @@ void smbw_setup_shared(void)
 
        slprintf(s,sizeof(s)-1, "%s/smbw.XXXXXX",tmpdir());
 
-       fstrcpy(name,(char *)mktemp(s));
+       fstrcpy(name,(char *)smbd_mktemp(s));
 
        /* note zero permissions! don't change this */
        fd = sys_open(name,O_RDWR|O_CREAT|O_TRUNC|O_EXCL,0); 
index 8c9d00bd98134f7b0b2ba302ee3dd925617587ff..e11244d4fb305b5b50be21e5852242612d70f02b 100644 (file)
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
 
        sys_getwd(wd);
 
-       slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
+       slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
 
        smbw_setshared(line, wd);
 
index faaa9f047b0537b9aa552f97d010361215a4c1ba..4c246e1e40af6ac4848d36239b78ce23de2ac2cd 100644 (file)
@@ -81,7 +81,7 @@ void smbw_init(void)
 
        lp_load(servicesf,True,False,False);
 
-       get_myname(global_myname,NULL);
+       get_myname(global_myname);
 
        if ((p=smbw_getshared("DEBUG"))) {
                DEBUGLEVEL = atoi(p);
@@ -93,11 +93,11 @@ void smbw_init(void)
 
        if ((p=smbw_getshared("PREFIX"))) {
                slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
-               string_sub(smbw_prefix,"//", "/");
+               all_string_sub(smbw_prefix,"//", "/", 0);
                DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
        }
 
-       slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
+       slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
        
        p = smbw_getshared(line);
        if (!p) {
@@ -320,7 +320,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
 
        pstrcpy(path,p);
 
-       string_sub(path, "/", "\\");
+       all_string_sub(path, "/", "\\", 0);
 
  ok:
        DEBUG(4,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n", 
@@ -341,6 +341,9 @@ int smbw_path(const char *path)
        char *cwd;
        int len;
 
+       if(!path)
+               return 0;
+
        /* this is needed to prevent recursion with the BSD malloc which
           opens /etc/malloc.conf on the first call */
        if (strncmp(path,"/etc/", 5) == 0) {
@@ -378,7 +381,7 @@ int smbw_errno(struct cli_state *c)
        uint32 ecode;
        int ret;
 
-       ret = cli_error(c, &eclass, &ecode);
+       ret = cli_error(c, &eclass, &ecode, NULL);
 
        if (ret) {
                DEBUG(3,("smbw_error %d %d (0x%x) -> %d\n", 
@@ -1385,7 +1388,7 @@ int smbw_fork(void)
                smbw_srv_close(srv);
        }
 
-       slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
+       slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
        smbw_setshared(line,smbw_cwd);
 
        /* unblock the parent */
index 7c6e6db70adb5bacbb70426ff5671d772983e1df..09294282736bcee81802d12c3eaa0e6b63c112e3 100644 (file)
@@ -146,8 +146,7 @@ static void smbw_printjob_add(struct print_job_info *job)
        finfo.mtime = job->t;
        finfo.atime = job->t;
        finfo.ctime = job->t;
-       finfo.uid   = (uid_t)-1;
-       nametouid(job->user, &finfo.uid);
+       finfo.uid = nametouid(job->user);
        finfo.mode = aRONLY;
        finfo.size = job->size;
 
@@ -198,7 +197,7 @@ int smbw_dir_open(const char *fname)
        cur_dir = dir;
 
        slprintf(mask, sizeof(mask)-1, "%s\\*", path);
-       string_sub(mask,"\\\\","\\");
+       all_string_sub(mask,"\\\\","\\",0);
 
        if ((p=strstr(srv->server_name,"#1D"))) {
                DEBUG(4,("doing NetServerEnum\n"));
index 4703614d649d87a6edbfc340ebac1f88da00c784..1b356e6a26defa186dfe58ae7e91e4002329fe9a 100644 (file)
 #include <errno.h>
 #include "realcalls.h"
 
+#ifndef NULL
+# define NULL ((void *)0)
+#endif
+
  int open(char *name, int flags, mode_t mode)
 {
        if (smbw_path(name)) {
                static double xx[70];
                void *d;
                d = (void *)readdir(dir);
-               if (!d) return (void *)0;
+               if (!d) return NULL;
                dirent64_convert(d, xx);
                return xx;
        }
 {
        return smbw_fork();
 }
+
index a90e00aa000acc32cedb6191fed84f244d01571f..32aecb874396957bcf4a74bc5fb3f6e07b4fc419 100644 (file)
@@ -1,5 +1,9 @@
 /* test whether fcntl locking works on this system */
 
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -33,7 +37,8 @@ static int sys_waitpid(pid_t pid,int *status,int options)
 int main(int argc, char *argv[])
 {
        struct flock lock;
-       int fd, pid, ret, status=1;
+       int fd, ret, status=1;
+       pid_t pid;
 
        if (!(pid=fork())) {
                sleep(2);
@@ -75,5 +80,15 @@ int main(int argc, char *argv[])
 
        unlink(DATA);
 
+#if defined(WIFEXITED) && defined(WEXITSTATUS)
+    if(WIFEXITED(status)) {
+        status = WEXITSTATUS(status);
+    } else {
+        status = 1;
+    }
+#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
+       status = (status == 0) ? 0 : 1;
+#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
+
        exit(status);
 }
index 8d5e8942e379867802efd1bb5ddc3a929a2ab052..93282782eedb15207ce51e42baaa377c9fc2961a 100644 (file)
@@ -1,6 +1,9 @@
 /* test whether ftruncte() can extend a file */
 
+#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
+#endif
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
index 37990e010b8db159953ab1fac680bc946aee8127..343fd5a184f908e0c3d5686f249f76e4de674533 100644 (file)
@@ -7,6 +7,10 @@
    array of ints! Ultrix is one culprit
   */
 
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <unistd.h>
index fb8a2a32d5f325bd6b19f1989cd03cce1e0df91f..fcef75d0d615918ca6c1caf987c17924809ce02b 100644 (file)
@@ -1,7 +1,9 @@
 /* this tests whether we can use a shared writeable mmap on a file -
    as needed for the mmap varient of FAST_SHARE_MODES */
 
+#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
+#endif
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -16,7 +18,7 @@
 main()
 {
        int *buf;
-       int i, pid;
+       int i
        int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666);
        int count=7;
 
index 3db510495aebf0a9e5ae8964c8e4ed8d879ba25e..7ff9ea61c9587b6abe003fd3ecabb5e021f52593 100644 (file)
@@ -2,7 +2,7 @@
 
 main()
 {
-#ifndef HAVE_FCNTL_LOCK
+#if !(defined(HAVE_FCNTL_LOCK) || defined(HAVE_STRUCT_FLOCK64))
        printf("ERROR: No locking available. Running Samba would be unsafe\n");
        exit(1);
 #endif
@@ -11,12 +11,13 @@ main()
        printf("WARNING: no shared memory. Running with slow locking code\n");
 #endif
 
-#ifdef HAVE_TRAPDOOR_UID
-       printf("WARNING: trapdoor uid system - Samba may not operate correctly\n");
+#if !(defined(HAVE_IFACE_IFCONF) || defined(HAVE_IFACE_IFREQ) || defined(HAVE_IFACE_AIX))
+       printf("WARNING: No automated network interface determination\n");
 #endif
 
-#if !(defined(HAVE_NETMASK_IFCONF) || defined(HAVE_NETMASK_IFREQ) || defined(HAVE_NETMASK_AIX))
-       printf("WARNING: No automated netmask determination - use an interfaces line\n");
+#if !(defined(USE_SETEUID) || defined(USE_SETREUID) || defined(USE_SETRESUID) || defined(USE_SETUIDX))
+       printf("ERROR: no seteuid method available\n");
+       exit(1);
 #endif
 
 #if !(defined(STAT_STATVFS) || defined(STAT_STATVFS64) || defined(STAT_STATFS3_OSF1) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS4) || defined(STAT_STATFS2_FSIZE) || defined(STAT_STATFS2_FS_DATA))
index 13956ec6f086f3b4f4202be0b0ed83ed61523da4..9f0e20957a2983896400108120b77d50acaa7da5 100644 (file)
@@ -1,7 +1,9 @@
 /* this tests whether we can use a sysv shared memory segment
    as needed for the sysv varient of FAST_SHARE_MODES */
 
+#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
index ef7201168fa97c1f87a4f206bddacce630d9a941..f9a1f43f461c3a788072e54200091c1cea5296fc 100644 (file)
  * does a decent job of converting Samba logs into HTML.
  * -------------------------------------------------------------------------- **
  *
- * $Revision: 1.9 $
+ * Revision 1.4  1998/11/13 03:37:01  tridge
+ * fixes for OSF1 compilation
+ *
+ * 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 -)-----
  *
  * ========================================================================== **
  */
 
-#include "includes.h"
-
-/* -------------------------------------------------------------------------- **
- * Global values.
- */
-
-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,33 +134,29 @@ 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, ")" );
-      break;
-    default:
+      (void)printf( ")" );
       break;
     }
 
   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, "(" );
-      break;
-    default:
+      (void)printf( "(" );
       break;
     }
   } /* newblock */
@@ -167,38 +180,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.
+   *
+   *  Output: Always zero.
    *
-   *  Input:  none.
-   *  output: none.
-   *  Notes:  Reads from the global infile, writes to the global outfile.
-   *          These default to stdin and stdout, respectively.
+   *  Notes:  The HTML output is sent to stdout.
    *
    * ------------------------------------------------------------------------ **
    */
@@ -211,8 +227,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 +248,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..fc1f8ad7812072dc0a8f4c3d37fb9954cb0e63ef 100644 (file)
@@ -176,6 +176,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
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 f920106f7532fad06363b3e0c8f919ee6c7e3c14..2f9bbc6c5395ab0b179236b713c01cc9c5acf613 100644 (file)
@@ -28,48 +28,37 @@ extern int DEBUGLEVEL;
 
 extern pstring scope;
 
-extern pstring myhostname;
 extern struct in_addr ipzero;
 
-int ServerFD= -1;
-
-BOOL RootPort = False;
+static BOOL use_bcast = True;
+static BOOL got_bcast = False;
+static struct in_addr bcast_addr;
+static BOOL recursion_desired = False;
+static BOOL translate_addresses = False;
+static int ServerFD= -1;
+static int RootPort = 0;
+static BOOL find_status=False;
 
 /****************************************************************************
   open the socket communication
   **************************************************************************/
 static BOOL open_sockets(void)
 {
-       if (RootPort)
-       {
-         ServerFD = open_socket_in( SOCK_DGRAM,
-                                    137,
-                                    3,
-                                    interpret_addr(lp_socket_address()) );
-
-         if (ServerFD == -1)
-       {
-           return(False);
-       }
+  ServerFD = open_socket_in( SOCK_DGRAM,
+                             (RootPort ? 137 :0),
+                             3,
+                             interpret_addr(lp_socket_address()), True );
 
-         set_socket_options(ServerFD,"SO_BROADCAST");
-  DEBUG(3, ("Socket opened.\n"));
-       }
-  return True;
-}
-
-
-/****************************************************************************
-  initialise connect, service and file structs
-****************************************************************************/
-static BOOL init_structs(void )
-{
-  if (!get_myname(myhostname,NULL))
+  if (ServerFD == -1)
     return(False);
 
+  set_socket_options(ServerFD,"SO_BROADCAST");
+
+  DEBUG(3, ("Socket opened.\n"));
   return True;
 }
 
+
 /****************************************************************************
 usage on the program
 ****************************************************************************/
@@ -83,15 +72,70 @@ static void usage(void)
   printf("\t-M                    searches for a master browser\n");
   printf("\t-R                    set recursion desired in packet\n");
   printf("\t-S                    lookup node status as well\n");
+  printf("\t-T                    translate IP addresses into names\n");
   printf("\t-r                    Use root port 137 (Win95 only replies to this)\n");
   printf("\t-A                    Do a node status on <name> as an IP Address\n");
   printf("\t-i NetBIOS scope      Use the given NetBIOS scope for name queries\n");
   printf("\t-s smb.conf file      Use the given path to the smb.conf file\n");
   printf("\t-h                    Print this help message.\n");
+  printf("\n  If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n");
   printf("\n");
 }
 
 
+/****************************************************************************
+send out one query
+****************************************************************************/
+static BOOL query_one(char *lookup, unsigned int lookup_type)
+{
+       int j, count;
+       struct in_addr *ip_list=NULL;
+
+       if (got_bcast) {
+               printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
+               ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
+                                    use_bcast?True:recursion_desired,
+                                    bcast_addr,&count,NULL);
+       } else {
+               struct in_addr *bcast;
+               for (j=iface_count() - 1;
+                    !ip_list && j >= 0;
+                    j--) {
+                       bcast = iface_n_bcast(j);
+                       printf("querying %s on %s\n", 
+                              lookup, inet_ntoa(*bcast));
+                       ip_list = name_query(ServerFD,lookup,lookup_type,
+                                            use_bcast,
+                                            use_bcast?True:recursion_desired,
+                                            *bcast,&count,NULL);
+               }
+       }
+
+       if (!ip_list) return False;
+
+       for (j=0;j<count;j++) {
+               if (translate_addresses) {
+                       struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
+                       if (host) {
+                               printf("%s, ", host -> h_name);
+                       }
+               }
+               printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
+       }
+
+       /* We can only do find_status if the ip address returned
+          was valid - ie. name_query returned true.
+       */
+       if (find_status) {
+               printf("Looking up status of %s\n",inet_ntoa(ip_list[0]));
+               name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL,NULL);
+               printf("\n");
+       }
+
+       return (ip_list != NULL);
+}
+
+
 /****************************************************************************
   main program
 ****************************************************************************/
@@ -103,14 +147,10 @@ int main(int argc,char *argv[])
   extern int optind;
   extern char *optarg;
   BOOL find_master=False;
-  BOOL find_status=False;
   int i;
   static pstring servicesf = CONFIGFILE;
-  struct in_addr bcast_addr;
-  BOOL use_bcast = True;
-  BOOL got_bcast = False;
   BOOL lookup_by_ip = False;
-  BOOL recursion_desired = False;
+  int commandline_debuglevel = -2;
 
   DEBUGLEVEL = 1;
   *lookup = 0;
@@ -121,21 +161,22 @@ int main(int argc,char *argv[])
 
   charset_initialise();
 
-  while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhAR")) != EOF)
+  while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhART")) != EOF)
     switch (opt)
       {
       case 'B':
-       iface_set_default(NULL,optarg,NULL);
        bcast_addr = *interpret_addr2(optarg);
        got_bcast = True;
        use_bcast = True;
        break;
       case 'U':
-       iface_set_default(NULL,optarg,NULL);
        bcast_addr = *interpret_addr2(optarg);
        got_bcast = True;
        use_bcast = False;
        break;
+      case 'T':
+        translate_addresses = !translate_addresses;
+       break;
       case 'i':
        fstrcpy(scope,optarg);
        strupper(scope);
@@ -150,13 +191,13 @@ int main(int argc,char *argv[])
        recursion_desired = True;
        break;
       case 'd':
-       DEBUGLEVEL = atoi(optarg);
+       commandline_debuglevel = DEBUGLEVEL = atoi(optarg);
        break;
       case 's':
        pstrcpy(servicesf, optarg);
        break;
       case 'r':
-        RootPort = True;
+        RootPort = -1;
         break;
       case 'h':
        usage();
@@ -175,27 +216,25 @@ int main(int argc,char *argv[])
     exit(1);
   }
 
-  init_structs();
-
   if (!lp_load(servicesf,True,False,False)) {
     fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
   }
 
-  load_interfaces();
-  if (!open_sockets()) return(1);
-
-  if (!got_bcast)
-    bcast_addr = *iface_bcast(ipzero);
+  /*
+   * Ensure we reset DEBUGLEVEL if someone specified it
+   * on the command line.
+   */
 
-  DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_addr)));
+  if(commandline_debuglevel != -2)
+    DEBUGLEVEL = commandline_debuglevel;
 
+  load_interfaces();
+  if (!open_sockets()) return(1);
 
   for (i=optind;i<argc;i++)
   {
-      int j, count;
       char *p;
       struct in_addr ip;
-      struct in_addr *ip_list;
 
       fstrcpy(lookup,argv[i]);
 
@@ -225,21 +264,7 @@ int main(int argc,char *argv[])
         sscanf(p+1,"%x",&lookup_type);
       }
 
-      if ((ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
-                               use_bcast?True:recursion_desired,
-                               bcast_addr,&count,NULL))) {
-             for (j=0;j<count;j++)
-                     printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
-             
-             /* We can only do find_status if the ip address returned
-                was valid - ie. name_query returned true.
-                */
-             if (find_status) {
-                     printf("Looking up status of %s\n",inet_ntoa(ip_list[0]));
-                     name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL,NULL);
-                     printf("\n");
-             }
-      } else {
+      if (!query_one(lookup, lookup_type)) {
              printf("name_query failed to find name %s\n", lookup);
       }
   }
index 0933cf38c1f45aac5ec9c38a4e65073c422d4de4..fb08d70011eba3f75c44be30c316f1ba7eb285a3 100644 (file)
@@ -49,61 +49,16 @@ struct cli_state *smb_cli = &smbcli;
 
 FILE *out_hnd;
 
-static pstring user_name; /* local copy only, if one is entered */
 static pstring password; /* local copy only, if one is entered */
-static pstring domain; /* local copy only, if one is entered */
-BOOL got_pass = False;
-
-static struct nmb_name calling;
-static struct nmb_name called;
-
-static void get_passwd(void)
-{
-       /* set the password cache info */
-       if (got_pass)
-       {
-               if (password[0] == 0)
-               {
-                       pwd_set_nullpwd(&(smb_cli->pwd));
-               }
-               else
-               {
-                       pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
-               }
-       }
-       else 
-       {
-               char *pwd = getpass("Enter Password:");
-               safe_strcpy(password, pwd, sizeof(password));
-               pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
-               got_pass = True;
-       }
-}
 
 /****************************************************************************
 initialise smb client structure
 ****************************************************************************/
 void rpcclient_init(void)
 {
-       bzero(smb_cli, sizeof(smb_cli));
+       memset((char *)smb_cli, '\0', sizeof(smb_cli));
        cli_initialise(smb_cli);
        smb_cli->capabilities |= CAP_NT_SMBS;
-       smb_cli->capabilities |= CAP_STATUS32;
-
-       pstrcpy(smb_cli->user_name, user_name);
-
-       get_passwd();
-
-       if (*domain == 0)
-       {
-               pstrcpy(smb_cli->domain,lp_workgroup());
-       }
-       else
-       {
-               pstrcpy(smb_cli->domain, domain);
-       }
-
-       strupper(smb_cli->domain);
 }
 
 /****************************************************************************
@@ -111,9 +66,11 @@ make smb client connection
 ****************************************************************************/
 static BOOL rpcclient_connect(struct client_info *info)
 {
-       rpcclient_init();
+       struct nmb_name calling;
+       struct nmb_name called;
 
-       smb_cli->use_ntlmv2 = lp_client_ntlmv2();
+       make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope);
+       make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0            , scope);
 
        if (!cli_establish_connection(smb_cli, 
                                  info->dest_host, &info->dest_ip, 
@@ -140,7 +97,7 @@ static void rpcclient_stop(void)
 /****************************************************************************
   log in as an nt user, log out again. 
 ****************************************************************************/
-void run_enums_test(int num_ops, struct client_info *cli_info)
+void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
 {
        pstring cmd;
        int i;
@@ -148,8 +105,8 @@ void run_enums_test(int num_ops, struct client_info *cli_info)
        /* establish connections.  nothing to stop these being re-established. */
        rpcclient_connect(cli_info);
 
-       DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
-       if (smb_cli->fd <= 0)
+       DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
+       if (cli->fd <= 0)
        {
                fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
                                 cli_info->dest_host, cli_info->name_type);
@@ -184,7 +141,7 @@ void run_enums_test(int num_ops, struct client_info *cli_info)
 /****************************************************************************
   log in as an nt user, log out again. 
 ****************************************************************************/
-void run_ntlogin_test(int num_ops, struct client_info *cli_info)
+void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
 {
        pstring cmd;
        int i;
@@ -192,8 +149,8 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info)
        /* establish connections.  nothing to stop these being re-established. */
        rpcclient_connect(cli_info);
 
-       DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
-       if (smb_cli->fd <= 0)
+       DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
+       if (cli->fd <= 0)
        {
                fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
                                 cli_info->dest_host, cli_info->name_type);
@@ -202,7 +159,7 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info)
        
        for (i = 0; i < num_ops; i++)
        {
-               slprintf(cmd, sizeof(cmd)-1, "%s %s", smb_cli->user_name, password);
+               slprintf(cmd, sizeof(cmd)-1, "%s %s", cli->user_name, password);
                set_first_token(cmd);
 
                cmd_netlogon_login_test(cli_info);
@@ -212,382 +169,12 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info)
 
 }
 
-/* generate a random buffer */
-static void rand_buf(char *buf, int len)
-{
-       while (len--) {
-               *buf = sys_random();
-               buf++;
-       }
-}
-
-/****************************************************************************
-do a random rpc command
-****************************************************************************/
-BOOL do_random_rpc(struct cli_state *cli, uint16 nt_pipe_fnum, int max_len)
-{
-       prs_struct rbuf;
-       prs_struct buf; 
-       uint8 opcode;
-       int param_len;
-       BOOL response = False;
-
-       if ((sys_random() % 20) == 0)
-       {
-               param_len = (sys_random() % 256) + 4;
-       }
-       else
-       {
-               param_len = (sys_random() % max_len) + 4;
-       }
-
-       prs_init(&buf , param_len, 4, SAFETY_MARGIN, False);
-       prs_init(&rbuf, 0        , 4, SAFETY_MARGIN, True );
-
-       opcode = sys_random() % 256;
-
-       /* turn parameters into data stream */
-       rand_buf(mem_data(&buf.data, 0), param_len);
-       buf.offset = param_len;
-
-       /* send the data on \PIPE\ */
-       if (rpc_api_pipe_req(cli, nt_pipe_fnum, opcode, &buf, &rbuf))
-       {
-               response = rbuf.offset != 0;
-
-               if (response)
-               {
-                       DEBUG(0,("response! opcode: 0x%x\n", opcode));
-                       DEBUG(0,("request: length %d\n", param_len));
-                       dump_data(0, mem_data(&buf.data , 0), MIN(param_len, 128));
-                       DEBUG(0,("response: length %d\n", rbuf.data->offset.end));
-                       dump_data(0, mem_data(&rbuf.data, 0), rbuf.data->offset.end);
-               }
-       }
-
-       prs_mem_free(&rbuf);
-       prs_mem_free(&buf );
-
-       return response;
-}
-
-
-/* send random IPC commands */
-static void random_rpc_pipe_enc(char *pipe_name, struct client_info *cli_info,
-               int numops)
-{
-       uint16 nt_pipe_fnum;
-       int i;
-
-       DEBUG(0,("starting random rpc test on %s (encryped)\n", pipe_name));
-
-       /* establish connections.  nothing to stop these being re-established. */
-       if (!rpcclient_connect(cli_info))
-       {
-               DEBUG(0,("random rpc test: connection failed\n"));
-               return;
-       }
-
-       cli_nt_set_ntlmssp_flgs(smb_cli,
-                                   NTLMSSP_NEGOTIATE_UNICODE |
-                                   NTLMSSP_NEGOTIATE_OEM |
-                                   NTLMSSP_NEGOTIATE_SIGN |
-                                   NTLMSSP_NEGOTIATE_SEAL |
-                                   NTLMSSP_NEGOTIATE_LM_KEY |
-                                   NTLMSSP_NEGOTIATE_NTLM |
-                                   NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
-                                   NTLMSSP_NEGOTIATE_00001000 |
-                                   NTLMSSP_NEGOTIATE_00002000);
-
-       for (i = 1; i <= numops * 100; i++)
-       {
-               /* open session.  */
-               cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum);
-
-               do_random_rpc(smb_cli, nt_pipe_fnum, 1024);
-               if (i % 500 == 0)
-               {
-                       DEBUG(0,("calls: %i\n", i));
-               }
-
-               /* close the session */
-               cli_nt_session_close(smb_cli, nt_pipe_fnum);
-       }
-
-       /* close the rpc pipe */
-       rpcclient_stop();
-
-       DEBUG(0,("finished random rpc test on %s\n", pipe_name));
-}
-
-/* send random IPC commands */
-static void random_rpc_pipe(char *pipe_name, struct client_info *cli_info,
-               int numops)
-{
-       uint16 nt_pipe_fnum;
-       int i;
-
-       DEBUG(0,("starting random rpc test on %s\n", pipe_name));
-
-       /* establish connections.  nothing to stop these being re-established. */
-       if (!rpcclient_connect(cli_info))
-       {
-               DEBUG(0,("random rpc test: connection failed\n"));
-               return;
-       }
-
-       /* open session.  */
-       if (!cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum))
-       {
-               DEBUG(0,("random rpc test: session open failed\n"));
-               return;
-       }
-
-       for (i = 1; i <= numops * 100; i++)
-       {
-               do_random_rpc(smb_cli, nt_pipe_fnum, 8192);
-               if (i % 500 == 0)
-               {
-                       DEBUG(0,("calls: %i\n", i));
-               }
-       }
-
-       /* close the session */
-       cli_nt_session_close(smb_cli, nt_pipe_fnum);
-
-       /* close the rpc pipe */
-       rpcclient_stop();
-
-       DEBUG(0,("finished random rpc test on %s\n", pipe_name));
-}
-
-static void run_randomrpc(int numops, struct client_info *cli_info)
-{
-       char *pipes[] =
-       {
-               PIPE_SAMR     ,
-               PIPE_WINREG   ,
-               PIPE_SRVSVC   ,
-               PIPE_WKSSVC   ,
-               PIPE_NETLOGON ,
-               PIPE_NTSVCS   ,
-               PIPE_LSARPC   ,
-               NULL
-       };
-
-       int i = 0;
-
-       while (pipes[i] != NULL)
-       {
-               random_rpc_pipe(pipes[i], cli_info, numops);
-#if 0
-               random_rpc_pipe_enc(pipes[i], cli_info, numops);
-#endif
-
-               i++;
-       }
-}
-
-
-static void run_samhandles(int numops, struct client_info *cli_info)
-{
-       uint16 nt_pipe_fnum;
-       int i;
-       int count = 0;
-       int failed = 0;
-       int retry = 500;
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, cli_info->dest_host);
-       strupper(srv_name);
-
-       DEBUG(0,("starting sam handle test\n"));
-
-       /* establish connections.  nothing to stop these being re-established. */
-       while (retry > 0 && !rpcclient_connect(cli_info))
-       {
-               retry--;
-       }
-
-       if (retry == 0)
-       {
-               DEBUG(0,("samhandle test: connection failed\n"));
-               return;
-       }
-
-       /* open session.  */
-       if (!cli_nt_session_open(smb_cli, PIPE_SAMR, &nt_pipe_fnum))
-       {
-               DEBUG(0,("samhandle test: session open failed\n"));
-               return;
-       }
-
-       for (i = 1; i <= numops * 100; i++)
-       {
-               POLICY_HND pol;
-               POLICY_HND dom;
-               if (!samr_connect(smb_cli, nt_pipe_fnum, srv_name, 0x20, &pol))
-               {
-                       failed++;
-               }
-/*
-               if (!samr_open_domain(smb_cli, nt_pipe_fnum, srv_name, 0x00000020, &pol))
-               {
-                       DEBUG(0,("samhandle domain open test (%i): failed\n", i));
-               }
- */
-               if (i % 500 == 0)
-               {
-                       DEBUG(0,("calls: %i\n", i));
-               }
-               count++;
-       }
-
-       /* close the session */
-       cli_nt_session_close(smb_cli, nt_pipe_fnum);
-
-       /* close the rpc pipe */
-       rpcclient_stop();
-
-       DEBUG(0,("finished samhandle test.  count: %d failed: %d\n", count, failed));
-}
-
-
-static void run_lsahandles(int numops, struct client_info *cli_info)
-{
-       uint16 nt_pipe_fnum;
-       int i;
-       int count = 0;
-       int failed = 0;
-       int retry = 500;
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, cli_info->myhostname);
-       strupper(srv_name);
-
-       DEBUG(0,("starting lsa handle test\n"));
-
-       /* establish connections.  nothing to stop these being re-established. */
-       while (retry > 0 && !rpcclient_connect(cli_info))
-       {
-               retry--;
-       }
-
-       if (retry == 0)
-       {
-               DEBUG(0,("lsahandle test: connection failed\n"));
-               return;
-       }
-       for (i = 1; i <= numops * 100; i++)
-       {
-               extern struct cli_state *rpc_smb_cli;
-               rpc_smb_cli = smb_cli;
-               POLICY_HND pol;
-               if (!lsa_open_policy(srv_name, &pol, False))
-               {
-                       failed++;
-               }
-               if (i % 500 == 0)
-               {
-                       DEBUG(0,("calls: %i\n", i));
-               }
-               count++;
-       }
-
-       /* close the rpc pipe */
-       rpcclient_stop();
-
-       DEBUG(0,("finished lsahandle test.  count: %d failed: %d\n", count, failed));
-}
-
-
-static void run_pipegobble(int numops, struct client_info *cli_info, char *pipe_name)
-{
-       uint16 nt_pipe_fnum;
-       int i;
-       int count = 0;
-       int failed = 0;
-       int retry = 500;
-       fstring srv_name;
-       fstrcpy(srv_name, "\\\\");
-       fstrcat(srv_name, cli_info->myhostname);
-       strupper(srv_name);
-
-       DEBUG(0,("starting pipe gobble test (%s)\n", pipe_name));
-
-       /* establish connections.  nothing to stop these being re-established. */
-       while (retry > 0 && !rpcclient_connect(cli_info))
-       {
-               retry--;
-       }
-
-       if (retry == 0)
-       {
-               DEBUG(0,("pipe gobble test: connection failed\n"));
-               return;
-       }
-       for (i = 1; i <= numops * 100; i++)
-       {
-               /* open session.  */
-               if (!cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum))
-               {
-                       DEBUG(0,("pipe gobble test: session open failed\n"));
-               }
-
-               if (i % 500 == 0)
-               {
-                       DEBUG(0,("calls: %i\n", i));
-               }
-               count++;
-       }
-
-       rpcclient_stop();
-
-       DEBUG(0,("finished pipe gobble test (%s).  count: %d failed: %d\n",
-                 pipe_name, count, failed));
-}
-
-
-static void run_handles(int numops, struct client_info *cli_info)
-{
-       run_lsahandles(numops, cli_info);
-       run_samhandles(numops, cli_info);
-}
-
-static void run_pipegobbler(int numops, struct client_info *cli_info)
-{
-       run_pipegobble(numops, cli_info, PIPE_SAMR);
-       run_pipegobble(numops, cli_info, PIPE_LSARPC);
-}
-
-/****************************************************************************
-make tcp connection
-****************************************************************************/
-static void run_tcpconnect(int numops, struct client_info *info)
-{
-       int i;
-       int failed = 0;
-
-       for (i = 0; i < numops; i++)
-       {
-               rpcclient_init();
-
-               if (!cli_connect(smb_cli, info->dest_host, &info->dest_ip))
-               {
-                       failed++;
-               }
-               cli_shutdown(smb_cli);
-       }
-
-       DEBUG(0,("tcp connections: count: %d failed: %d\n", numops, failed));
-}
-
 /****************************************************************************
   runs n simultaneous functions.
 ****************************************************************************/
 static void create_procs(int nprocs, int numops, 
-               struct client_info *cli_info,
-               void (*fn)(int, struct client_info *))
+               struct client_info *cli_info, struct cli_state *cli,
+               void (*fn)(int, struct client_info *, struct cli_state *))
 {
        int i, status;
 
@@ -595,10 +182,10 @@ static void create_procs(int nprocs, int numops,
        {
                if (fork() == 0)
                {
-                       int mypid = getpid();
+                       pid_t mypid = getpid();
                        sys_srandom(mypid ^ time(NULL));
-                       fn(numops, cli_info);
-                       dbgflush();
+                       fn(numops, cli_info, cli);
+                       fflush(out_hnd);
                        _exit(0);
                }
        }
@@ -608,8 +195,6 @@ static void create_procs(int nprocs, int numops,
                waitpid(0, &status, 0);
        }
 }
-
-
 /****************************************************************************
 usage on the program - OUT OF DATE!
 ****************************************************************************/
@@ -628,8 +213,6 @@ static void usage(char *pname)
   fprintf(out_hnd, "\t-U username           set the network username\n");
   fprintf(out_hnd, "\t-W workgroup          set the workgroup name\n");
   fprintf(out_hnd, "\t-t terminal code      terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
-  fprintf(out_hnd, "\t-N processes          number of processes\n");
-  fprintf(out_hnd, "\t-o operations         number of operations\n");
   fprintf(out_hnd, "\n");
 }
 
@@ -652,6 +235,7 @@ enum client_action
        extern int optind;
        static pstring servicesf = CONFIGFILE;
        pstring term_code;
+       BOOL got_pass = False;
        char *cmd_str="";
        mode_t myumask = 0755;
        enum client_action cli_action = CLIENT_NONE;
@@ -662,6 +246,8 @@ enum client_action
 
        out_hnd = stdout;
 
+       rpcclient_init();
+
 #ifdef KANJI
        pstrcpy(term_code, KANJI);
 #else /* KANJI */
@@ -699,6 +285,8 @@ enum client_action
        pstrcpy(cli_info.cur_dir , "\\");
        pstrcpy(cli_info.file_sel, "");
        pstrcpy(cli_info.base_dir, "");
+       pstrcpy(smb_cli->domain, "");
+       pstrcpy(smb_cli->user_name, "");
        pstrcpy(cli_info.myhostname, "");
        pstrcpy(cli_info.dest_host, "");
 
@@ -711,6 +299,7 @@ enum client_action
        ZERO_STRUCT(cli_info.dom.level5_sid);
        pstrcpy(cli_info.dom.level5_dom, "");
 
+       smb_cli->nt_pipe_fnum   = 0xffff;
 
        setup_logging(pname, True);
 
@@ -720,7 +309,7 @@ enum client_action
        myumask = umask(0);
        umask(myumask);
 
-       if (!get_myname(global_myname, NULL))
+       if (!get_myname(global_myname))
        {
                fprintf(stderr, "Failed to get my hostname.\n");
        }
@@ -771,7 +360,7 @@ enum client_action
                cli_action = CLIENT_SVC;
        }
 
-       while ((opt = getopt(argc, argv,"s:B:O:M:S:i:N:o:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+       while ((opt = getopt(argc, argv,"s:O:M:S:i:N:o:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
        {
                switch (opt)
                {
@@ -799,12 +388,6 @@ enum client_action
                                break;
                        }
 
-                       case 'B':
-                       {
-                               iface_set_default(NULL,optarg,NULL);
-                               break;
-                       }
-
                        case 'i':
                        {
                                pstrcpy(scope, optarg);
@@ -814,8 +397,8 @@ enum client_action
                        case 'U':
                        {
                                char *lp;
-                               pstrcpy(user_name,optarg);
-                               if ((lp=strchr(user_name,'%')))
+                               pstrcpy(smb_cli->user_name,optarg);
+                               if ((lp=strchr(smb_cli->user_name,'%')))
                                {
                                        *lp = 0;
                                        pstrcpy(password,lp+1);
@@ -827,7 +410,7 @@ enum client_action
 
                        case 'W':
                        {
-                               pstrcpy(domain,optarg);
+                               pstrcpy(smb_cli->domain,optarg);
                                break;
                        }
 
@@ -925,7 +508,13 @@ enum client_action
        strupper(global_myname);
        fstrcpy(cli_info.myhostname, global_myname);
 
-       DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
+       DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
+
+       if (*smb_cli->domain == 0)
+       {
+               pstrcpy(smb_cli->domain,lp_workgroup());
+       }
+       strupper(smb_cli->domain);
 
        load_interfaces();
 
@@ -939,25 +528,31 @@ enum client_action
        strupper(cli_info.mach_acct);
        fstrcat(cli_info.mach_acct, "$");
 
-       make_nmb_name(&called , dns_to_netbios_name(cli_info.dest_host ), cli_info.name_type, scope);
-       make_nmb_name(&calling, dns_to_netbios_name(cli_info.myhostname), 0x0               , scope);
+       /* set the password cache info */
+       if (got_pass)
+       {
+               if (password[0] == 0)
+               {
+                       pwd_set_nullpwd(&(smb_cli->pwd));
+               }
+               else
+               {
+                       pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
+               }
+       }
+       else 
+       {
+               char *pwd = getpass("Enter Password:");
+               safe_strcpy(password, pwd, sizeof(password));
+               pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
+       }
 
-       get_passwd();
-/*
-       create_procs(nprocs, numops, &cli_info, run_enums_test);
+       create_procs(nprocs, numops, &cli_info, smb_cli, run_enums_test);
 
        if (password[0] != 0)
        {
-               create_procs(nprocs, numops, &cli_info, run_ntlogin_test);
+               create_procs(nprocs, numops, &cli_info, smb_cli, run_ntlogin_test);
        }
-*/
-
-/*
-       create_procs(nprocs, numops, &cli_info, run_randomrpc);
-       create_procs(nprocs, numops, &cli_info, run_pipegobbler);
-       create_procs(nprocs, numops, &cli_info, run_tcpconnect);
-*/
-       create_procs(nprocs, numops, &cli_info, run_handles);
 
        fflush(out_hnd);
 
index 643a3ed2ce591033c6e0b6b098d64fbd8a0f7c15..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)) {
@@ -159,7 +159,7 @@ static void start_filter(char *desthost)
        CatchChild();
 
        /* start listening on port 139 locally */
-       s = open_socket_in(SOCK_STREAM, 139, 0, 0);
+       s = open_socket_in(SOCK_STREAM, 139, 0, 0, True);
        
        if (s == -1) {
                DEBUG(0,("bind failed\n"));
@@ -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 3b87687c261609fdfbdf979b94eec5b42adeb21a..ec6ce15f07df1abc90ca162b7488db7400025c23 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module.
- * Copyright (C) Jeremy Allison               1995-1999
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
+ * (C) Jeremy Allison 1995-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
@@ -20,9 +19,7 @@
 
 #include "includes.h"
 
-extern pstring myhostname;
 extern pstring global_myname;
-extern pstring global_myworkgroup;
 extern int DEBUGLEVEL;
 
 /*
@@ -65,135 +62,85 @@ static void usage(void)
        if (getuid() == 0) {
                printf("  -R ORDER             name resolve order\n");
                printf("  -j DOMAIN            join domain name\n");
-               printf("  -S                   synchronise with PDC (if we are BDC)\n");
                printf("  -a                   add user\n");
                printf("  -d                   disable user\n");
                printf("  -e                   enable user\n");
                printf("  -n                   set no password\n");
-               printf("  -m                   workstation trust account\n");
-               printf("  -b                   backup domain controller account\n");
-               printf("  -i                   inter-domain trust account\n");
-               printf("  -p                   user cannot change password\n");
-               printf("  -x                   user can change password\n");
+               printf("  -m                   machine trust account\n");
        }
-       
        exit(1);
 }
 
 /*********************************************************
 Join a domain.
 **********************************************************/
-static int create_interdomain_trust_acct(char *domain, char *name)
+static int join_domain(char *domain, char *remote)
 {
+       pstring remote_machine;
        fstring trust_passwd;
-       unsigned char hash[16];
-       uint16 sec_chan;
-
-       switch (lp_server_role())
-       {
-               case ROLE_DOMAIN_PDC:
-               {
-                       DEBUG(0, ("Joining domain - we are PDC\n"));
-                       sec_chan = SEC_CHAN_DOMAIN;
-                       break;
-               }
-               case ROLE_DOMAIN_BDC:
-               {
-                       DEBUG(0, ("Cannot set up inter-domain trust as BDC!\n"));
-                       return 1;
-               }
-               default:
-               {
-                       DEBUG(0, ("Cannot set up inter-domain trust as workstation!\n"));
-                       return 1;
-               }
-       }
+       unsigned char orig_trust_passwd_hash[16];
+       BOOL ret;
+
+       pstrcpy(remote_machine, remote ? remote : "");
+       fstrcpy(trust_passwd, global_myname);
+       strlower(trust_passwd);
+       E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
 
-#if 0
-       pstrcpy(remote_machine, remote ? remote : lp_passwordserver());
+       /* Ensure that we are not trying to join a
+          domain if we are locally set up as a domain
+          controller. */
 
-       if (!remote_machine[0])
-       {
-               fprintf(stderr, "You must specify the PDC via 'password server' or -r.");
+       if(strequal(remote, global_myname)) {
+               fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
                return 1;
        }
-#endif
 
-       fstrcpy(trust_passwd, name);
-       strlower(trust_passwd);
-       E_md4hash( (uchar *)trust_passwd, hash);
-
-       if (!create_trust_account_file(domain, name, hash))
-       {
+       /*
+        * Create the machine account password file.
+        */
+       if(!trust_password_lock( domain, global_myname, True)) {
+               fprintf(stderr, "Unable to open the machine account password file for \
+machine %s in domain %s.\n", global_myname, domain); 
                return 1;
        }
+
+       /*
+        * Write the old machine account password.
+        */
        
-#if 0
-       if(!change_trust_account_password(domain, remote_machine, sec_chan))
-       {
-               fprintf(stderr,"Unable to join domain %s.\n",domain);
+       if(!set_trust_account_password( orig_trust_passwd_hash)) {              
+               fprintf(stderr, "Unable to write the machine account password for \
+machine %s in domain %s.\n", global_myname, domain);
+               trust_password_unlock();
                return 1;
        }
-#endif
-       printf("Created Inter-Domain Trust Account for %s.\n",domain);
-       return 0;
-}
-
-/*********************************************************
-Join a domain.
-**********************************************************/
-static int join_domain(char *domain, char *remote)
-{
-       pstring remote_machine;
-       fstring trust_passwd;
-       unsigned char orig_trust_passwd_hash[16];
-       uint16 sec_chan;
-
-       switch (lp_server_role())
-       {
-               case ROLE_DOMAIN_PDC:
-               {
-                       DEBUG(0, ("Cannot join domain - we are PDC!\n"));
-                       return 1;
-               }
-               case ROLE_DOMAIN_BDC:
-               {
-                       DEBUG(0, ("Joining Domain as BDC\n"));
-                       sec_chan = SEC_CHAN_BDC;
-                       break;
-               }
-               default:
-               {
-                       DEBUG(0, ("Joining Domain as Workstation\n"));
-                       sec_chan = SEC_CHAN_WKSTA;
-               }
+       
+       /*
+        * If we are given a remote machine assume this is the PDC.
+        */
+       
+       if(remote == NULL) {
+               pstrcpy(remote_machine, lp_passwordserver());
        }
 
-       pstrcpy(remote_machine, remote ? remote : lp_passwordserver());
-
-       if (!remote_machine[0])
-       {
-               fprintf(stderr, "You must specify the PDC via 'password server' or -r.");
+       if(!*remote_machine) {
+               fprintf(stderr, "No password server list given in smb.conf - \
+unable to join domain.\n");
+               trust_password_unlock();
                return 1;
        }
 
-       fstrcpy(trust_passwd, global_myname);
-       strlower(trust_passwd);
-       E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
-
-       if (!create_trust_account_file(domain, global_myname, trust_passwd))
-       {
-               return 1;
-       }
+       ret = change_trust_account_password( domain, remote_machine);
+       trust_password_unlock();
        
-       if(!change_trust_account_password(domain, remote_machine, sec_chan))
-       {
+       if(!ret) {
+               trust_password_delete( domain, global_myname);
                fprintf(stderr,"Unable to join domain %s.\n",domain);
-               return 1;
+       } else {
+               printf("Joined domain %s.\n",domain);
        }
-
-       printf("Joined domain %s.\n",domain);
-       return 0;
+       
+       return (int)ret;
 }
 
 
@@ -262,6 +209,7 @@ static char *prompt_for_new_password(BOOL stdin_get)
 
        if (strcmp(p, new_passwd)) {
                fprintf(stderr, "Mismatch - password unchanged.\n");
+               ZERO_ARRAY(new_passwd);
                return NULL;
        }
 
@@ -273,47 +221,35 @@ static char *prompt_for_new_password(BOOL stdin_get)
 change a password either locally or remotely
 *************************************************************/
 static BOOL password_change(const char *remote_machine, char *user_name, 
-                               char *old_passwd, char *new_passwd, 
-                               BOOL add_user, 
-                               uint16 acb_info, uint16 acb_mask)
+                           char *old_passwd, char *new_passwd, 
+                           BOOL add_user, BOOL enable_user, 
+                           BOOL disable_user, BOOL set_no_password,
+                           BOOL trust_account)
 {
        BOOL ret;
        pstring err_str;
        pstring msg_str;
 
-       if (remote_machine != NULL)
-       {
-               if (add_user ||
-                   IS_BITS_SET_SOME(acb_info, ACB_PWNOTREQ | ACB_WSTRUST | ACB_DOMTRUST | ACB_SVRTRUST) ||
-                   (IS_BITS_SET_SOME(acb_mask, ACB_DISABLED) && 
-                    IS_BITS_CLR_ALL(acb_info, ACB_DISABLED)))
-               {
+       if (remote_machine != NULL) {
+               if (add_user || enable_user || disable_user || set_no_password || trust_account) {
                        /* these things can't be done remotely yet */
                        return False;
                }
                ret = remote_password_change(remote_machine, user_name, 
-                                           old_passwd, new_passwd,
-                                           err_str, sizeof(err_str));
-               if (*err_str != 0)
-               {
+                                                                        old_passwd, new_passwd, err_str, sizeof(err_str));
+               if(*err_str)
                        fprintf(stderr, err_str);
-               }
                return ret;
        }
        
-       ret = local_password_change(user_name, add_user, acb_info, acb_mask,
-                                    new_passwd, 
-                                    err_str, sizeof(err_str),
-                                    msg_str, sizeof(msg_str));
+       ret = local_password_change(user_name, trust_account, add_user, enable_user, 
+                                    disable_user, set_no_password, new_passwd, 
+                                    err_str, sizeof(err_str), msg_str, sizeof(msg_str));
 
-       if (*msg_str != 0)
-       {
+       if(*msg_str)
                printf(msg_str);
-       }
-       if (*err_str != 0)
-       {
+       if(*err_str)
                fprintf(stderr, err_str);
-       }
 
        return ret;
 }
@@ -326,156 +262,80 @@ static int process_root(int argc, char *argv[])
 {
        struct passwd  *pwd;
        int ch;
-       uint16 acb_info = 0;
-       uint16 acb_mask = 0;
        BOOL joining_domain = False;
-       BOOL sam_sync = False;
-       BOOL wks_trust_account = False;
-       BOOL srv_trust_account = False;
-       BOOL dom_trust_account = False;
+       BOOL trust_account = False;
        BOOL add_user = False;
        BOOL disable_user = False;
        BOOL enable_user = False;
        BOOL set_no_password = False;
        BOOL stdin_passwd_get = False;
-       BOOL lock_password = False;
-       BOOL unlock_password = False;
        char *user_name = NULL;
        char *new_domain = NULL;
        char *new_passwd = NULL;
        char *old_passwd = NULL;
        char *remote_machine = NULL;
-       int ret;
-
-       while ((ch = getopt(argc, argv, "abdehimnpxj:Sr:sR:D:U:")) != EOF)
-       {
-               switch(ch)
-               {
-                       case 'a':
-                       {
-                               add_user = True;
-                               break;
-                       }
-                       case 'd':
-                       {
-                               disable_user = True;
-                               new_passwd = "XXXXXX";
-                               break;
-                       }
-                       case 'e':
-                       {
-                               enable_user = True;
-                               break;
-                       }
-                       case 'D':
-                       {
-                               DEBUGLEVEL = atoi(optarg);
-                               break;
-                       }
-                       case 'n':
-                       {
-                               set_no_password = True;
-                               new_passwd = "NO PASSWORD";
-                       }
-                       case 'r':
-                       {
-                               remote_machine = optarg;
-                               break;
-                       }
-                       case 's':
-                       {
-                               set_line_buffering(stdin);
-                               set_line_buffering(stdout);
-                               set_line_buffering(stderr);
-                               stdin_passwd_get = True;
-                               break;
-                       }
-                       case 'R':
-                       {
-                               lp_set_name_resolve_order(optarg);
-                               break;
-                       }
-                       case 'i':
-                       {
-                               dom_trust_account = True;
-                               break;
-                       }
-                       case 'b':
-                       {
-                               srv_trust_account = True;
-                               break;
-                       }
-                       case 'm':
-                       {
-                               wks_trust_account = True;
-                               break;
-                       }
-                       case 'j':
-                       {
-                               new_domain = optarg;
-                               strupper(new_domain);
-                               joining_domain = True;
-                               break;
-                       }
-                       case 'S':
-                       {
-                               sam_sync = True;
-                               break;
-                       }
-                       case 'U':
-                       {
-                               user_name = optarg;
-                               break;
-                       }
-                       case 'p':
-                       {
-                               lock_password = True;
-                               break;
-                       }
-                       case 'x':
-                       {
-                               unlock_password = True;
-                               break;
-                       }
-                       default:
-                       {
-                               usage();
-                       }
+
+       while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) {
+               switch(ch) {
+               case 'a':
+                       add_user = True;
+                       break;
+               case 'd':
+                       disable_user = True;
+                       new_passwd = "XXXXXX";
+                       break;
+               case 'e':
+                       enable_user = True;
+                       break;
+               case 'D':
+                       DEBUGLEVEL = atoi(optarg);
+                       break;
+               case 'n':
+                       set_no_password = True;
+                       new_passwd = "NO PASSWORD";
+               case 'r':
+                       remote_machine = optarg;
+                       break;
+               case 's':
+                       set_line_buffering(stdin);
+                       set_line_buffering(stdout);
+                       set_line_buffering(stderr);
+                       stdin_passwd_get = True;
+                       break;
+               case 'R':
+                       lp_set_name_resolve_order(optarg);
+                       break;
+               case 'm':
+                       trust_account = True;
+                       break;
+               case 'j':
+                       new_domain = optarg;
+                       strupper(new_domain);
+                       joining_domain = True;
+                       break;
+               case 'U':
+                       user_name = optarg;
+                       break;
+               default:
+                       usage();
                }
        }
        
        argc -= optind;
        argv += optind;
 
+
        /*
         * Ensure add_user and either remote machine or join domain are
         * not both set.
         */     
-       if (add_user && ((remote_machine != NULL) || joining_domain))
-       {
+       if(add_user && ((remote_machine != NULL) || joining_domain)) {
                usage();
        }
-
-       if (sam_sync && lp_server_role() != ROLE_DOMAIN_BDC) {
-               fprintf(stderr, "The -S option can only be used on a Backup Domain Controller.\n");
-               return 1;
-       }
        
-       if (joining_domain)
-       {
-               if (!dom_trust_account)
-               {
-                       if (argc != 0) usage();
-                       ret = join_domain(new_domain, remote_machine);
-
-                       if ((ret != 0) || (!sam_sync))
-                               return ret;
-               }
-       }
-
-       if (sam_sync)
-       {
-               return synchronise_passdb();
+       if(joining_domain) {
+               if (argc != 0) usage();
+               return join_domain(new_domain, remote_machine);
        }
 
        /*
@@ -496,7 +356,7 @@ static int process_root(int argc, char *argv[])
                usage();
        }
 
-       if (!user_name && (pwd = getpwuid(0))) {
+       if (!user_name && (pwd = sys_getpwuid(0))) {
                user_name = xstrdup(pwd->pw_name);
        } 
 
@@ -505,8 +365,7 @@ static int process_root(int argc, char *argv[])
                exit(1);
        }
 
-       if (wks_trust_account || srv_trust_account || dom_trust_account)
-       {
+       if (trust_account) {
                /* add the $ automatically */
                static fstring buf;
 
@@ -539,24 +398,12 @@ static int process_root(int argc, char *argv[])
                exit(1);
        }
 
-       if (joining_domain)
-       {
-               if (dom_trust_account)
-               {
-                       ret = create_interdomain_trust_acct(new_domain,
-                                                           global_myworkgroup);
-
-                       if ((ret != 0) || (!sam_sync))
-                               return ret;
-               }
-       }
-
        if (remote_machine != NULL) {
                old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
        }
        
-       if (!new_passwd)
-       {
+       if (!new_passwd) {
+
                /*
                 * If we are trying to enable a user, first we need to find out
                 * if they are using a modern version of the smbpasswd file that
@@ -566,94 +413,43 @@ static int process_root(int argc, char *argv[])
                 * smbpasswd file) then we need to prompt for a new password.
                 */
 
-               if (enable_user)
-               {
+               if(enable_user) {
                        struct smb_passwd *smb_pass = getsmbpwnam(user_name);
-                       if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL))
-                       {
+                       if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) {
                                new_passwd = "XXXX"; /* Don't care. */
                        }
                }
 
                if(!new_passwd)
-               {
                        new_passwd = prompt_for_new_password(stdin_passwd_get);
-               }
-       }
-       
-       if (enable_user)
-       {
-               acb_mask |= ACB_DISABLED;
-               acb_info &= ~ACB_DISABLED;
-       }
-
-       if (disable_user)
-       {
-               acb_mask |= ACB_DISABLED;
-               acb_info |= ACB_DISABLED;
-       }
 
-       if (set_no_password)
-       {
-               acb_mask |= ACB_PWNOTREQ;
-               acb_info |= ACB_PWNOTREQ;
-       }
-
-       if (lock_password)
-       {
-               acb_mask |= ACB_PWLOCK;
-               acb_info |= ACB_PWLOCK;
-       }
-
-       if (unlock_password)
-       {
-               acb_mask |= ACB_PWLOCK;
-               acb_info &= ~ACB_PWLOCK;
+               if(!new_passwd) {
+                       fprintf(stderr, "Unable to get new password.\n");
+                       exit(1);
+               }
        }
        
-       if (wks_trust_account)
-       {
-               acb_mask |= ACB_WSTRUST;
-               acb_info |= ACB_WSTRUST;
-       }
-       else if (srv_trust_account)
-       {
-               acb_mask |= ACB_SVRTRUST;
-               acb_info |= ACB_SVRTRUST;
-       }
-       else if (dom_trust_account)
-       {
-               acb_mask |= ACB_DOMTRUST;
-               acb_info |= ACB_DOMTRUST;
-       }
-       else
-       {
-               acb_mask |= ACB_NORMAL;
-               acb_info |= ACB_NORMAL;
-       }
-
        if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
-                            add_user, acb_info, acb_mask))
-       {
+                            add_user, enable_user, disable_user, set_no_password,
+                            trust_account)) {
                fprintf(stderr,"Failed to change password entry for %s\n", user_name);
                return 1;
        } 
 
-       if (disable_user)
-       {
+       if(disable_user) {
                printf("User %s disabled.\n", user_name);
-       }
-       if (enable_user)
-       {
+       } else if(enable_user) {
                printf("User %s enabled.\n", user_name);
-       }
-       if (set_no_password)
-       {
+       } else if (set_no_password) {
                printf("User %s - set to no password.\n", user_name);
-       }
-       if (!disable_user && !enable_user && !set_no_password)
-       {
-               printf("Password changed for user %s\n", user_name);
+       } else {
+               struct smb_passwd *smb_pass = getsmbpwnam(user_name);
+               printf("Password changed for user %s.", user_name );
+               if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_DISABLED ))
+                       printf(" User has disabled flag set.");
+               if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ))
+                       printf(" User has no password flag set.");
+               printf("\n");
        }
        return 0;
 }
@@ -671,11 +467,9 @@ static int process_nonroot(int argc, char *argv[])
        char *remote_machine = NULL;
        char *user_name = NULL;
        char *new_passwd = NULL;
-       
-       while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF)
-       {
-               switch(ch)
-               {
+
+       while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF) {
+               switch(ch) {
                case 'D':
                        DEBUGLEVEL = atoi(optarg);
                        break;
@@ -708,7 +502,7 @@ static int process_nonroot(int argc, char *argv[])
        }
        
        if (!user_name) {
-               pwd = getpwuid(getuid());
+               pwd = sys_getpwuid(getuid());
                if (pwd) {
                        user_name = xstrdup(pwd->pw_name);
                } else {
@@ -726,6 +520,7 @@ static int process_nonroot(int argc, char *argv[])
                remote_machine = "127.0.0.1";
        }
 
+
        if (remote_machine != NULL) {
                old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
        }
@@ -735,14 +530,12 @@ static int process_nonroot(int argc, char *argv[])
        }
        
        if (!new_passwd) {
-               printf("unable to get new password\n");
-               exit(0);
+               fprintf(stderr, "Unable to get new password.\n");
+               exit(1);
        }
 
-       if (!password_change(remote_machine, user_name,
-                            old_passwd, new_passwd,
-                            False, 0x0, 0x0))
-       {
+       if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
+                            False, False, False, False, False)) {
                fprintf(stderr,"Failed to change password for %s\n", user_name);
                return 1;
        }
@@ -760,20 +553,24 @@ int main(int argc, char **argv)
 {      
        static pstring servicesf = CONFIGFILE;
 
+#if defined(HAVE_SET_AUTH_PARAMETERS)
+       set_auth_parameters(argc, argv);
+#endif /* HAVE_SET_AUTH_PARAMETERS */
+
        TimeInit();
        
        setup_logging("smbpasswd", True);
        
        charset_initialise();
        
-       if (!lp_load(servicesf,True,False,False)) {
-               fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
-                       servicesf);
+       if(!initialize_password_db()) {
+               fprintf(stderr, "Can't setup password database vectors.\n");
                exit(1);
        }
 
-       if(!get_myname(myhostname,NULL)) {
-               fprintf(stderr, "unable to get my hostname.\n");
+       if (!lp_load(servicesf,True,False,False)) {
+               fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
+                       servicesf);
                exit(1);
        }
 
@@ -784,7 +581,7 @@ int main(int argc, char **argv)
     
        if (!*global_myname) {   
                char *p;
-               fstrcpy(global_myname, myhostname);
+               fstrcpy(global_myname, myhostname());
                p = strchr(global_myname, '.' );
                if (p) *p = 0;
        }           
@@ -794,12 +591,6 @@ int main(int argc, char **argv)
 
        load_interfaces();
 
-       if(!pwdb_initialise(False))
-       {
-               fprintf(stderr, "Can't setup password database vectors.\n");
-               exit(1);
-       }
-
        /* Check the effective uid - make sure we are not setuid */
        if ((geteuid() == (uid_t)0) && (getuid() != (uid_t)0)) {
                fprintf(stderr, "smbpasswd must *NOT* be setuid root.\n");
index 2a94ac32353d97ed9705d35547b45b311170a00a..b7c678411c66a58209dab0cbcec780f390340c68 100644 (file)
@@ -48,35 +48,17 @@ It takes 3 arguments as uid,gid,command and runs command after
 becoming a non-root user */
  int main(int argc,char *argv[])
 {
-  int uid,gid;
+  uid_t uid;
+  gid_t gid;
 
   close_fds();
 
   if (argc != 4) exit(2);
 
-  uid = atoi(argv[1]);
-  gid = atoi(argv[2]);
-
-  /* first become root - we may need to do this in order to lose
-     our privilages! */
-#ifdef HAVE_SETRESUID
-  setresgid(0,0,0);
-  setresuid(0,0,0);
-#else      
-  setuid(0);
-  seteuid(0);
-#endif
-
-#ifdef HAVE_SETRESUID
-  setresgid(gid,gid,gid);
-  setresuid(uid,uid,uid);      
-#else
-  setgid(gid);
-  setegid(gid);
-  setuid(uid);
-  seteuid(uid);
-#endif
+  uid = (uid_t)atoi(argv[1]);
+  gid = (gid_t)atoi(argv[2]);
 
+  become_user_permanently( uid, gid);
 
   /* paranoia :-) */
   if (getuid() != uid)
index 320a54cc7df922d897556e4d5e394f3684eed4c4..2cbfbfdaf5b25b2cf1ac87a0989382bb9752ab1c 100644 (file)
 
 #include "includes.h"
 
+struct connect_record crec;
+
 struct session_record{
-  int pid;
-  int uid;
+  pid_t pid;
+  uid_t uid;
   char machine[31];
   time_t start;
   struct session_record *next;
@@ -46,10 +48,9 @@ struct session_record{
 
 extern int DEBUGLEVEL;
 extern FILE *dbf;
-extern pstring myhostname;
 
 static pstring Ucrit_username = "";                   /* added by OH */
-int            Ucrit_pid[100];  /* Ugly !!! */        /* added by OH */
+pid_t  Ucrit_pid[100];  /* Ugly !!! */        /* added by OH */
 int            Ucrit_MaxPid=0;                        /* added by OH */
 unsigned int   Ucrit_IsActive = 0;                    /* added by OH */
 
@@ -76,7 +77,7 @@ static unsigned int Ucrit_checkUsername(char *username)
        return 0;
 }
 
-static void Ucrit_addPid(int pid)
+static void Ucrit_addPid(pid_t pid)
 {
        int i;
        if ( !Ucrit_IsActive) return;
@@ -85,7 +86,7 @@ static void Ucrit_addPid(int pid)
        Ucrit_pid[Ucrit_MaxPid++] = pid;
 }
 
-static unsigned int Ucrit_checkPid(int pid)
+static unsigned int Ucrit_checkPid(pid_t pid)
 {
        int i;
        if ( !Ucrit_IsActive) return 1;
@@ -106,7 +107,7 @@ static void print_share_mode(share_mode_entry *e, char *fname)
        count++;
 
        if (Ucrit_checkPid(e->pid)) {
-          printf("%-5d  ",e->pid);
+          printf("%-5d  ",(int)e->pid);
          switch ((e->share_mode>>4)&0xF) {
          case DENY_NONE: printf("DENY_NONE  "); break;
          case DENY_ALL:  printf("DENY_ALL   "); break;
@@ -128,10 +129,13 @@ static void print_share_mode(share_mode_entry *e, char *fname)
                printf("EXCLUSIVE       ");
          else if (e->op_type & BATCH_OPLOCK)
                printf("BATCH           ");
+         else if (e->op_type & LEVEL_II_OPLOCK)
+               printf("LEVEL_II        ");
          else
                printf("NONE            ");
 
-         printf(" %s   %s",fname,asctime(LocalTime((time_t *)&e->time.tv_sec)));
+         printf(" %s   %s",dos_to_unix(fname,False),
+             asctime(LocalTime((time_t *)&e->time.tv_sec)));
        }
 }
 
@@ -167,12 +171,9 @@ static int profile_dump(void)
   extern char *optarg;
   int verbose = 0, brief =0;
   BOOL processes_only=False;
-  int last_pid=0;
+  pid_t last_pid=(pid_t)0;
   struct session_record *ptr;
   int profile_only = 0;
-  struct connect_record *crec = NULL;
-  uint32 connection_count;
-  uint32 conn; 
 
   TimeInit();
   setup_logging(argv[0],True);
@@ -214,13 +215,11 @@ static int profile_dump(void)
       Ucrit_addUsername(optarg);                    /* added by OH */
       break;
     default:
-      fprintf(stderr, "Usage: %s [-P] [-d] [-L] [-p] [-S] [-s configfile] [-u username]\n", *argv); 
+      fprintf(stderr, "Usage: %s [-P] [-d] [-L] [-p] [-S] [-s configfile] [-u username]\n", *argv); /* changed by OH */
       return (-1);
     }
   }
 
-  get_myname(myhostname, NULL);
-
   if (!lp_load(servicesf,False,False,False)) {
     fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
     return (-1);
@@ -232,7 +231,7 @@ static int profile_dump(void)
   }
 
   if (profile_only) {
-         return profile_dump();
+       return profile_dump();
   }
 
   pstrcpy(fname,lp_lockdir());
@@ -267,59 +266,60 @@ static int profile_dump(void)
          printf("----------------------------------------------\n");
        }
     }
-               
-    if (get_connection_status(&crec, &connection_count))
-       {
-          for (conn=0;conn<connection_count;conn++) 
+
+    while (!feof(f))
+      {
+       if (fread(&crec,sizeof(crec),1,f) != 1)
+         break;
+       if (crec.cnum == -1) continue;
+       if ( crec.magic == 0x280267 && process_exists(crec.pid) 
+            && Ucrit_checkUsername(uidtoname(crec.uid))                      /* added by OH */
+            )
          {
-            if (Ucrit_checkUsername(uidtoname(crec[conn].uid)))
-              {
-               if (brief)
+           if (brief)
+             {
+               ptr=srecs;
+               while (ptr!=NULL)
+                 {
+                   if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) 
                      {
-                       ptr=srecs;
-                       while (ptr!=NULL)
-                         {
-                           if ((ptr->pid==crec[conn].pid)&&(strncmp(ptr->machine,crec[conn].machine,30)==0)) 
-                             {
-                               if (ptr->start > crec[conn].start)
-                                 ptr->start=crec[conn].start;
-                               break;
-                             }
-                           ptr=ptr->next;
-                         }
-                       if (ptr==NULL)
-                         {
-                           ptr=(struct session_record *) malloc(sizeof(struct session_record));
-                           ptr->uid=crec[conn].uid;
-                           ptr->pid=crec[conn].pid;
-                           ptr->start=crec[conn].start;
-                           strncpy(ptr->machine,crec[conn].machine,30);
-                           ptr->machine[30]='\0';
-                           ptr->next=srecs;
-                           srecs=ptr;
-                         }
+                       if (ptr->start > crec.start)
+                         ptr->start=crec.start;
+                       break;
                      }
-                   else
-                     {
-                       Ucrit_addPid(crec[conn].pid);                                             /* added by OH */
-                       if (processes_only) {
-                         if (last_pid != crec[conn].pid)
-                           printf("%d\n",crec[conn].pid);
-                         last_pid = crec[conn].pid; /* XXXX we can still get repeats, have to
-                                           add a sort at some time */
-                       }
-                       else      
-                         printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
-                                crec[conn].name,uidtoname(crec[conn].uid),gidtoname(crec[conn].gid),crec[conn].pid,
-                                crec[conn].machine,crec[conn].addr,
-                                asctime(LocalTime(&crec[conn].start)));
-                     }
-              }
-          }
-          free(crec);
-       }
+                   ptr=ptr->next;
+                 }
+               if (ptr==NULL)
+                 {
+                   ptr=(struct session_record *) malloc(sizeof(struct session_record));
+                   ptr->uid=crec.uid;
+                   ptr->pid=crec.pid;
+                   ptr->start=crec.start;
+                   strncpy(ptr->machine,crec.machine,30);
+                   ptr->machine[30]='\0';
+                   ptr->next=srecs;
+                   srecs=ptr;
+                 }
+             }
+           else
+             {
+               Ucrit_addPid(crec.pid);                                             /* added by OH */
+               if (processes_only) {
+                 if (last_pid != crec.pid)
+                   printf("%d\n",(int)crec.pid);
+                 last_pid = crec.pid; /* XXXX we can still get repeats, have to
+                                   add a sort at some time */
+               }
+               else      
+                 printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
+                        crec.name,uidtoname(crec.uid),gidtoname(crec.gid),(int)crec.pid,
+                        crec.machine,crec.addr,
+                        asctime(LocalTime(&crec.start)));
+             }
+         }
+      }
+    fclose(f);
   }
-
   if (processes_only) exit(0);
   
   if (brief)
@@ -327,7 +327,7 @@ static int profile_dump(void)
     ptr=srecs;
     while (ptr!=NULL)
     {
-      printf("%-8d%-10.10s%-30.30s%s",ptr->pid,uidtoname(ptr->uid),ptr->machine,asctime(LocalTime(&(ptr->start))));
+      printf("%-8d%-10.10s%-30.30s%s",(int)ptr->pid,uidtoname(ptr->uid),ptr->machine,asctime(LocalTime(&(ptr->start))));
     ptr=ptr->next;
     }
     printf("\n");
index 9bf741e24f14ae3df926ef7da22d69bf7814c9ae..e4f603e0ce27f63f7a8d3fa23686a075f6c054c6 100644 (file)
 /* these live in util.c */
 extern FILE *dbf;
 extern int DEBUGLEVEL;
-extern pstring myhostname;
 
 /***********************************************
  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();
 
@@ -85,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;
     }
   }
 
@@ -105,71 +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(!get_myname(myhostname,NULL))
-  {
-    printf("Failed to get my hostname.\n");
-    return(1);
-  }
-
-  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 if (argc == 4) {
-       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 6dea2f2d229193746ffed11047965933e73d9733..9dc9d664b2cfa7494d22ca3fee1ef2e3f169597c 100644 (file)
 
 #include "includes.h"
 
-extern int DEBUGLEVEL;
-extern pstring debugf;
-
 static fstring host, workgroup, share, password, username, myname;
 static int max_protocol = PROTOCOL_NT1;
-static char *sockops="";
+static char *sockops="TCP_NODELAY";
+static int nprocs=1, numops=100;
+static struct cli_state current_cli;
+
+static double create_procs(void (*fn)(int));
 
 
 static struct timeval tp1,tp2;
@@ -45,82 +46,101 @@ static double end_timer(void)
               (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
 }
 
-#define FAILED_NO_ERROR            0
-#define FAILED_TCP_CONNECT         1
-#define FAILED_SESSION_REQ         2
-#define FAILED_SMB_SESS_SETUP      3
-#define FAILED_SMB_TCON            4
-#define FAILED_SMB_NEGPROT         5
-#define FAILED_CLI_STATE_INIT      6
-#define NUM_ERR_STATES             7
 
-static char *smb_messages[] =
+/* return a pointer to a anonymous shared memory segment of size "size"
+   which will persist across fork() but will disappear when all processes
+   exit 
+
+   The memory is not zeroed 
+
+   This function uses system5 shared memory. It takes advantage of a property
+   that the memory is not destroyed if it is attached when the id is removed
+   */
+static void *shm_setup(int size)
 {
-       "No errors in connection",
-       "TCP connection         ",
-       "NetBIOS Session Request",
-       "SMB Session Setup      ",
-       "SMB Tcon               ",
-       "SMB Negprot            ",
-       "Client initialisation  "
-};
-
-static int open_connection(struct cli_state *c)
+       int shmid;
+       void *ret;
+
+       shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+       if (shmid == -1) {
+               printf("can't get shared memory\n");
+               exit(1);
+       }
+       ret = (void *)shmat(shmid, 0, 0);
+       if (!ret || ret == (void *)-1) {
+               printf("can't attach to shared memory\n");
+               return NULL;
+       }
+       /* the following releases the ipc, but note that this process
+          and all its children will still have access to the memory, its
+          just that the shmid is no longer valid for other shm calls. This
+          means we don't leave behind lots of shm segments after we exit 
+
+          See Stevens "advanced programming in unix env" for details
+          */
+       shmctl(shmid, IPC_RMID, 0);
+       
+       return ret;
+}
+
+
+static BOOL open_connection(struct cli_state *c)
 {
        struct nmb_name called, calling;
+       struct in_addr ip;
+       extern struct in_addr ipzero;
 
        ZERO_STRUCTP(c);
 
        make_nmb_name(&calling, myname, 0x0, "");
        make_nmb_name(&called , host, 0x20, "");
 
-       if (!cli_initialise(c))
-       {
-               DEBUG(0,("Failed to connect with %s\n", host));
-               return FAILED_CLI_STATE_INIT;
-       }
+       ip = ipzero;
 
-       if (!cli_connect(c, host, NULL)) {
-               DEBUG(0,("Failed to connect with %s\n", host));
-               return FAILED_TCP_CONNECT;
+       if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
+               printf("Failed to connect with %s\n", host);
+               return False;
        }
 
+       c->timeout = 120000; /* set a really long timeout (2 minutes) */
+
        if (!cli_session_request(c, &calling, &called)) {
+               printf("%s rejected the session\n",host);
                cli_shutdown(c);
-               DEBUG(0,("%s rejected the session\n",host));
-               return FAILED_SESSION_REQ;
+               return False;
        }
 
        if (!cli_negprot(c)) {
-               DEBUG(0,("%s rejected the negprot (%s)\n",host, cli_errstr(c)));
+               printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
                cli_shutdown(c);
-               return FAILED_SMB_NEGPROT;
+               return False;
        }
 
        if (!cli_session_setup(c, username, 
                               password, strlen(password),
                               password, strlen(password),
                               workgroup)) {
-               DEBUG(0,("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c)));
+               printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
                cli_shutdown(c);
-               return FAILED_SMB_SESS_SETUP;
+               return False;
        }
 
        if (!cli_send_tconX(c, share, "?????",
                            password, strlen(password)+1)) {
-               DEBUG(0,("%s refused tree connect (%s)\n", host, cli_errstr(c)));
+               printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
                cli_shutdown(c);
-               return FAILED_SMB_TCON;
+               return False;
        }
 
-       return FAILED_NO_ERROR;
+       return True;
 }
 
 
+
 static void close_connection(struct cli_state *c)
 {
        if (!cli_tdis(c)) {
-               DEBUG(0,("tdis failed (%s)\n", cli_errstr(c)));
+               printf("tdis failed (%s)\n", cli_errstr(c));
        }
 
        cli_shutdown(c);
@@ -133,14 +153,13 @@ static BOOL check_error(struct cli_state *c,
 {
        uint8 class;
        uint32 num;
-       int eno;
-       eno = cli_error(c, &class, &num);
+       (void)cli_error(c, &class, &num, NULL);
        if ((eclass != class || ecode != num) &&
            num != (nterr&0xFFFFFF)) {
-               DEBUG(0,("unexpected error code class=%d code=%d\n", 
-                        (int)class, (int)num));
-               DEBUG(0,(" expected %d/%d %d\n", 
-                      (int)eclass, (int)ecode, (int)nterr));
+               printf("unexpected error code class=%d code=%d\n", 
+                        (int)class, (int)num);
+               printf(" expected %d/%d %d\n", 
+                      (int)eclass, (int)ecode, (int)nterr);
                return False;
        }
        return True;
@@ -156,13 +175,13 @@ static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
 }
 
 
-static BOOL rw_torture(struct cli_state *c, int numops)
+static BOOL rw_torture(struct cli_state *c)
 {
        char *lockfname = "\\torture.lck";
        fstring fname;
        int fnum;
        int fnum2;
-       int pid2, pid = getpid();
+       pid_t pid2, pid = getpid();
        int i, j;
        char buf[1024];
 
@@ -171,7 +190,7 @@ static BOOL rw_torture(struct cli_state *c, int numops)
        if (fnum2 == -1)
                fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", lockfname, cli_errstr(c)));
+               printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
                return False;
        }
 
@@ -179,7 +198,7 @@ static BOOL rw_torture(struct cli_state *c, int numops)
        for (i=0;i<numops;i++) {
                unsigned n = (unsigned)sys_random()%10;
                if (i % 10 == 0) {
-                       DEBUG(0,("%d\r", i));
+                       printf("%d\r", i); fflush(stdout);
                }
                slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
 
@@ -189,92 +208,194 @@ static BOOL rw_torture(struct cli_state *c, int numops)
 
                fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
                if (fnum == -1) {
-                       DEBUG(0,("open failed (%s)\n", cli_errstr(c)));
+                       printf("open failed (%s)\n", cli_errstr(c));
                        break;
                }
 
                if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
-                       DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
+                       printf("write failed (%s)\n", cli_errstr(c));
                }
 
                for (j=0;j<50;j++) {
                        if (cli_write(c, fnum, 0, (char *)buf, 
                                      sizeof(pid)+(j*sizeof(buf)), 
                                      sizeof(buf)) != sizeof(buf)) {
-                               DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
+                               printf("write failed (%s)\n", cli_errstr(c));
                        }
                }
 
                pid2 = 0;
 
                if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
-                       DEBUG(0,("read failed (%s)\n", cli_errstr(c)));
+                       printf("read failed (%s)\n", cli_errstr(c));
                }
 
                if (pid2 != pid) {
-                       DEBUG(0,("data corruption!\n"));
+                       printf("data corruption!\n");
                }
 
                if (!cli_close(c, fnum)) {
-                       DEBUG(0,("close failed (%s)\n", cli_errstr(c)));
+                       printf("close failed (%s)\n", cli_errstr(c));
                }
 
                if (!cli_unlink(c, fname)) {
-                       DEBUG(0,("unlink failed (%s)\n", cli_errstr(c)));
+                       printf("unlink failed (%s)\n", cli_errstr(c));
                }
 
                if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1)) {
-                       DEBUG(0,("unlock failed (%s)\n", cli_errstr(c)));
+                       printf("unlock failed (%s)\n", cli_errstr(c));
                }
        }
 
        cli_close(c, fnum2);
        cli_unlink(c, lockfname);
 
-       DEBUG(0,("%d\n", i));
+       printf("%d\n", i);
 
        return True;
 }
 
-static void usage(void)
+static void run_torture(int dummy)
 {
-       printf("Usage: smbtorture //server/share <options>\n");
+       struct cli_state cli;
 
-       printf("\t-U user%%pass\n");
-       printf("\t-N numprocs\n");
-       printf("\t-n my_netbios_name\n");
-       printf("\t-W workgroup\n");
-       printf("\t-o num_operations\n");
-       printf("\t-O socket_options\n");
-       printf("\t-m maximum protocol\n");
-       printf("\n");
+       cli = current_cli;
 
-       exit(1);
-}
+       cli_sockopt(&cli, sockops);
 
+       rw_torture(&cli);
+       
+       close_connection(&cli);
+}
 
+int line_count = 0;
 
-static void run_torture(int numops)
+/* run a test that simulates an approximate netbench client load */
+static void run_netbench(int client)
 {
-       static struct cli_state cli;
+       struct cli_state cli;
+       int i;
+       fstring fname;
+       pstring line;
+       char cname[20];
+       FILE *f;
+       char *params[20];
+
+       cli = current_cli;
+
+       cli_sockopt(&cli, sockops);
 
-       if (open_connection(&cli) == 0)
-       {
-               cli_sockopt(&cli, sockops);
+       nb_setup(&cli);
 
-               DEBUG(0,("pid %d OK\n", getpid()));
+       slprintf(cname,sizeof(fname), "CLIENT%d", client);
 
-               rw_torture(&cli, numops);
+       f = fopen("client.txt", "r");
 
-               close_connection(&cli);
+       if (!f) {
+               perror("client.txt");
+               return;
        }
-       else
-       {
-               DEBUG(0,("pid %d failed\n", getpid()));
+
+       while (fgets(line, sizeof(line)-1, f)) {
+               line_count++;
+
+               line[strlen(line)-1] = 0;
+
+               /* printf("[%d] %s\n", line_count, line); */
+
+               all_string_sub(line,"CLIENT1", cname, sizeof(line));
+               
+               for (i=0;i<20;i++) params[i] = "";
+
+               /* parse the command parameters */
+               params[0] = strtok(line," ");
+               i = 0;
+               while (params[i]) params[++i] = strtok(NULL," ");
+
+               params[i] = "";
+
+               if (i < 2) continue;
+
+               if (strcmp(params[1],"REQUEST") == 0) {
+                       if (!strcmp(params[0],"SMBopenX")) {
+                               fstrcpy(fname, params[5]);
+                       } else if (!strcmp(params[0],"SMBclose")) {
+                               nb_close(atoi(params[3]));
+                       } else if (!strcmp(params[0],"SMBmkdir")) {
+                               nb_mkdir(params[3]);
+                       } else if (!strcmp(params[0],"CREATE")) {
+                               nb_create(params[3], atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBrmdir")) {
+                               nb_rmdir(params[3]);
+                       } else if (!strcmp(params[0],"SMBunlink")) {
+                               fstrcpy(fname, params[3]);
+                       } else if (!strcmp(params[0],"SMBmv")) {
+                               nb_rename(params[3], params[5]);
+                       } else if (!strcmp(params[0],"SMBgetatr")) {
+                               fstrcpy(fname, params[3]);
+                       } else if (!strcmp(params[0],"SMBwrite")) {
+                               nb_write(atoi(params[3]), 
+                                        atoi(params[5]), atoi(params[7]));
+                       } else if (!strcmp(params[0],"SMBwritebraw")) {
+                               nb_write(atoi(params[3]), 
+                                        atoi(params[7]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBreadbraw")) {
+                               nb_read(atoi(params[3]), 
+                                        atoi(params[7]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBread")) {
+                               nb_read(atoi(params[3]), 
+                                        atoi(params[5]), atoi(params[7]));
+                       }
+               } else {
+                       if (!strcmp(params[0],"SMBopenX")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_open(fname, atoi(params[3]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBgetatr")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_stat(fname, atoi(params[3]));
+                       } else if (!strcmp(params[0],"SMBunlink")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_unlink(fname);
+                       }
+               }
        }
+       fclose(f);
+
+       slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
+       rmdir(fname);
+       rmdir("CLIENTS");
 
+       printf("+");    
+
+       close_connection(&cli);
 }
 
+
+/* run a test that simulates an approximate netbench w9X client load */
+static void run_nbw95(int dummy)
+{
+       double t;
+       t = create_procs(run_netbench);
+       /* to produce a netbench result we scale accoding to the
+           netbench measured throughput for the run that produced the
+           sniff that was used to produce client.txt. That run used 2
+           clients and ran for 660 seconds to produce a result of
+           4MBit/sec. */
+       printf("Throughput %g MB/sec (NB=%g MB/sec  %g MBit/sec)\n", 
+              132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
+}
+
+/* run a test that simulates an approximate netbench wNT client load */
+static void run_nbwnt(int dummy)
+{
+       double t;
+       t = create_procs(run_netbench);
+       printf("Throughput %g MB/sec (NB=%g MB/sec  %g MBit/sec)\n", 
+              132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
+}
+
+
+
 /*
   This test checks for two things:
 
@@ -282,57 +403,57 @@ static void run_torture(int numops)
      must not use posix semantics)
   2) support for lock timeouts
  */
-static void run_locktest1(void)
+static void run_locktest1(int dummy)
 {
        static struct cli_state cli1, cli2;
        char *fname = "\\lockt1.lck";
        int fnum1, fnum2, fnum3;
        time_t t1, t2;
 
-       if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
+       if (!open_connection(&cli1) || !open_connection(&cli2)) {
                return;
        }
        cli_sockopt(&cli1, sockops);
        cli_sockopt(&cli2, sockops);
 
-       DEBUG(0,("starting locktest1\n"));
+       printf("starting locktest1\n");
 
        cli_unlink(&cli1, fname);
 
        fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
                return;
        }
        fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1)));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
                return;
        }
        fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
        if (fnum3 == -1) {
-               DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
+               printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
                return;
        }
 
        if (!cli_lock(&cli1, fnum1, 0, 4, 0)) {
-               DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli1)));
+               printf("lock1 failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
 
        if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
-               DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
+               printf("lock2 succeeded! This is a locking bug\n");
                return;
        } else {
                if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
        }
 
 
-       DEBUG(0,("Testing lock timeouts\n"));
+       printf("Testing lock timeouts\n");
        t1 = time(NULL);
        if (cli_lock(&cli2, fnum3, 0, 4, 10*1000)) {
-               DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
+               printf("lock3 succeeded! This is a locking bug\n");
                return;
        } else {
                if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
@@ -340,33 +461,33 @@ static void run_locktest1(void)
        t2 = time(NULL);
 
        if (t2 - t1 < 5) {
-               DEBUG(0,("error: This server appears not to support timed lock requests\n"));
+               printf("error: This server appears not to support timed lock requests\n");
        }
 
        if (!cli_close(&cli1, fnum2)) {
-               DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
+               printf("close1 failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
        if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
-               DEBUG(0,("lock4 succeeded! This is a locking bug\n"));
+               printf("lock4 succeeded! This is a locking bug\n");
                return;
        } else {
                if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
        }
 
        if (!cli_close(&cli1, fnum1)) {
-               DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli1)));
+               printf("close2 failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
        if (!cli_close(&cli2, fnum3)) {
-               DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli2)));
+               printf("close3 failed (%s)\n", cli_errstr(&cli2));
                return;
        }
 
        if (!cli_unlink(&cli1, fname)) {
-               DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
+               printf("unlink failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
@@ -374,7 +495,7 @@ static void run_locktest1(void)
        close_connection(&cli1);
        close_connection(&cli2);
 
-       DEBUG(0,("Passed locktest1\n"));
+       printf("Passed locktest1\n");
 }
 
 
@@ -389,19 +510,19 @@ static void run_locktest1(void)
 
   3) the server denies unlock requests by an incorrect client PID
 */
-static void run_locktest2(void)
+static void run_locktest2(int dummy)
 {
        static struct cli_state cli;
        char *fname = "\\lockt2.lck";
        int fnum1, fnum2, fnum3;
 
-       if (open_connection(&cli) != 0) {
+       if (!open_connection(&cli)) {
                return;
        }
 
        cli_sockopt(&cli, sockops);
 
-       DEBUG(0,("starting locktest2\n"));
+       printf("starting locktest2\n");
 
        cli_unlink(&cli, fname);
 
@@ -409,13 +530,13 @@ static void run_locktest2(void)
 
        fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
                return;
        }
 
        fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli)));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
                return;
        }
 
@@ -423,19 +544,19 @@ static void run_locktest2(void)
 
        fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
        if (fnum3 == -1) {
-               DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli)));
+               printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
                return;
        }
 
        cli_setpid(&cli, 1);
 
        if (!cli_lock(&cli, fnum1, 0, 4, 0)) {
-               DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli)));
+               printf("lock1 failed (%s)\n", cli_errstr(&cli));
                return;
        }
 
        if (cli_lock(&cli, fnum2, 0, 4, 0)) {
-               DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
+               printf("lock2 succeeded! This is a locking bug\n");
        } else {
                if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
        }
@@ -443,11 +564,11 @@ static void run_locktest2(void)
        cli_setpid(&cli, 2);
 
        if (cli_unlock(&cli, fnum1, 0, 4, 0)) {
-               DEBUG(0,("unlock1 succeeded! This is a locking bug\n"));
+               printf("unlock1 succeeded! This is a locking bug\n");
        }
 
        if (cli_lock(&cli, fnum3, 0, 4, 0)) {
-               DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
+               printf("lock3 succeeded! This is a locking bug\n");
        } else {
                if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
        }
@@ -455,23 +576,23 @@ static void run_locktest2(void)
        cli_setpid(&cli, 1);
 
        if (!cli_close(&cli, fnum1)) {
-               DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli)));
+               printf("close1 failed (%s)\n", cli_errstr(&cli));
                return;
        }
 
        if (!cli_close(&cli, fnum2)) {
-               DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli)));
+               printf("close2 failed (%s)\n", cli_errstr(&cli));
                return;
        }
 
        if (!cli_close(&cli, fnum3)) {
-               DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli)));
+               printf("close3 failed (%s)\n", cli_errstr(&cli));
                return;
        }
 
        close_connection(&cli);
 
-       DEBUG(0,("locktest2 finished\n"));
+       printf("locktest2 finished\n");
 }
 
 
@@ -480,7 +601,7 @@ static void run_locktest2(void)
 
   1) the server supports the full offset range in lock requests
 */
-static void run_locktest3(int numops)
+static void run_locktest3(int dummy)
 {
        static struct cli_state cli1, cli2;
        char *fname = "\\lockt3.lck";
@@ -489,40 +610,40 @@ static void run_locktest3(int numops)
 
 #define NEXT_OFFSET offset += (~(uint32)0) / numops
 
-       if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
+       if (!open_connection(&cli1) || !open_connection(&cli2)) {
                return;
        }
        cli_sockopt(&cli1, sockops);
        cli_sockopt(&cli2, sockops);
 
-       DEBUG(0,("starting locktest3\n"));
+       printf("starting locktest3\n");
 
        cli_unlink(&cli1, fname);
 
        fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
                return;
        }
        fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
                return;
        }
 
        for (offset=i=0;i<numops;i++) {
                NEXT_OFFSET;
                if (!cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
-                       DEBUG(0,("lock1 %d failed (%s)\n", 
+                       printf("lock1 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1)));
+                              cli_errstr(&cli1));
                        return;
                }
 
                if (!cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
-                       DEBUG(0,("lock2 %d failed (%s)\n", 
+                       printf("lock2 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1)));
+                              cli_errstr(&cli1));
                        return;
                }
        }
@@ -531,22 +652,22 @@ static void run_locktest3(int numops)
                NEXT_OFFSET;
 
                if (cli_lock(&cli1, fnum1, offset-2, 1, 0)) {
-                       DEBUG(0,("error: lock1 %d succeeded!\n", i));
+                       printf("error: lock1 %d succeeded!\n", i);
                        return;
                }
 
                if (cli_lock(&cli2, fnum2, offset-1, 1, 0)) {
-                       DEBUG(0,("error: lock2 %d succeeded!\n", i));
+                       printf("error: lock2 %d succeeded!\n", i);
                        return;
                }
 
                if (cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
-                       DEBUG(0,("error: lock3 %d succeeded!\n", i));
+                       printf("error: lock3 %d succeeded!\n", i);
                        return;
                }
 
                if (cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
-                       DEBUG(0,("error: lock4 %d succeeded!\n", i));
+                       printf("error: lock4 %d succeeded!\n", i);
                        return;
                }
        }
@@ -555,37 +676,37 @@ static void run_locktest3(int numops)
                NEXT_OFFSET;
 
                if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0)) {
-                       DEBUG(0,("unlock1 %d failed (%s)\n", 
+                       printf("unlock1 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1)));
+                              cli_errstr(&cli1));
                        return;
                }
 
                if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0)) {
-                       DEBUG(0,("unlock2 %d failed (%s)\n", 
+                       printf("unlock2 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1)));
+                              cli_errstr(&cli1));
                        return;
                }
        }
 
        if (!cli_close(&cli1, fnum1)) {
-               DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
+               printf("close1 failed (%s)\n", cli_errstr(&cli1));
        }
 
        if (!cli_close(&cli2, fnum2)) {
-               DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli2)));
+               printf("close2 failed (%s)\n", cli_errstr(&cli2));
        }
 
        if (!cli_unlink(&cli1, fname)) {
-               DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
+               printf("unlink failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
        close_connection(&cli1);
        close_connection(&cli2);
 
-       DEBUG(0,("finished locktest3\n"));
+       printf("finished locktest3\n");
 }
 
 
@@ -593,31 +714,31 @@ static void run_locktest3(int numops)
 test whether fnums and tids open on one VC are available on another (a major
 security hole)
 */
-static void run_fdpasstest(void)
+static void run_fdpasstest(int dummy)
 {
        static struct cli_state cli1, cli2;
        char *fname = "\\fdpass.tst";
        int fnum1;
        pstring buf;
 
-       if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
+       if (!open_connection(&cli1) || !open_connection(&cli2)) {
                return;
        }
        cli_sockopt(&cli1, sockops);
        cli_sockopt(&cli2, sockops);
 
-       DEBUG(0,("starting fdpasstest\n"));
+       printf("starting fdpasstest\n");
 
        cli_unlink(&cli1, fname);
 
        fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
                return;
        }
 
        if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
-               DEBUG(0,("write failed (%s)\n", cli_errstr(&cli1)));
+               printf("write failed (%s)\n", cli_errstr(&cli1));
                return;
        }
 
@@ -627,8 +748,8 @@ static void run_fdpasstest(void)
 
 
        if (cli_read(&cli2, fnum1, buf, 0, 13) == 13) {
-               DEBUG(0,("read succeeded! nasty security hole [%s]\n",
-                      buf));
+               printf("read succeeded! nasty security hole [%s]\n",
+                      buf);
                return;
        }
 
@@ -638,7 +759,7 @@ static void run_fdpasstest(void)
        close_connection(&cli1);
        close_connection(&cli2);
 
-       DEBUG(0,("finished fdpasstest\n"));
+       printf("finished fdpasstest\n");
 }
 
 
@@ -647,19 +768,19 @@ static void run_fdpasstest(void)
 
   1) the server does not allow an unlink on a file that is open
 */
-static void run_unlinktest(void)
+static void run_unlinktest(int dummy)
 {
        static struct cli_state cli;
        char *fname = "\\unlink.tst";
        int fnum;
 
-       if (open_connection(&cli) != 0) {
+       if (!open_connection(&cli)) {
                return;
        }
 
        cli_sockopt(&cli, sockops);
 
-       DEBUG(0,("starting unlink test\n"));
+       printf("starting unlink test\n");
 
        cli_unlink(&cli, fname);
 
@@ -667,12 +788,12 @@ static void run_unlinktest(void)
 
        fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum == -1) {
-               DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
                return;
        }
 
        if (cli_unlink(&cli, fname)) {
-               DEBUG(0,("error: server allowed unlink on an open file\n"));
+               printf("error: server allowed unlink on an open file\n");
        }
 
        cli_close(&cli, fnum);
@@ -680,59 +801,56 @@ static void run_unlinktest(void)
 
        close_connection(&cli);
 
-       DEBUG(0,("unlink test finished\n"));
+       printf("unlink test finished\n");
 }
 
 
 /*
 test how many open files this server supports on the one socket
 */
-static void run_maxfidtest(int n)
+static void run_maxfidtest(int dummy)
 {
        static struct cli_state cli;
        char *template = "\\maxfid.%d.%d";
        fstring fname;
        int fnum;
        int retries=4;
+       int n = numops;
 
-       srandom(getpid());
-
-       while (open_connection(&cli) != 0 && retries--) msleep(random() % 2000);
+       cli = current_cli;
 
        if (retries <= 0) {
-               DEBUG(0,("failed to connect\n"));
+               printf("failed to connect\n");
                return;
        }
 
        cli_sockopt(&cli, sockops);
 
-       DEBUG(0,("starting maxfid test\n"));
-
        fnum = 0;
        while (1) {
-               slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
+               slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
                if (cli_open(&cli, fname, 
                             O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
                    -1) {
-                       DEBUG(0,("open of %s failed (%s)\n", 
-                              fname, cli_errstr(&cli)));
-                       DEBUG(0,("maximum fnum is %d\n", fnum));
+                       printf("open of %s failed (%s)\n", 
+                              fname, cli_errstr(&cli));
+                       printf("maximum fnum is %d\n", fnum);
                        break;
                }
                fnum++;
        }
 
-       DEBUG(0,("cleaning up\n"));
+       printf("cleaning up\n");
        while (fnum > n) {
                fnum--;
-               slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
+               slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
                if (cli_unlink(&cli, fname)) {
-                       DEBUG(0,("unlink of %s failed (%s)\n", 
-                              fname, cli_errstr(&cli)));
+                       printf("unlink of %s failed (%s)\n", 
+                              fname, cli_errstr(&cli));
                }
        }
 
-       DEBUG(0,("maxfid test finished\n"));
+       printf("maxfid test finished\n");
        close_connection(&cli);
 }
 
@@ -740,116 +858,45 @@ static void run_maxfidtest(int n)
 static void rand_buf(char *buf, int len)
 {
        while (len--) {
-               *buf = sys_random();
+               *buf = (char)sys_random();
                buf++;
        }
 }
 
-#define TORT_BUFFER_SIZE 1024
-
 /* send random IPC commands */
-static void run_randomipc(int numops)
+static void run_randomipc(int dummy)
 {
        char *rparam = NULL;
        char *rdata = NULL;
        int rdrcnt,rprcnt;
-       char param[TORT_BUFFER_SIZE];
+       pstring param;
        int api, param_len, i;
-       int reconnect_count = 500;
        static struct cli_state cli;
 
-       DEBUG(0,("starting random ipc test\n"));
-
-       while (reconnect_count > 0 && open_connection(&cli) != 0)
-       {
-               DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
-               msleep(sys_random() % 5000);
-               reconnect_count--;
-       }
+       printf("starting random ipc test\n");
 
-       if (reconnect_count == 0)
-       {
+       if (!open_connection(&cli)) {
                return;
        }
 
-       for (i=0;i<numops * 100;i++)
-       {
+       for (i=0;i<50000;i++) {
                api = sys_random() % 500;
-               if ((sys_random() % 10) == 0)
-               {
-                       param_len = (sys_random() % TORT_BUFFER_SIZE);
-               }
-               else
-               {
-                       param_len = (sys_random() % 64);
-               }
+               param_len = (sys_random() % 64);
 
                rand_buf(param, param_len);
   
                SSVAL(param,0,api); 
 
-               cli_api(&cli,
+               cli_api(&cli, 
                        param, param_len, 8,  
                        NULL, 0, BUFFER_SIZE, 
-                       &rparam, &rprcnt,
+                       &rparam, &rprcnt,     
                        &rdata, &rdrcnt);
        }
 
        close_connection(&cli);
 
-       DEBUG(0,("finished random ipc test\n"));
-}
-
-/* send random IPC commands */
-static void run_randomipc_nowait(int numops)
-{
-       char param[TORT_BUFFER_SIZE];
-       int api, param_len, i;
-       int reconnect_count = 500;
-       static struct cli_state cli;
-
-       DEBUG(0,("start random ipc test no waiting for SMBtrans response\n"));
-
-       while (reconnect_count > 0 && open_connection(&cli) != 0)
-       {
-               DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
-               msleep(sys_random() % 5000);
-               reconnect_count--;
-       }
-
-       if (reconnect_count == 0)
-       {
-               return;
-       }
-
-       for (i=0;i<numops * 100;i++)
-       {
-               api = sys_random() % 500;
-               if ((sys_random() % 10) == 0)
-               {
-                       param_len = (sys_random() % TORT_BUFFER_SIZE);
-               }
-               else
-               {
-                       param_len = (sys_random() % 64);
-               }
-
-               rand_buf(param, param_len);
-  
-               SSVAL(param,0,api); 
-
-               cli_send_trans(&cli,SMBtrans,
-                       PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */
-                       0,0,                             /* fid, flags */
-                       NULL,0,0,                /* Setup, length, max */
-
-                       param, param_len, 8,  
-                       NULL, 0, BUFFER_SIZE);
-       }
-
-       close_connection(&cli);
-
-       DEBUG(0,("finished random ipc test\n"));
+       printf("finished random ipc test\n");
 }
 
 
@@ -857,7 +904,7 @@ static void run_randomipc_nowait(int numops)
 static void browse_callback(const char *sname, uint32 stype, 
                            const char *comment)
 {
-       DEBUG(0,("\t%20.20s %08x %s\n", sname, stype, comment));
+       printf("\t%20.20s %08x %s\n", sname, stype, comment);
 }
 
 
@@ -866,45 +913,45 @@ static void browse_callback(const char *sname, uint32 stype,
   This test checks the browse list code
 
 */
-static void run_browsetest(void)
+static void run_browsetest(int dummy)
 {
        static struct cli_state cli;
 
-       DEBUG(0,("starting browse test\n"));
+       printf("starting browse test\n");
 
-       if (open_connection(&cli) != 0) {
+       if (!open_connection(&cli)) {
                return;
        }
 
-       DEBUG(0,("domain list:\n"));
-       cli_NetServerEnum(&cli, workgroup
+       printf("domain list:\n");
+       cli_NetServerEnum(&cli, cli.server_domain
                          SV_TYPE_DOMAIN_ENUM,
                          browse_callback);
 
-       DEBUG(0,("machine list:\n"));
-       cli_NetServerEnum(&cli, workgroup
+       printf("machine list:\n");
+       cli_NetServerEnum(&cli, cli.server_domain
                          SV_TYPE_ALL,
                          browse_callback);
 
        close_connection(&cli);
 
-       DEBUG(0,("browse test finished\n"));
+       printf("browse test finished\n");
 }
 
 
 /*
   This checks how the getatr calls works
 */
-static void run_attrtest(void)
+static void run_attrtest(int dummy)
 {
        static struct cli_state cli;
        int fnum;
        time_t t, t2;
        char *fname = "\\attrib.tst";
 
-       DEBUG(0,("starting attrib test\n"));
+       printf("starting attrib test\n");
 
-       if (open_connection(&cli) != 0) {
+       if (!open_connection(&cli)) {
                return;
        }
 
@@ -913,43 +960,43 @@ static void run_attrtest(void)
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        cli_close(&cli, fnum);
        if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
-               DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
+               printf("getatr failed (%s)\n", cli_errstr(&cli));
        }
 
        if (abs(t - time(NULL)) > 2) {
-               DEBUG(0,("ERROR: SMBgetatr bug. time is %s",
-                      ctime(&t)));
+               printf("ERROR: SMBgetatr bug. time is %s",
+                      ctime(&t));
                t = time(NULL);
        }
 
        t2 = t-60*60*24; /* 1 day ago */
 
        if (!cli_setatr(&cli, fname, 0, t2)) {
-               DEBUG(0,("setatr failed (%s)\n", cli_errstr(&cli)));
+               printf("setatr failed (%s)\n", cli_errstr(&cli));
        }
 
        if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
-               DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
+               printf("getatr failed (%s)\n", cli_errstr(&cli));
        }
 
        if (t != t2) {
-               DEBUG(0,("ERROR: getatr/setatr bug. times are\n%s",
-                      ctime(&t)));
-               DEBUG(0,("%s", ctime(&t2)));
+               printf("ERROR: getatr/setatr bug. times are\n%s",
+                      ctime(&t));
+               printf("%s", ctime(&t2));
        }
 
        cli_unlink(&cli, fname);
 
        close_connection(&cli);
 
-       DEBUG(0,("attrib test finished\n"));
+       printf("attrib test finished\n");
 }
 
 
 /*
   This checks a couple of trans2 calls
 */
-static void run_trans2test(void)
+static void run_trans2test(int dummy)
 {
        static struct cli_state cli;
        int fnum;
@@ -959,9 +1006,9 @@ static void run_trans2test(void)
        char *dname = "\\trans2";
        char *fname2 = "\\trans2\\trans2.tst";
 
-       DEBUG(0,("starting trans2 test\n"));
+       printf("starting trans2 test\n");
 
-       if (open_connection(&cli) != 0) {
+       if (!open_connection(&cli)) {
                return;
        }
 
@@ -970,7 +1017,7 @@ static void run_trans2test(void)
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
                           NULL, NULL)) {
-               DEBUG(0,("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
        }
        cli_close(&cli, fnum);
 
@@ -982,20 +1029,20 @@ static void run_trans2test(void)
        cli_close(&cli, fnum);
 
        if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
-               DEBUG(0,("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
        } else {
                if (c_time != m_time) {
-                       DEBUG(0,("create time=%s", ctime(&c_time)));
-                       DEBUG(0,("modify time=%s", ctime(&m_time)));
-                       DEBUG(0,("This system appears to have sticky create times\n"));
+                       printf("create time=%s", ctime(&c_time));
+                       printf("modify time=%s", ctime(&m_time));
+                       printf("This system appears to have sticky create times\n");
                }
                if (a_time % (60*60) == 0) {
-                       DEBUG(0,("access time=%s", ctime(&a_time)));
-                       DEBUG(0,("This system appears to set a midnight access time\n"));
+                       printf("access time=%s", ctime(&a_time));
+                       printf("This system appears to set a midnight access time\n");
                }
 
                if (abs(m_time - time(NULL)) > 60*60*24*7) {
-                       DEBUG(0,("ERROR: totally incorrect times - maybe word reversed?\n"));
+                       printf("ERROR: totally incorrect times - maybe word reversed?\n");
                }
        }
 
@@ -1006,11 +1053,11 @@ static void run_trans2test(void)
        cli_close(&cli, fnum);
        if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
                            &w_time, &size, NULL, NULL)) {
-               DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
        } else {
                if (w_time < 60*60*24*2) {
-                       DEBUG(0,("write time=%s", ctime(&w_time)));
-                       DEBUG(0,("This system appears to set a initial 0 write time\n"));
+                       printf("write time=%s", ctime(&w_time));
+                       printf("This system appears to set a initial 0 write time\n");
                }
        }
 
@@ -1020,12 +1067,12 @@ static void run_trans2test(void)
        /* check if the server updates the directory modification time
            when creating a new file */
        if (!cli_mkdir(&cli, dname)) {
-               DEBUG(0,("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
        }
        sleep(3);
        if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
                            &w_time, &size, NULL, NULL)) {
-               DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
        }
 
        fnum = cli_open(&cli, fname2, 
@@ -1034,10 +1081,10 @@ static void run_trans2test(void)
        cli_close(&cli, fnum);
        if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
                            &w_time, &size, NULL, NULL)) {
-               DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
        } else {
                if (m_time2 == m_time)
-                       DEBUG(0,("This system does not update directory modification times\n"));
+                       printf("This system does not update directory modification times\n");
        }
        cli_unlink(&cli, fname2);
        cli_rmdir(&cli, dname);
@@ -1045,105 +1092,298 @@ static void run_trans2test(void)
 
        close_connection(&cli);
 
-       DEBUG(0,("trans2 test finished\n"));
+       printf("trans2 test finished\n");
 }
 
 
-static void run_connection(int numops)
+/*
+  this is a harness for some oplock tests
+ */
+static void run_oplock(int dummy)
 {
-       struct cli_state c;
-       int count = 0;
-       int failed[NUM_ERR_STATES];
-       int i;
+       static struct cli_state cli1, cli2;
+       char *fname = "\\lockt1.lck";
+       char *fname2 = "\\lockt2.lck";
+       int fnum1, fnum2;
 
-       DEBUG(0,("Connection test starts:\n"));
+       printf("starting oplock test\n");
 
-       for (i = 0; i < NUM_ERR_STATES; i++)
-       {
-               failed[i] = 0;
+       if (!open_connection(&cli1)) {
+               return;
        }
 
-       for (i = 0; i < numops; i++)
-       {
-               int err;
-               DEBUG(0,("Connection test %d %d\n", i, numops));
-               if ((err = open_connection(&c)))
-               {
-                       failed[err]++;
-               }
-               count++;
+       cli_unlink(&cli1, fname);
+
+       cli_sockopt(&cli1, sockops);
+
+       cli1.use_oplocks = True;
+
+       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum1 == -1) {
+               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               return;
+       }
+
+       cli1.use_oplocks = False;
+
+       cli_unlink(&cli1, fname);
+       cli_unlink(&cli1, fname);
+
+       if (!cli_close(&cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+               return;
        }
 
-       {
-               int failtotal = 0;
+       if (!cli_unlink(&cli1, fname)) {
+               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+               return;
+       }
+
+
+       close_connection(&cli1);
+
+       printf("finished oplock test\n");
+}
+
+
+static void list_fn(file_info *finfo, const char *name)
+{
+       
+}
+
+/*
+  test directory listing speed
+ */
+static void run_dirtest(int dummy)
+{
+       int i;
+       static struct cli_state cli;
+       int fnum;
+       double t1;
+
+       printf("starting directory test\n");
+
+       if (!open_connection(&cli)) {
+               return;
+       }
+
+       cli_sockopt(&cli, sockops);
 
-               for (i = 0, failtotal = 0; i < NUM_ERR_STATES; i++)
-               {
-                       failtotal += failed[i];
+       srandom(0);
+       for (i=0;i<numops;i++) {
+               fstring fname;
+               slprintf(fname, sizeof(fname), "%x", random());
+               fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
+               if (fnum == -1) {
+                       fprintf(stderr,"Failed to open %s\n", fname);
+                       return;
                }
-               DEBUG(0,("Connection test results: count %d success %d\n", count, count-failtotal));
+               cli_close(&cli, fnum);
        }
-       for (i = 0; i < NUM_ERR_STATES; i++)
-       {
-               DEBUG(0,("%s: failed: %d\n", smb_messages[i], failed[i]));
+
+       t1 = end_timer();
+
+       printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn));
+       printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn));
+       printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn));
+
+       printf("dirtest core %g seconds\n", end_timer() - t1);
+
+       srandom(0);
+       for (i=0;i<numops;i++) {
+               fstring fname;
+               slprintf(fname, sizeof(fname), "%x", random());
+               cli_unlink(&cli, fname);
        }
+
+       close_connection(&cli);
+
+       printf("finished dirtest\n");
 }
 
-static void create_procs(int nprocs, int numops, void (*fn)(int ))
+
+
+static double create_procs(void (*fn)(int))
 {
        int i, status;
+       volatile int *child_status;
+       int synccount;
+       int tries = 8;
 
-       for (i=0;i<nprocs;i++)
-       {
-               if (fork() == 0)
-               {
-                       int mypid = getpid();
-                       sys_srandom(mypid ^ time(NULL));
-
-                       if (!dbg_interactive())
-                       {
-                               slprintf(debugf, sizeof(debugf), "./log.torture.%d", mypid);
-                               reopen_logs();
+       start_timer();
+
+       synccount = 0;
+
+       child_status = (volatile int *)shm_setup(sizeof(int)*nprocs);
+       if (!child_status) {
+               printf("Failed to setup shared memory\n");
+               return end_timer();
+       }
+
+       memset((char *)child_status, 0, sizeof(int)*nprocs);
+
+       for (i=0;i<nprocs;i++) {
+               if (fork() == 0) {
+                       pid_t mypid = getpid();
+                       sys_srandom(((int)mypid) ^ ((int)time(NULL)));
+
+                       slprintf(myname,sizeof(myname),"CLIENT%d", i);
+
+                       while (1) {
+                               memset(&current_cli, 0, sizeof(current_cli));
+                               if (open_connection(&current_cli)) break;
+                               if (tries-- == 0) {
+                                       printf("pid %d failed to start\n", (int)getpid());
+                                       _exit(1);
+                               }
+                               msleep(10);
                        }
 
-                       fn(numops);
-                       dbgflush();
+                       child_status[i] = getpid();
+
+                       while (child_status[i]) msleep(2);
+
+                       fn(i);
                        _exit(0);
                }
        }
 
-       for (i=0;i<nprocs;i++)
-       {
+       do {
+               synccount = 0;
+               for (i=0;i<nprocs;i++) {
+                       if (child_status[i]) synccount++;
+               }
+               if (synccount == nprocs) break;
+               msleep(10);
+       } while (end_timer() < 30);
+
+       if (synccount != nprocs) {
+               printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
+               return end_timer();
+       }
+
+       /* start the client load */
+       start_timer();
+
+       for (i=0;i<nprocs;i++) {
+               child_status[i] = 0;
+       }
+
+       printf("%d clients started\n", nprocs);
+
+       for (i=0;i<nprocs;i++) {
                waitpid(0, &status, 0);
+               printf("*");
        }
+       printf("\n");
+       return end_timer();
 }
 
 
+#define FLAG_MULTIPROC 1
+
+static struct {
+       char *name;
+       void (*fn)(int);
+       unsigned flags;
+} torture_ops[] = {
+       {"FDPASS", run_fdpasstest, 0},
+       {"LOCK1",  run_locktest1,  0},
+       {"LOCK2",  run_locktest2,  0},
+       {"LOCK3",  run_locktest3,  0},
+       {"UNLINK", run_unlinktest, 0},
+       {"BROWSE", run_browsetest, 0},
+       {"ATTR",   run_attrtest,   0},
+       {"TRANS2", run_trans2test, 0},
+       {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
+       {"TORTURE",run_torture,    FLAG_MULTIPROC},
+       {"RANDOMIPC", run_randomipc, 0},
+       {"NBW95",  run_nbw95, 0},
+       {"NBWNT",  run_nbwnt, 0},
+       {"OPLOCK",  run_oplock, 0},
+       {"DIR",  run_dirtest, 0},
+       {NULL, NULL, 0}};
+
+
+/****************************************************************************
+run a specified test or "ALL"
+****************************************************************************/
+static void run_test(char *name)
+{
+       int i;
+       if (strequal(name,"ALL")) {
+               for (i=0;torture_ops[i].name;i++) {
+                       run_test(torture_ops[i].name);
+               }
+       }
+       
+       for (i=0;torture_ops[i].name;i++) {
+               if (strequal(name, torture_ops[i].name)) {
+                       start_timer();
+                       printf("Running %s\n", name);
+                       if (torture_ops[i].flags & FLAG_MULTIPROC) {
+                               create_procs(torture_ops[i].fn);
+                       } else {
+                               torture_ops[i].fn(0);
+                       }
+                       printf("%s took %g secs\n\n", name, end_timer());
+               }
+       }
+}
+
+
+static void usage(void)
+{
+       int i;
+
+       printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
+
+       printf("\t-U user%%pass\n");
+       printf("\t-N numprocs\n");
+       printf("\t-n my_netbios_name\n");
+       printf("\t-W workgroup\n");
+       printf("\t-o num_operations\n");
+       printf("\t-O socket_options\n");
+       printf("\t-m maximum protocol\n");
+       printf("\n\n");
+
+       printf("tests are:");
+       for (i=0;torture_ops[i].name;i++) {
+               printf(" %s", torture_ops[i].name);
+       }
+       printf("\n");
+
+       printf("default test is ALL\n");
+       
+       exit(1);
+}
+
+
+
 
-#define DEBUG_INTERACTIVE True
 
 /****************************************************************************
   main program
 ****************************************************************************/
  int main(int argc,char *argv[])
 {
-       int nprocs=1, numops=100;
-       int opt;
+       int opt, i;
        char *p;
        int gotpass = 0;
        extern char *optarg;
        extern int optind;
-       extern BOOL append_log;
-       extern BOOL timestamp_log;
+       extern FILE *dbf;
+       static pstring servicesf = CONFIGFILE;
+
+       dbf = stdout;
 
-       DEBUGLEVEL = 0;
-       pstrcpy(debugf,"./log.torture");
-       setup_logging(argv[0], DEBUG_INTERACTIVE);
-       append_log = True;
-       timestamp_log = False;
+       setbuffer(stdout, NULL, 0);
 
        charset_initialise();
 
+       lp_load(servicesf,True,False,False);
+       load_interfaces();
+
        if (argc < 2) {
                usage();
        }
@@ -1164,7 +1404,7 @@ static void create_procs(int nprocs, int numops, void (*fn)(int ))
        *p = 0;
        fstrcpy(share, p+1);
 
-       get_myname(myname,NULL);
+       get_myname(myname);
 
        if (*username == 0 && getenv("LOGNAME")) {
          pstrcpy(username,getenv("LOGNAME"));
@@ -1174,6 +1414,8 @@ static void create_procs(int nprocs, int numops, void (*fn)(int ))
        argv++;
 
 
+       fstrcpy(workgroup, lp_workgroup());
+
        while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
                switch (opt) {
                case 'W':
@@ -1218,35 +1460,16 @@ static void create_procs(int nprocs, int numops, void (*fn)(int ))
                }
        }
 
-       printf("host=%s share=%s user=%s myname=%s procs=%d ops=%d\n", 
-              host, share, username, myname, nprocs, numops);
+       printf("host=%s share=%s user=%s myname=%s\n", 
+              host, share, username, myname);
 
-       create_procs(nprocs, numops, run_randomipc);
-/*
-       create_procs(nprocs, numops, run_randomipc_nowait);
-
-       create_procs(nprocs, numops, run_connection);
-
-       run_fdpasstest();
-       run_locktest1();
-       run_locktest2();
-       run_locktest3(numops);
-       run_unlinktest();
-       run_browsetest();
-       run_attrtest();
-       run_trans2test();
-
-       create_procs(nprocs, numops, run_maxfidtest);
-
-
-
-       start_timer();
-       create_procs(nprocs, numops, run_torture);
-       printf("rw_torture: %g secs\n", end_timer());
-*/
-       dbgflush();
+       if (argc == 1) {
+               run_test("ALL");
+       } else {
+               for (i=1;i<argc;i++) {
+                       run_test(argv[i]);
+               }
+       }
 
        return(0);
 }
-
-
index 305c173a5d07b056753e35f1a2f460bef447b70f..62a5e71e0516a1c8979891c5427b13c6da528cf0 100644 (file)
@@ -333,7 +333,7 @@ handle a http authentication line
 static BOOL cgi_handle_authorization(char *line)
 {
        char *p, *user, *user_pass;
-       const struct passwd *pass = NULL;
+       struct passwd *pass = NULL;
        BOOL ret = False;
 
        if (strncasecmp(line,"Basic ", 6)) {
@@ -386,20 +386,7 @@ static BOOL cgi_handle_authorization(char *line)
                         * We have not authenticated as root,
                         * become the user *permanently*.
                         */
-                       if(!become_user_permanently(pass->pw_uid, pass->pw_gid)) {
-                               /*
-                                * Always give the same error so a cracker
-                                * cannot tell why we fail.
-                                */
-                               cgi_setup_error("401 Bad Authorization", "",
-                       "username/password must be supplied");
-                       return False;
-                       }
-
-                       /*
-                        * On exit from here we are the authenticated
-                        * user - no way back.
-                        */
+                       become_user_permanently(pass->pw_uid, pass->pw_gid);
                }
 
                /* Save the users name */
@@ -571,9 +558,9 @@ void cgi_setup(char *rootdir, int auth_required)
                *p = 0;
        }
 
-       string_sub(url, "/swat/", "");
+       string_sub(url, "/swat/", "", 0);
 
-       if (strstr(url,"..")==0 && file_exist(url, NULL)) {
+       if (url[0] != '/' && strstr(url,"..")==0 && file_exist(url, NULL)) {
                cgi_download(url);
        }
 
index 054de2a631de28e7832d14053047fe288e7839c7..f29e380b93c8e9a59a93d49960f1ae903a2ff045 100644 (file)
@@ -32,7 +32,7 @@ BOOL nmbd_running(void)
        struct in_addr *ip_list;
 
        if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
-                                interpret_addr("127.0.0.1"))) != -1) {
+                                interpret_addr("127.0.0.1"), True)) != -1) {
                if ((ip_list = name_query(fd, "__SAMBA__", 0, 
                                          True, True, loopback_ip,
                                          &count,0)) != NULL) {
index 6a15e7a46f8d4a7213cf7c90f978b208f79cdb46..9eeac96cc0c795b73b7ad52a2405d42a0bf3de92 100644 (file)
@@ -37,7 +37,7 @@ void start_smbd(void)
                return;
        }
 
-       slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", BINDIR);
+       slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", SBINDIR);
 
        become_daemon();
 
@@ -58,7 +58,7 @@ void start_nmbd(void)
                return;
        }
 
-       slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", BINDIR);
+       slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", SBINDIR);
        
        become_daemon();
 
index faf1dcb20d613acf6a2baafecae5f1bd8611dc43..304a122e2304d3a2c8febbe87e9f409513160600 100644 (file)
@@ -26,13 +26,13 @@ static char *tstring(time_t t)
 {
        static pstring buf;
        pstrcpy(buf, asctime(LocalTime(&t)));
-       all_string_sub(buf," ","&nbsp;");
+       all_string_sub(buf," ","&nbsp;",sizeof(buf));
        return buf;
 }
 
 static void print_share_mode(share_mode_entry *e, char *fname)
 {
-       printf("<tr><td>%d</td>",e->pid);
+       printf("<tr><td>%d</td>",(int)e->pid);
        printf("<td>");
        switch ((e->share_mode>>4)&0xF) {
        case DENY_NONE: printf("DENY_NONE"); break;
@@ -60,12 +60,14 @@ static void print_share_mode(share_mode_entry *e, char *fname)
                printf("EXCLUSIVE       ");
        else if (e->op_type & BATCH_OPLOCK)
                printf("BATCH           ");
+       else if (e->op_type & LEVEL_II_OPLOCK)
+               printf("LEVEL_II        ");
        else
                printf("NONE            ");
        printf("</td>");
 
        printf("<td>%s</td><td>%s</td></tr>\n",
-              fname,tstring(e->time.tv_sec));
+              dos_to_unix(fname,False),tstring(e->time.tv_sec));
 }
 
 
@@ -131,7 +133,7 @@ void status_page(void)
                        if (crec.magic == 0x280267 && crec.cnum == -1 &&
                            process_exists(crec.pid)) {
                                char buf[30];
-                               slprintf(buf,sizeof(buf)-1,"kill_%d", crec.pid);
+                               slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
                                if (cgi_variable(buf)) {
                                        kill_pid(crec.pid);
                                }
@@ -159,10 +161,10 @@ void status_page(void)
 
        f = sys_fopen(fname,"r");
        if (!f) {
-               printf("Couldn't open status file %s\n",fname);
+               /* open failure either means no connections have been
+                   made or status=no */
                if (!lp_status(-1))
                        printf("You need to have status=yes in your smb config file\n");
-               return;
        }
 
 
@@ -171,60 +173,74 @@ void status_page(void)
        printf("<tr><td>version:</td><td>%s</td></tr>",VERSION);
 
        fflush(stdout);
-       if (smbd_running()) {
-               printf("<tr><td>smbd:</td><td>running</td><td><input type=submit name=\"smbd_stop\" value=\"Stop smbd\"></td><td><input type=submit name=\"smbd_restart\" value=\"Restart smbd\"></td></tr>\n");
-       } else {
-               printf("<tr><td>smbd:</td><td>not running</td><td><input type=submit name=\"smbd_start\" value=\"Start smbd\"></td>><td><input type=submit name=\"smbd_restart\" value=\"Restart smbd\"></td></tr>\n");
+       printf("<tr><td>smbd:</td><td>%srunning</td>\n",smbd_running()?"":"not ");
+       if (geteuid() == 0) {
+           if (smbd_running()) {
+               printf("<td><input type=submit name=\"smbd_stop\" value=\"Stop smbd\"></td>\n");
+           } else {
+               printf("<td><input type=submit name=\"smbd_start\" value=\"Start smbd\"></td>\n");
+           }
+           printf("<td><input type=submit name=\"smbd_restart\" value=\"Restart smbd\"></td>\n");
        }
+       printf("</tr>\n");
 
        fflush(stdout);
-       if (nmbd_running()) {
-               printf("<tr><td>nmbd:</td><td>running</td><td><input type=submit name=\"nmbd_stop\" value=\"Stop nmbd\"></td><td><input type=submit name=\"nmbd_restart\" value=\"Restart nmbd\"></td></tr>\n");
-       } else {
-               printf("<tr><td>nmbd:</td><td>not running</td><td><input type=submit name=\"nmbd_start\" value=\"Start nmbd\"></td><td><input type=submit name=\"nmbd_restart\" value=\"Restart nmbd\"></td></tr>\n");
+       printf("<tr><td>nmbd:</td><td>%srunning</td>\n",nmbd_running()?"":"not ");
+       if (geteuid() == 0) {
+           if (nmbd_running()) {
+               printf("<td><input type=submit name=\"nmbd_stop\" value=\"Stop nmbd\"></td>\n");
+           } else {
+               printf("<td><input type=submit name=\"nmbd_start\" value=\"Start nmbd\"></td>\n");
+           }
+           printf("<td><input type=submit name=\"nmbd_restart\" value=\"Restart nmbd\"></td>\n");
        }
+       printf("</tr>\n");
 
        printf("</table>\n");
        fflush(stdout);
 
-
-       if (geteuid() != 0)
-               printf("<b>NOTE: You are not logged in as root and won't be able to start/stop the server</b><p>\n");
-
        printf("<p><h3>Active Connections</h3>\n");
        printf("<table border=1>\n");
-       printf("<tr><th>PID</th><th>Client</th><th>IP address</th><th>Date</th><th>Kill</th></tr>\n");
+       printf("<tr><th>PID</th><th>Client</th><th>IP address</th><th>Date</th>\n");
+       if (geteuid() == 0) {
+               printf("<th>Kill</th>\n");
+       }
+       printf("</tr>\n");
 
-       while (!feof(f)) {
+       while (f && !feof(f)) {
                if (fread(&crec,sizeof(crec),1,f) != 1)
                        break;
                if (crec.magic == 0x280267 && 
                    crec.cnum == -1 &&
                    process_exists(crec.pid)) {
-                       printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td><input type=submit value=\"X\" name=\"kill_%d\"></td></tr>\n",
-                              crec.pid,
+                       printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
+                              (int)crec.pid,
                               crec.machine,crec.addr,
-                              tstring(crec.start),
-                              crec.pid);
+                              tstring(crec.start));
+                       if (geteuid() == 0) {
+                           printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
+                              (int)crec.pid);
+                       }
+                       printf("</tr>\n");
                }
        }
 
        printf("</table><p>\n");
 
-       fseek(f, 0, SEEK_SET);
+       if (f) fseek(f, 0, SEEK_SET);
        
        printf("<p><h3>Active Shares</h3>\n");
        printf("<table border=1>\n");
        printf("<tr><th>Share</th><th>User</th><th>Group</th><th>PID</th><th>Client</th><th>Date</th></tr>\n\n");
 
-       while (!feof(f)) {
+       while (f && !feof(f)) {
                if (fread(&crec,sizeof(crec),1,f) != 1)
                        break;
                if (crec.cnum == -1) continue;
                if (crec.magic == 0x280267 && process_exists(crec.pid)) {
                        printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
                               crec.name,uidtoname(crec.uid),
-                              gidtoname(crec.gid),crec.pid,
+                              gidtoname(crec.gid),(int)crec.pid,
                               crec.machine,
                               tstring(crec.start));
                }
@@ -241,7 +257,7 @@ void status_page(void)
        locking_end();
        printf("</table>\n");
 
-       fclose(f);
+       if (f) fclose(f);
 
        printf("</FORM>\n");
 
index ce7801ba5ca3bfba83ed6ee46a172ccbd535e537..48c3ae07e25bc8c657b7cdd8e64fbea51e1e3c58 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
@@ -215,9 +217,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:
@@ -252,10 +255,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;
@@ -299,6 +310,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 
 ****************************************************************************/
@@ -306,15 +326,15 @@ static void write_config(FILE *f, BOOL show_defaults)
 {
        fprintf(f, "# Samba config file created using SWAT\n");
        fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
-       fprintf(f, "# Date: %s\n\n", timestring());
+       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;
 
@@ -325,14 +345,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;
 }
@@ -379,14 +403,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 
 ****************************************************************************/
@@ -402,13 +418,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("Globals", "globals", "images/globals.gif");
-       image_link("Shares", "shares", "images/shares.gif");
-       image_link("Printers", "printers", "images/printers.gif");
-       image_link("Status", "status", "images/status.gif");
-       image_link("View Config", "viewconfig","images/viewconfig.gif");
+       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");
@@ -462,7 +487,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");
@@ -511,26 +536,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");
@@ -542,10 +570,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("<td><input type=text size=30 name=newshare></td></tr>\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>");
 
 
@@ -554,7 +590,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 {
@@ -584,8 +620,6 @@ static BOOL change_password(const char *remote_machine, char *user_name,
                            BOOL add_user, BOOL enable_user, BOOL disable_user)
 {
        BOOL ret = False;
-       uint16 acb_info = 0;
-       uint16 acb_mask = 0;
        pstring err_str;
        pstring msg_str;
 
@@ -602,28 +636,14 @@ static BOOL change_password(const char *remote_machine, char *user_name,
                return ret;
        }
 
-       if (!pwdb_initialise(False))
-       {
+       if(!initialize_password_db()) {
                printf("Can't setup password database vectors.\n<p>");
                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),
-                                   msg_str, sizeof(msg_str));
+       ret = local_password_change(user_name, False, add_user, enable_user, 
+                                    disable_user, False, new_passwd, err_str, sizeof(err_str),
+                                        msg_str, sizeof(msg_str));
 
        if(*msg_str)
                printf("%s\n<p>", msg_str);
@@ -787,7 +807,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>");
 
@@ -826,26 +846,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);
        }
 
@@ -859,23 +890,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");
 
-       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 (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 {
@@ -908,13 +952,22 @@ 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);
 
        dbf = sys_fopen("/dev/null", "w");
-
        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':
@@ -927,7 +980,9 @@ static void printers_page(void)
        }
 
        charset_initialise();
-       load_config();
+       load_config(True);
+       iNumNonAutoPrintServices = lp_numservices();
+       load_printers();
 
        cgi_setup(SWATDIR, !demo_mode);
 
@@ -935,24 +990,34 @@ static void printers_page(void)
        
        cgi_load_variables(NULL);
 
+       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();
 
-       /* check if the authenticated user has write access - if not then
-          don't show write options */
-       have_write_access = (access(servicesf,W_OK) == 0);
-
        /* 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();
index bbde61e54909727213034656da05696d10fbbb4c..48579d62722b7259def3e858bead846ec0f33023 100644 (file)
@@ -24,6 +24,7 @@ Please choose a configuration action using one of the above buttons
     <li><a href="/swat/help/nmblookup.1.html" target="docs">nmblookup</a> - NetBIOS name query tool
     <li><a href="/swat/help/smbtar.1.html" target="docs">smbtar</a> - SMB backup tool
     <li><a href="/swat/help/smbclient.1.html" target="docs">smbclient</a> - command line SMB client
+    <li><a href="/swat/help/smbspool.8.html"  target="docs">smbspool</a> - command line SMB print client
    </ul>
  <li><b>Configuration Files</b>
    <ul>
@@ -34,7 +35,8 @@ Please choose a configuration action using one of the above buttons
  <li><b>Miscellaneous</b>
    <ul>
     <li><a href="/swat/help/samba.7.html" target="docs">Samba introduction</a>
-    <li><a href="/swat/help/DOMAIN_MEMBER.html" target="docs">Joining a NT Domain</a>
+    <li><a href="/swat/help/DOMAIN_MEMBER.html" target="docs">Joining an NT Domain</a>
+    <li><a href="/swat/help/NT_Security.html" target="docs">Changing UNIX permissions using NT</a>
     <li><a href="/swat/help/smbrun.1.html" target="docs">smbrun</a> - internal smbd utility
    </ul>
 </ul>